madebyraygun / craft-block-loader
Craft CMS 矩阵块和嵌套条目的上下文加载器。
Requires
- php: >=8.2.0
- composer/class-map-generator: ^1.3.4
- craftcms/cms: ^5.0
Requires (Dev)
- craftcms/ecs: dev-main
- craftcms/phpstan: dev-main
README
这是一个 Craft CMS 矩阵块和嵌套条目的上下文加载器。请与 Craft 组件库 结合使用,以格式化您的块上下文,以便与组件库协同工作。
在 Craft 组件库示例 仓库中查看示例实现。
需求
此插件需要 Craft CMS 5.0 或更高版本,以及 PHP 8.2 或更高版本。
安装
此插件不在 Craft 插件商店中提供,但已发布在 Packagist 上,可以使用 Composer 进行安装。
从终端
composer require madebyraygun/craft-block-loader
php craft plugin/install block-loader
配置
默认情况下,插件将使用 craft/modules/blocks 目录中的 modules\blocks 命名空间初始化所有块类定义,因此请确保您已设置适当的 自动加载配置。通常您会在
"autoload": { "psr-4": { "modules\\blocks": "modules/blocks" } }
ContextBlock 类在 CraftCMS 的模块初始化逻辑之外工作,但它应遵守您定义的目录结构的 PSR-4 标准。要更改这些默认值,请创建一个 block-loader.php 文件到您的 Craft 配置目录中,以更改此目录。
示例配置
return [ 'blocksNamespace' => 'modules\blocks', 'scanNewFiles' => false, 'enableCaching' => true, ];
扫描新文件
根据您定义的 namespace 自动检测可用的 ContextBlock 类,但自动加载器将在您运行 composer dump-autoload -a 重新生成自动加载器类映射之前不会抓取文件更改。这可能在开发过程中略显繁琐。相反,您可以将 scanNewFiles 设置为 true,插件将在每次请求时扫描目录中的新文件。请注意,这 不推荐 用于生产环境,因为可能会影响性能。
用法
使用提供的命名空间 modules\blocks 定义的每个类都与 矩阵字段 或 Ckeditor 字段 内的每个条目块配对。您需要从 ContextBlock 类扩展并实现 getContext 方法以返回您的块上下文数据。
示例: AnchorBlock.php
namespace modules\blocks; use craft\elements\Entry; use madebyraygun\blockloader\base\ContextBlock; class AnchorBlock extends ContextBlock { public function getContext(Entry $block): array { return [ 'anchorId' => $block->anchorId, ]; } }
不是很令人兴奋,但希望您能看出这为您提供了返回任何所需自定义数据的机会。
更复杂的示例可以扩展 ContextBlockSettings 类以在每个块的基础上更改设置。设置选项包括
fieldHandle:在matrix或ckeditor字段内的entry类型处理。默认情况下,这是基于类名自动生成的。例如:类RichTextBlock将在您的字段中查找richText处理。templateHandle:用于标识每个块的句柄。这可以是您用于在模板中标识块的任何 ID。eagerFields:是否 提前加载字段 以提高相关或嵌套元素的性能。以字段句柄数组的形式传递,例如['cards.image','cards.author']。cacheable:查询的结果是否应该被缓存(在大型页面上提高性能)
namespace modules\blocks; use craft\elements\Entry; use madebyraygun\blockloader\base\ContextBlock; class RichTextBlock extends ContextBlock { public function setSettings(): void { $this->settings ->templateHandle('richTextColumns') ->eagerFields([ 'richTextColumns', ]); } public function getContext(Entry $block): array { $columnsTable = $block->richTextColumns->all(); $columns = []; foreach ($columnsTable as $column) { $columns[] = [ 'body' => $body = ($field ? (string) $field : ''); ]; } return [ 'align' => $block->align->value ?? 'left', 'width' => $block->width->value ?? 'default', 'columns' => $columns, ]; } }
在你的条目模板中
{% set blocks = entry.blocksFromField('contentBlocks') %}
{% for item in blocks %}
{% include '@content-blocks/' ~ item.templateHandle with item.context %}
{% endfor %}
缓存
插件将缓存上下文块设置中定义为 cacheable 的所有块。这将提高不随每次请求更改其上下文的块的性能。每次保存条目时都会清除块缓存,只影响与保存的条目相关的块。
如果您需要全局清除所有条目的缓存,可以从 Craft 控制面板的 实用工具 > 缓存 > 块上下文数据 项中进行操作,或者从终端运行 php craft clear-caches/block-loader 命令。
此外,您可以通过将 block-loader.php 配置文件中的 enableCaching 设置为 false 来完全禁用所有块的缓存。这在开发环境中很有用,您希望立即看到块的更改。但您可能希望在生产环境中启用缓存以提高性能。
Ckeditor 字段
无论字段类型(Matrix 或 Ckeditor)如何,您都可以在条目上调用 blocksFromField 函数。插件将自动检测字段类型并以相同的格式返回块。然而,对于 Ckeditor 字段,markup 默认情况下被包装成一个块,您可以将上下文传递给特定的组件或直接渲染 markup。
{% set blocks = entry.blocksFromField('ckEditorFieldHandle') %}
{% for item in blocks %}
{% if item.templateHandle == 'markup' %}
{{ item.context.content|raw }}
{% else %}
{% include '@content-blocks/' ~ item.templateHandle with item.context %}
{% endif %}
{% endfor %}
要对 markup 上下文块进行更高级的预处理,您可以创建一个从 ContextBlock 类扩展并实现 getMarkupContext 方法的自定义类。为了使此类自动调用,必须将 fieldHandle 设置为 markup。或者只需将类命名为 MarkupBlock,插件将自动从类名派生模板句柄作为 markup。
namespace modules\blocks; use madebyraygun\blockloader\base\ContextBlock; class MarkupBlock extends ContextBlock { public function getMarkupContext(string $markup): array { // do some preprocessing on the markup before rendering $markup = preg_replace('/<p>/', '<p class="prose">', $markup); return [ 'content' => $markup, ]; } }