sands / laravel-presenter
为 Laravel 5+ 以各种格式展示您的响应
This package is not auto-updated.
Last update: 2024-09-14 19:53:02 UTC
README
Laravel 5+ 的自动响应展示器。自动将您的响应发送为 Blade 视图或 JSON。
需要其他类型的响应?请查看下面的插件部分。您也可以创建自己的展示器。
安装
$ composer require sands/laravel-presenter
在 config/app.php
中,将 Sands\Presenter\PresenterServiceProvider
添加到 providers
数组中
'providers' => [ ... Sands\Presenter\PresenterServiceProvider::class, ... ]
在 app/Http/Controllers/Controller.php
中添加 Sands\Presenter\PresentsResponses
特性,以便它可以在所有控制器中使用
// app/Http/Controllers/Controller.php ... use Sands\Presenter\PresentsResponses; ... class Controller extends BaseController { use PresentsResponses; }
用法
假设您有一个由网页和移动端同时使用的控制器 UsersController
。对于网页,您希望返回由 Blade 视图生成的 HTML 文档,而对于移动端,您希望返回 JSON 格式的数据。
在控制器的 index
方法中,您可以如此展示数据
public function index() { return $this->present(['users' => User::paginate()]) ->using('blade', 'json'); }
Laravel 会自动以首选格式返回响应。格式检测通过 Accept
头、通过 format
查询字符串或通过 presentUsing
请求参数完成。
带有 application/json
值的 Accept
请求头将返回 json
格式,而 text/html
将返回渲染的 Blade 视图。
您还可以通过在 URL 中附加 ?format={presenter}
来定义响应类型。这对于下载链接特别有帮助。
或者也可以通过 presentUsing
路由参数定义响应类型
// in your routes file Route::get('/users/export.{presentUsing}', 'UsersController@index');
因此,当用户访问 users/export.json
路由时,Laravel 会以 JSON 格式返回响应。
自定义数据
有时您可能希望针对不同的展示返回不同的数据。例如,当渲染 Blade 视图时,您可能希望返回分页集合,而当通过 JSON 访问时,您可能希望所有数据都可用。为此,您可以使用以下方法 setOption
public function index() { return $this->present() ->setOption('data.blade', 'data') // call this method to get data for blade ->setOption('data.json', 'jsonData') // call this method to get data for JSON ->setOption('data', 'data') // default data method ->using('json', 'blade'); } public function data() { return ['users' => User::paginate()]; } public function jsonData() { return ['users' => User::all()]; }
默认情况下,展示器会查找 data.{presenterName}
选项,并在控制器上调用该方法以获取数据。如果该选项不存在,则查找 data
选项,并在控制器上调用该方法。如果该选项未设置,则返回在调用 present
时传递的数据。
为了避免对所有数据方法调用昂贵的 DB 操作,该方法仅在展示器 render
方法调用之前调用。这是在控制器上下文之外完成的。由于数据方法是在控制器之外调用的,因此方法的可见性应该是 public
。
您应该考虑到 Laravel 5.0 - 5.2 控制器方法的命名约定,以便通过
Route::controller
注册的控制器不会意外地将这些数据方法暴露为路由。
您还可以将这些方法放入单独的特性文件中,以便控制器不会因数据方法而变得杂乱。
内置展示器
默认情况下,Sands\Presenter
随附三个默认展示器
- blade (html)
- json
Blade 视图响应
Blade视图路径自动从完全限定的控制器类名称计算得出,移除了App\Http\Controllers\
前缀和Controller
后缀,以及控制器当前调用的方法。例如,调用App\Http\Controllers\Auth\FacebookAuthController@show
方法时,将加载Blade视图auth.facebook-auth.show
。
在调用present
时可以通过调用setOption
方法来覆盖控制器前缀。
namespace App\Controllers; ... public function index() { return $this->present(['users' => User::paginate()]) ->setOption('controllerPrefix', 'App\\Controllers') ->using('blade', 'json'); }
在调用present
时可以通过调用setOption
方法来覆盖控制器后缀。
class UsersControllers { ... public function index() { return $this->present(['users' => User::paginate()]) ->setOption('controllerSuffix', 'Controllers') ->using('blade', 'json'); }
在调用present
时可以通过调用setOption
方法来覆盖视图路径。
public function index() { return $this->present(['users' => User::paginate()]) ->setOption('view', 'some.blade.path') ->using('blade', 'json'); }
JSON响应
JSON响应将返回传递给它的数据作为JSON。这对移动应用来说特别有用。
格式化JSON
可选地,您可以使用spatie/laravel-fractal包(本包不包括此包)来转换JSON,方法是告诉展示器使用自定义的JSON数据方法。
public function index() { return $this->present() ->setOption('data', 'data') ->setOption('data.json', 'jsonData') // call this method to get data for JSON ->using('json', 'blade'); } public function jsonData() { return [ 'users' => fractal() ->collection(User::all() ->transformWith(new UserTransformer()) ->toArray(); ]; }
创建您的展示器
创建自己的展示器非常简单。您的自定义展示器类需要实现Sands\Presenter\PresenterContract
接口。展示器合同将期望您的实现有一个__construct
和render
方法。必须返回一个Illuminate\Http\Response
实例或可以被它消费的数据的实例。
__construct
方法将presenter
实例作为唯一参数。通常您会将presenter
附加为类属性。
use Sands\Presenter\Presenter; use Sands\Presenter\PresenterContract; ... class PdfPresenter implements PresenterContract { public function __construct(Presenter $presenter) { $this->presenter = $presenter; } ...
所有响应都是延迟实例化的。这意味着只有在展示器的render
方法需要被调用时,展示器才会被加载和实例化。
render
方法将有一个传递为第一个参数的$data
变量。必须返回一个Illuminate\Http\Response
实例或可以被该类消费的值。
public function render($data = []) { $viewPath = $this->presenter->getOption('view.pdf'); return PDF::loadView($viewPath, $data)->stream(); }
可用选项
通常,用户通过使用setOption
方法设置选项。这些选项可以通过调用$this->presenter->getOption('key')
方法在您的自定义展示器中使用,其中key
是您正在查找的选项。如果未设置选项,则返回null
。
要获取所有选项,使用$this->presenter->getOptions()
方法。
默认情况下,这些选项可用
controllerPrefix
:App\Http\Controllers
controllersSuffix
:Controllers
controller
: 当前调用的控制器,例如:App\Http\Controllers\UsersController
method
: 当前调用的控制器方法,例如:index
routeParams
: 当前路由参数。
注册您的展示器
要注册您的展示器,只需调用register
方法
app('sands.presenter')->register('pdf', [ 'presenter' => \App\Presenters\Pdf::class, 'mimes' => [ // optionally bind to these mimes 'application/pdf', ], 'extensions' => [ // optionally bind to these extensions 'pdf' ], 'options' => [] // options to be included in the $presenter instance ]);
通常您应该在Sands\Presenter\PresenterServiceProvider
之后加载的服务提供者中注册您的展示器。
可用插件
MIT许可证
版权所有(c)2016 Sands Consulting Sdn Bhd
特此授予任何获得本软件及其相关文档文件(以下简称“软件”)副本的人免费使用软件的权利,不受限制,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本,以及允许获得软件的人进行此类操作,前提是遵守以下条件
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
本软件按“原样”提供,不提供任何形式的保证,无论是明示的还是暗示的,包括但不限于适用性、特定用途的适用性和非侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论是基于合同行为、侵权行为或其他方式,无论该索赔、损害或其他责任源于、产生于或与该软件或对该软件的使用或其他使用方式有关。