大麻/presenter

Laravel中的简易模型展示器

安装数: 467,642

依赖项: 1

建议者: 1

安全: 0

星级: 249

关注者: 6

分支: 16

开放问题: 0

类型:项目

v3.0.0 2024-03-22 17:53 UTC

README

此包可让您快速、有趣且有利可图地装饰Eloquent模型以在视图中展示,PDF文件中,CSV文件中或项目中的任何其他地方。

有关展示器解决的问题的简要介绍,请参阅此文章:Laravel中的展示器

安装

通过 Composer 安装包

composer require hemp/presenter

Laravel 5.5+ 中,包的服务提供者应该会自动发现,因此您不需要注册它。如果出于某种原因您需要手动注册它,可以将它添加到 config/app.php 中的 providers 数组中

'providers' => [
    // ...
    Hemp\Presenter\PresenterServiceProvider::class,
],

创建 Presenter

您可以通过调用 make:presenter Artisan 命令轻松生成一个 Presenter

php artisan make:presenter ApiPresenter

这将生成一个空的 Presenter 类在 app/Presenters 中。

自定义 Presenter

在核心上,展示器是简单的类,旨在封装复杂或重复的视图逻辑。使 hemp/presenter 友好的是,它允许您将这些 Presenter 对象附加到魔法访问器,同时允许使用常规 Model 对象和集合的典型序列化工作流程。例如,考虑这个 ApiPresenter

<?php

namespace App\Presenters;

use Hemp\Presenter\Presenter;

class ApiPresenter extends Presenter
{
  public function createdDate()
  {
    return $this->created_at->format('n/j/Y');
  }

  public function getFullNameAttribute()
  {
    return trim($this->first_name . ' ' . $this->last_name);
  }
}

此类有一个自定义方法 createdDate,可以在使用此 Presenter 的任何地方调用。它还有一个魔法访问器 getFullNameAttribute,可以通过 Presenter 访问,如下所示:$user->full_name。这与Eloquent的魔法访问器的工作方式完全一样...当 Presenter 转换为响应(如视图或API响应)时,这些魔法访问器将被调用并添加到渲染输出中。

您会注意到我们调用了 $this->first_name$this->last_name。这些不是在 Presenter 类本身上可用的,但被委托给底层的 Model 实例。

Presenter 可能会输出如下内容

{
  id: 1,
  first_name: 'David',
  last_name: 'Hemphill',
  created_at: '2016-10-14 12:00:00',
  updated_at: '2016-12-14 12:00:00',
  full_name: 'David Hemphill', // The magic accessor
}

一旦您有一个展示的模型实例(如Blade视图中),您可以使用魔法访问器如下所示

$presentedUser->full_name;

或使用 Presenter 自身上可用的方法

$presentedUser->createdAt();

当将 Presenter 输出到 array 或 JSON 时,如果您希望每个渲染属性都使用 camelCase 格式而不是默认的 snake_case 格式,可以将您的 Presenter 上的 snakeCase 属性设置为 false

class ApiPresenter extends Presenter
{
  public $snakeCase = false;
}

这将导致渲染输出看起来像这样

{
  "id": 1,
  "firstName": "David",
  "lastName": "Hemphill",
  "createdAt": "2016-10-14 12:00:00",
  "updatedAt": "2016-12-14 12:00:00",
  "fullName": "David Hemphill"
}

如果您的前端JavaScript样式指南主要使用camelCased变量,您可能喜欢此选项。

此外,您可以使用 snakeCasecamelCase 设置器在运行时设置使用的策略

Presenter::make($user, ApiPresenter::class)->snakeCase();
Presenter::make($user, ApiPresenter::class)->camelCase();

展示单个模型

您可以根据个人喜好以多种不同的方式展示您的 Model 对象。例如,您可以使用 Presenter 类的 make 工厂方法

$user = User::first();
$presentedUser = Presenter::make($user, ApiPresenter::class);

您还可以在您的任何自定义 Presenter 类上调用 make 方法,而不传递第二个参数

$user = User::first();
$presentedUser = ApiPresenter::make($user);

如果您喜欢,也可以使用 present 全局函数

$user = User::first();
$presentedUser = present($user, ApiPresenter::class);

或者您可以在您的 Model 上使用 Hemp\Presenter\Presentable trait。这将允许您直接调用其上的 present 方法

use Hemp\Presenter\Presentable;

class User extends \Illuminate\Database\Eloquent\Model
{
  use Presentable;
}

$presentedUser = User::first()->present(ApiPresenter::class);

此外,在使用 Presentable trait 时,您可以在 Model 上使用 defaultPresenter 属性来指定默认的展示器,然后调用 present

use Hemp\Presenter\Presentable;

class User extends \Illuminate\Database\Eloquent\Model
{
  use Presentable;

  public $defaultPresenter = App\Presenters\ApiPresenter::class;
}

$presentedUser = User::first()->present();

展示集合

您还可以创建一个展示过的 Model 对象集合。一种方法是在 Presenter 类上使用静态的 collection 方法来展示一个 Model 对象数组

$users = User::all();
$presenter = Presenter::collection($users, ApiPresenter::class);

您还可以直接在您的任何自定义 Presenter 类上使用静态的 collection 方法,而不需要传递第二个参数

$users = User::all();
$presenter = ApiPresenter::collection($users);

您还可以在集合对象上使用 present

$presentedUsers = User::all()->present(ApiPresenter::class);

从输出中隐藏模型属性

有时您可能希望某些键不被渲染在您的 Presenter 中。您可以使用 Presenter 上的 hidden 属性来防止任何默认的 Model 属性被用于输出

<?php

namespace App\Presenters;

use Hemp\Presenter\Presenter;

class ApiPresenter extends Presenter
{
  protected $hidden = ['stripe_private_key'];
}

这将防止最终输出中显示底层 Model 实例的 stripe_private_key 属性。

您还可以在 Presenter 上指定 visible 属性,将其作为应该显示在输出中的属性的允许列表。

<?php

namespace App\Presenters;

use Hemp\Presenter\Presenter;

class ApiPresenter extends Presenter
{
  protected $visible = ['name', 'email'];
}

注意:如果键同时指定在 hiddenvisible 属性中,那么它将被假设您希望它在渲染的输出中是可见的。

支持

如果您使用这个包,我很乐意了解!

如果您在使用这个包时遇到问题,请在 Twitter 上联系我。我会很乐意帮助。

如果您认为您已经发现了一个错误、改进或其他问题,请使用 GitHub 问题跟踪器 报告它,或者分支仓库并提交一个 pull request。