schnoop / laravel-remote-template
一个用于从远程URL获取模板的Laravel包。
Requires
- php: ^7.1
- guzzlehttp/guzzle: ^6.0
- laravel/framework: ~5.5.0|~5.6.0|~5.7.0|~5.8.0
Requires (Dev)
- mockery/mockery: ^1.2
- phpunit/phpunit: ^7.0
This package is auto-updated.
Last update: 2024-09-13 13:13:53 UTC
README
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,而不是内容。
例如:
- http://remote-content-host.dev/foo/
- http://remote-content-host.dev/foo
- http://remote-content-host.dev/foo/bar
- http://remote-content-host.dev/foo/index.php
配置应被忽略的远程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); });