bozboz/jam

此包已被弃用且不再维护。未建议替代包。
关于此包的最新版本(v1.22.6)没有可用的许可信息。

v1.22.6 2023-04-13 13:37 UTC

This package is auto-updated.

Last update: 2023-04-13 13:53:18 UTC


README

内容

1. 安装

  1. 通过运行 composer require bozboz/jam 在 Composer 中要求此包
  2. Bozboz\Jam\Providers\JamServiceProvider::class 添加到 config/app.php 中的 providers 数组 - 注意:必须在 RouteServiceProvider 之上,否则路由将不会正确排序。将其添加到现有的 bozboz 服务提供者中。
  3. 运行 php artisan vendor:publish && php artisan migrate
  4. 转到 3. 使用 了解默认通配路由

2. 数据设置

2.1. 类型

实体类型(也称为类型)是 jam 架构的最高级别。它们本质上可以被视为模型,或模型的逻辑分组(待澄清:说明),因为模板实际上包含字段。类型在应用程序的服务提供者中注册,例如

<?php
// todo: specify convention
[
    'default_everything_entities' => // key used where?
        new Type([
            'menu_title' => 'Default Everything Entities',
            'name' => 'Default Everything Entities', // used where?
    ]),
    'custom_everything_entities' => 
        new CustomType([
            'menu_title' => 'Custom Everything Entities',
            'name' => 'Custom Entities',
            'report' => MyReport::class, 
            'link_builder' => MyLinkBuilder::class,
            'menu_builder' => MyMenuBuilder::class,
            'entity' => MyEntity::class,
            'search_handler' => MySearchHandler::class,
            'decorator' => MyDecorator::class
            'can_restrict_access' => true, // used where?
            'gated' => true, // used where?
            'custom_attribute' => ''
        ])
];

Jam 预先注册了 "pages" NestedType,因为大多数应用程序都需要一个(NestedType 用于需要嵌套排序的实体)。

类型属性

  • report 列表的后台报告类。通常情况下,除非您要实现完全定制的功能,否则不需要更改此设置。NestedType 会自动将默认值切换为 NestedReport。

    默认 Bozboz\Admin\Reports\Report

  • link_builder 这是一个负责知道其负责的类型应生成哪些路径/URLs 的类。默认情况下,类型不会生成路径,因为假设每个实体不是一个独立的页面。如果需要类型生成路径,可以使用 Bozboz\Jam\Entities\LinkBuilder,它将根据当前实体的嵌套生成单个路径,并更新任何子实体的路径。对于需要存在于多个 URL 下的复杂实体,可以扩展 LinkBuilder 类并添加自己的路径生成逻辑。实体嵌套生成的主要路径将被用作任何附加路径的规范路径。

    默认 Bozboz\Jam\Entities\LinksDisabled

  • menu_builder
    处理类型在后台菜单中的位置。类型在没有基于其实体进行设置的 模板 之前不会显示在菜单中。

    • Bozboz\Jam\Types\Menu\Hidden 不显示在菜单中
    • Bozboz\Jam\Types\Menu\Content 在内容下拉菜单中显示
    • Bozboz\Jam\Types\Menu\Standalone 作为顶级菜单项显示

    默认 Bozboz\Jam\Types\Menu\Content

  • search_handler Jam内置了对Elastic Search的基本支持,但默认情况下是禁用的。请参阅4. 搜索索引

  • entity 在Jam中存在几种不同类型的实体类,它们决定了排序选项。普通的Bozboz\Jam\Entities\Entity不可排序,将按名称排序。Bozboz\Jam\Entities\SortableEntity可以手动排序,但单独使用时只允许兄弟排序。如果需要嵌套排序,则必须与Bozboz\Jam\Types\NestedType类型结合使用。最后还有Bozboz\Jam\Entities\Post实体,它将按发布日期对实体进行排序。

    默认Bozboz\Jam\Entities\Entity

2.2. 模板

通过添加/创建模板来定义实体类型的数据字段。类型可以具有多个模板。要添加模板,请登录到管理员界面,点击“Jam”,然后选择要编辑的类型。

添加模板时,必须为其提供nameview,但列出视图max_uses值是可选的。视图字段将在默认渲染方法中使用以选择实际要渲染的视图。列出视图的实现主要取决于需求,但其目的是可以在类型中具有多个模板,这些模板在列表中需要不同的视图。创建模板后,管理员菜单将确认类型,并在配置的菜单_builder指定的菜单中显示它。max_uses允许您限制模板的使用次数,例如,将其设置为1将在创建1个之后隐藏使用该模板创建新实体的选项(待办事项:示例用例)。

2.2.1. 模板迁移

在开发中对模板进行更改时,需要在发布后对生产数据库中的相同更改进行更改。为了帮助实现这一点,有一个模板生成器和模板历史视图。

如果您创建了一个全新的模板,该模板在实时数据库中还不存在,那么最好的办法是使用控制台命令php artisan jam:make-seeder <类型别名> <模板别名>来使用模板生成器。这将生成一个可以在实时数据库上运行的生成器,以插入模板及其所有字段和字段选项。生成的生成器将具有由类型和模板别名组成的名字,后缀为"JamTemplate.php"。

例如:php artisan jam:make-seeder pages text-page将生成一个名为PagesTextPageJamTemplate.php的生成器,因此一旦部署到实时服务器,就可以使用php artisan db:seed --class=PagesTextPageJamTemplate来运行它。

如果您不是在创建全新的模板,而是在修改现有模板的部分,那么最好的办法是查看该模板的历史记录,并在工作部署后在生产数据库上手动重做显示在那里的更改。

2.3. 字段

模板由一系列字段组成。Jam提供了以下字段类型

  • 文本
    标准的单行文本输入。

  • 文本区域
    标准的多行文本输入,带有复选框选项,使其成为WYSIWYG HTML编辑器。

  • 图片
    单个媒体库字段。

  • 相册
    多选媒体库字段。

  • 日期

  • 日期和时间

  • 切换
    复选框用于切换布尔值。

  • 实体列表
    允许创建多个子实体。对于如幻灯片、突出显示框等重复内容结构非常有用。
    为了使用此字段类型,您必须首先设置另一个实体类型,该字段可以使用Bozboz\Jam\Types\EntityList类型链接。
    例如:

    <?php
    $mapper = $this->app['EntityMapper'];
    
    $mapper->register([
        'callout-boxes' => new \Bozboz\Jam\Types\EntityList('Callout Boxes'),
    ]);
  • 属于
    允许您将一个实体链接到另一个实体。

    在创建/编辑表单中输入“en”和所有创建的实体都将具有所选的父实体。仅选择类型或模板将使用户能够从所选类型/模板的实体中选择父实体。

    您还可以选择具有此字段的实体是否作为子页面嵌套在相关实体之下。

    注意:此功能不应与不在同一列表中显示的可排序实体一起使用,因为重新排序可能会导致意外的树状结构操作。

  • 属于多个
    为实体表单提供选择与多个实体相关联的选项。与属于类似,下拉菜单中的选项将限制为添加字段到模板时所选的类型和模板。

  • 反向属于多个(只读)
    属于多个字段中定义关系的反向,提供一个只读视图来查看相关实体。

  • 隐藏
    允许您向实体创建/编辑表单中添加隐藏字段,该字段将在创建字段时保存输入的值。

如果您需要上述未列出的任何功能(例如,定义实体模板与不在Jam中存储的应用程序自定义模型之间的关系),您可以通过扩展Bozboz\Jam\Fields\Field类并在服务容器中使用注册的FieldMapper在服务提供程序中注册字段类型来创建任意数量的自定义字段类型。

2.4. 实体

通常,您不需要超过包中的默认功能,并且您不应直接与Entity类本身交互。有关如何使用不同实体类的信息,请参阅2.4. 实体,有关如何获取实体的信息,请参阅3.2. EntityRepository

2.5. 修订

每次保存实体时,它都会在实体_revisions表中创建一个修订版,并创建一组新值。这允许您跟踪实体的变化或回滚到以前的状态。

3. 使用

3.1. 通用路由

Jam默认没有设置任何前端路由,但它有一个控制器,您的应用程序可以将一些路由指向它。

通常,您希望在路由文件末尾添加一个通用路由,这将处理大多数或所有实体路由。这将使用路径表根据请求路径查找实体,并按照其配置的模板在视图中提供。

<?php
/**
 * Jam Catch All
 */
Route::get('{entityId}{slug?}', [
    'as' => 'entity-by-id',
    'uses' => '\Bozboz\Jam\Http\Controllers\EntityController@forId'
])->where('entityId', '(\d+)')->where('slug', '(/.+)?');

Route::get('{entityPath}', [
    'as' => 'entity',
    'uses' => '\Bozboz\Jam\Http\Controllers\EntityController@forPath',
])->where('entityPath', '(.+)?');

3.2. EntityRepository

应使用Bozboz\Jam\Repositories\EntityRepository类上的forType方法手动检索实体。这将返回正确注册到类型的实体类的查询构建器,并限制为该类型的实体。

3.3. 列表与其他数据

某些页面可能需要比实体更多的数据,因此您需要为当前视图创建一个视图编写器。这些应添加到app/Http/ViewComposers并注册到ComposerServiceProvider服务提供程序的boot方法中。

3.4. 标准路径

每个拥有链接构建器的实体都将有一个规范路径,通常这是您从其他页面/菜单链接到它时希望使用的路径。在查询实体时,您应使用withCanonicalPath作用域来预加载它;或者在与集合一起工作时,使用loadCanonicalPath方法来延迟加载它。使用$entity->canonical_path来输出它。

3.5. 值检索

仅查询实体只会给您从实体表中获取的数据,为了加载值,您必须在单个或实体集合上调用loadFields方法。此方法接受要加载的字段列表,如果未提供参数,则将加载所有字段。

例如:

<?php
$pages = $entityRepository->forType('page')->get()->loadFields('content', 'image');

如果您需要为“属于”或“属于多个”实体关系加载值,则可以使用loadRelationFields(string $relationName, mixed $field/s)方法。这将也会检查该关系是否已加载,如果没有,则加载它,这样您就不需要事先加载它。

例如:

<?php
$entities->loadRelationFields('categories', ['description', 'image']);

4. 搜索索引

jam支持通过elasticsearch索引实体,但每种类型都需要设置一个搜索处理器,参见2.1. 类型。如果您只需索引实体的名称,则可以使用基类Bozboz\Jam\Entities\Indexer。在可能需要更多功能的情况下,每种类型都需要为其编写处理器。在为实体类型设置搜索处理器类时,它应扩展基Indexer类并重写getPreviewDatagetSearchableData方法。

getPreviewData的目的是将实体转换为您搜索结果视图的合适格式,而getSearchableData则用于返回您希望可搜索的所有值作为单个长字符串。

例如:

<?php
protected function getPreviewData($page)
{
    return [
        'preview' => str_limit(strip_tags(
            $page->intro_text ?: $page->content
        ), 200),
        'image' => Media::getFilenameOrFallback($page->image, null, 'search-result'),
    ];
}

protected function getSearchableData($page)
{
    return strip_tags(implode(' ', [
        $page->intro_text,
        $page->content,
    ]));
}