schnoop/laravel-remote-template

一个用于从远程URL获取模板的Laravel包。

v1.0.1 2019-10-14 12:03 UTC

README

Latest Version Build Status Quality Score StyleCI Total Downloads

laravel-remote-template 是一个用于从远程URL获取blade模板的包。

从远程URL获取内容的使用场景是什么?

想象一下,您的客户希望您构建一个完全灵活的应用程序,同时也希望他们自己管理内容。Laravel非常适合构建应用程序 - 但内容管理不是其重点。也许您有内容管理系统(CMS)的经验 - 但是,嘿,那些并不像Laravel在构建应用程序方面那么灵活。为什么不用两者呢?使用CMS来管理内容,使用Laravel来构建应用程序。这个包可以帮助您在Laravel应用程序中使用远程可用的内容进行渲染。

安装

只需使用composer安装此包

composer require schnoop/laravel-remote-template

如果您正在使用较旧的Laravel版本(< 5.5),您还需要将我们的服务提供程序添加到您的应用程序配置中(config/app.php

'providers' => [
    ...
    Schnoop\RemoteTemplate\RemoteTemplateServiceProvider::class,
],    

接下来,发布配置文件

php artisan vendor:publish --provider="Schnoop\RemoteTemplate\RemoteTemplateServiceProvider"

配置

配置远程分隔符

该包扩展了Laravel的FileViewFinder类,用于按名称解析视图。当遇到特殊的远程分隔符标记时,配置的远程主机将用于解析视图,而不是本地文件系统。

'remote-delimiter' => 'remote:',

现在,每次您通过名称调用或包含视图,并且名称以remote:开头时,模板将从远程主机获取。示例

@extends('remote:login')

{{-- Content --}}
@section('content')
	...
@endsection    

以下内容仍将使用默认的Laravel(文件系统)行为解析视图

@extends('layouts.master')

{{-- Content --}}
@section('content')
	...
@endsection   

配置视图文件夹

在解析远程模板时,文件将下载到特殊视图文件夹。视图文件夹可以通过view-folder配置选项进行自定义。如果启用了缓存,这些文件将在后续请求中重用,并且不会向远程主机发送新的请求。

配置远程主机

您可以使用hosts配置选项配置多个具有唯一标识符的远程主机。然后可以将标识符附加到远程分隔符。

'hosts' => [
	'base' => [
    	...
    ],
],

以下示例将使用base远程主机来解析模板

@extends('remote:base::login')

{{-- Content --}}
@section('content')
	...
@endsection   

如果指定了default主机,则在没有使用其他命名空间的情况下使用它。以下示例将使用default主机

@extends('remote:login')

{{-- Content --}}
@section('content')
	...
@endsection   

可以使用hosts.*.host配置选项定义主机基本URL

'hosts' => [
        'default' => [
            'host' => env('CONTENT_DOMAIN'),
        ],
    ],

配置URL映射

远程分隔符和主机标识符之后的任何标记都将用于构建远程主机的URL。在上面的示例中,将发出对www.yourhost.com/login的请求,并将响应用作解析的视图文件。如果您希望配置自定义映射,可以使用mappings配置选项进行操作

'hosts' => [
        'default' => [
            ...
            'mapping' => [
                'login' => '/index.php?id=51',
            ],
        ],
    ],

配置应被忽略的远程URL

如果您有不想通过这些后备方式公开的URL,可以在配置文件中配置这些URL

  • ignore-urls:可以包含多个URL的数组,这些URL不应通过内容主机解析。
'ignore-urls' => [
    'foo'
],

如果请求远程主机的URL以任何配置的ignore-urls开头,您将收到一个UrlIsForbiddenException,而不是内容。

例如:

配置应被忽略的远程URL后缀

除了配置以特定字符串开头的URL外,您还可以拒绝访问以后缀结尾的URL。

'ignore-url-suffix' => [
    'png',
    'jpg',
    'jpeg',
    'css',
    'js',
    'woff',
    'ttf',
    'gif',
    'svg'
],

在上面的示例中,我们拒绝了对任何静态文件的请求。

其他配置选项

  • hosts.*.cache:当设置为true时,只有在视图文件夹中找不到匹配的模板时,才会向远程主机发送请求。如果找到了模板,它将被重用以解析视图。
  • hosts.*.request_options:将传递给Guzzle HTTP客户端以向远程主机发送请求的请求选项数组。此选项可用于配置身份验证。

使用后备路由

通过结合使用回退路由和默认视图,任何不匹配Laravel中定义的路由的请求都将转发到任何配置的远程主机。

在您的routes/web.php文件中:

Route::fallback('FallbackController@fallback');

控制器将简单地调用一个视图并传递请求的URL。

class FallbackController extends Controller
{
    /**
     * Fallback.
     *
     * @param Request $request
     *
     * @return View
     */
    public function fallback(Request $request): View
    {
        return view('cms::fallback')->with('uri', $request->getRequestUri());
    }
}

视图将把URL传递给远程主机。

@extends('remote:'.$uri)

现在,对于应用程序中未定义的路由的请求,将向远程主机发出请求。如果返回成功响应,它将被用作视图。否则,将返回一个404响应。

在执行调用之前修改远程URL

有时,您可能希望根据Laravel应用程序中的状态强制远程主机渲染模板。一个非常常见的例子是当用户认证时更改导航。

为了实现这一点,我们有一个回调,将在调用远程主机之前触发。

$this->app->make('remoteview.finder')->setModifyTemplateUrlCallback(function ($url) {
    return $url;
});

在这个回调中,您有机会根据需要修改请求URL,告诉远程主机更改其模板渲染。

$this->app->make('remoteview.finder')->setModifyTemplateUrlCallback(function ($url) {
    $glue = '?';
    if (strpos($url, $glue) !== false) {
        $glue = '&';
    }

    if (Auth::check() === true) {
        $url .= $glue . 'login=true';
    }

    // ..... following by more role checks e.g.

    return $url;
});

推送响应处理器

最后但同样重要的是,您可以选择在调用发生后执行的处理器:这些处理器被分配给远程主机返回的响应代码。

在以下示例中,只有在远程主机响应以301 HTTP状态代码时,处理器才会执行。

$this->app->make('remoteview.finder')->pushResponseHandler(301, function (Response $result, array $config, RemoteTemplateFinder $service) {
    // Do some stuff, and return the HTML.
});

一个常见的例子是远程主机可能响应301,这表示重定向到另一个URL。在这种情况下,我们希望从响应中解析目标并从那里获取内容。为此,在函数中注入了一个RemoteTemplateFinder的实例,可以用来执行进一步的调用。

$this->app->make('remoteview.finder')->pushResponseHandler(301, function (Response $result, array $config, RemoteTemplateFinder $service) {
    return $service->fetchContentFromRemoteHost($result->getHeaderLine('Location'), $config);
});