brandcom / cakephp-content-blocks
CakePHP的内容块插件
Requires
- cakephp/cakephp: ^3.5
Requires (Dev)
- phpunit/phpunit: ^5.7.14|^6.0
README
安装
您可以使用 composer 将此插件安装到您的 CakePHP 应用程序中。
安装 composer 包的推荐方法是
composer require brandcom/cakephp-content-blocks
加载插件
bin/cake plugin load ContentBlocks
... 并运行迁移
bin/cake migrations migrate --plugin ContentBlocks
入门指南
1. 创建块
该插件不附带任何块,因此您需要自己创建它们。
让我们创建一个简单的 TextContentBlock,它具有 title 和 content 字段。
注意:每个 ContentBlock 必须以
*ContentBlock结尾
-
在您的数据库中,创建一个名为
text_content_blocks的表,具有字段title(Varchar 255)和content(Text)。注意:您还需要一个id字段和一个content_blocks_block_id字段,类型为int(11), unsigned。 -
然后,运行
bin/cake bake model text_content_blocks命令。您不需要任何模板或控制器。 -
编辑生成的
TextContentBlock.php文件,并将类扩展为ContentBlocks\Model\Entity\Block而不是Entity。 -
修改您的
TextContentBlocksTable.php,以便您的TextContentBlocksTable扩展ContentBlocks\Model\Entity\BlocksTable,并按以下方式修改类
设置关系
$this->belongsTo('Blocks', [
'foreignKey' => 'content_blocks_block_id',
'className' => 'ContentBlocks.Blocks',
]);
修复 buildRules() 方法,将 table 设置为 Blocks
$rules->add($rules->existsIn(['content_blocks_block_id'], 'Blocks'));
下面将介绍更多关于自定义块的内容,但让我们现在将其添加到您的某个页面。
2. 管理界面
要将您的 TextContentBlock 添加到实体,例如 Article,请将 BlocksAdmin 单元添加到您的编辑模板
<?= $this->cell("ContentBlocks.BlocksAdmin", ['entityOrKey' => $article]) ?>
这将渲染表示相应实体 BlockArea 的表格。
0.3 版本新增:您还可以为自定义键创建区域,例如在网站的其他位置或索引页面上
<?= $this->cell("ContentBlocks.BlocksAdmin", ['entityOrKey' => 'my_custom_key']) ?>
在表格底部,将为每个 ContentBlock 添加一个按钮。您应该已经找到了一个标题为 Text 的按钮。
如果您点击该按钮,将向 BlockArea 添加一个新块。您可以输入内容并保存。
3. 为您的块创建一个模板
ContentBlock 模板是元素。在您的 Template/Element 文件夹中,创建文件夹 content_blocks/ 和文件 text.ctp。
模板文件名始终是您的模型名的下划线小写版本,省略了 content_block。
因此,MyCoolHeroHeaderContentBlock 的模板将在 /Template/Element/content_blocks/my_cool_hero_header.ctp 中。
您的 TextContentBlock 实体将作为 $block 变量可用。
现在您可以创建模板
<?php
/**
* @var \App\Model\Entity\TextContentBlock $block
*/
?>
<section class="my-12">
<h2>
<?= $block->title ?>
</h2>
<div class="content">
<?= $block->content ?>
</div>
</section>
注意:您可以通过覆盖
TextContentBlock实体中的render()方法来更改TextContentBlock实体中的渲染逻辑。
4. 显示块
要为实体渲染块区域,请将此单元格添加到模板
<?= $this->cell("ContentBlocks.BlocksArea", ['entity' => $article]) ?>
5. 修改管理界面
如果您想更改字段的显示方式,您可以在 TextContentBlock 实体中覆盖 getFields() 方法。
该方法应返回一个数组,其中包含所有可编辑字段,字段名称作为键,值是一个数组,该数组作为 $options 传递给 FormHelper::control。
public function getFields(): array
{
return array_merge(
parent::getFields(),
[
'title' => [
'label' => __("Block Title"),
],
'style' => [
'label' => __("Choose a style for this block."),
'options' => [
'default' => __("Default Style"),
'funky' => __("Other cool Style"),
],
],
]
);
}
特殊字段选项
beforeControl:将在相应控件之前渲染。afterControl:将在相应控件之后渲染。
要更改隐藏字段,请重写Block::getHiddenFields()
public function getHiddenFields(): array
{
return array_merge(
parent::getHiddenFields(),
[
'some_field',
'another_hidden_field',
]
);
}
例如,默认情况下content_blocks_block_id是隐藏的,你可能希望使其可编辑。
6. 包含关联模型
在您的TextContenBlocksTable中定义一个beforeFind()方法
public function beforeFind(Event $event, Query $query): Query
{
return $query->contain([
'Images',
]);
}
7. 编辑相关模型
该插件支持即使是相关模型也具有管理界面。
HasMany关系
假设您有一个具有多个幻灯片的SliderContentBlock。这意味着,您将有一个例如SliderBlockSlide实体和SliderBlockSlidesTable。
- 让您的幻灯片实体使用
ContentBlocks\Model\Entity\Traits\BelongsToBlockTrait - 如第6点所述包含幻灯片
- 在您的
SliderContentBlock中,重写Block的getManagedModels()方法。这应该返回一个数组,包含所有在管理表单中可编辑的相关模型。
public function getManagedModels(): array
{
return [
"SliderBlockSlides,"
];
}
- 要自定义管理表单中的外观,您可以重写来自
BelongsToBlockTrait的方法,例如定义更漂亮的标题或控制哪些字段可编辑(类似于第5点“修改管理界面”)。
8. 向块模板传递自定义数据
默认情况下,块区域的包含模型作为$owner传递到模板中,因此,例如,如果您有一个具有TextContentBlock的Article实体,您的文章实体将在text.ctp中以$owner的形式访问。
您可以通过重写您的*ContentBlocksTable中的getViewVariables()方法来覆盖此操作 - 并添加更多视图变量。
如果您想重命名$owner并添加更多数据,可以这样做
public function getViewVariables($entity): array
{
$vars = parent::getViewVariables($entity);
return [
'article' => $vars['owner'],
'random' => "This is just a string",
'someOtherVariable' => $this->getSomeOtherVariable($entity),
];
}
$entity,您的*ContentBlock的实例,将被传递到该方法。
9. 在特定实体上允许或禁止ContentBlock
如果实体的模型在ContentBlock::getDisallowedEntities()中列出,它将永远不会在块列表中可见。
protected function getDisallowedEntities(): array
{
return [
"Articles",
"Jobs",
];
}
您也可以定义一个允许的实体列表
protected function getAllowedEntities(): array
{
return [
"BlogPosts",
];
}
注意:如果模型同时出现在两者中,则会被禁止。
10. 块HTML锚点和(自定义)预览链接
新功能 0.2.0:每个块都有一个HTML锚点字段。在下方显示链接到锚点的链接。
要覆盖默认路由,您可以在您的$owner实体上定义一个URL,该URL包含区域,例如Articles。如果有必要使用slug或其他参数,这将很有用。将传递$block实例到方法中。
public function getContentBlocksViewUrl(Block $block): array
{
$anchor = $block->html_anchor ?: "content-block-" . $block->id;
return [
'prefix' => false,
'plugin' => false,
'controller' => 'Articles',
'action' => 'view',
$this->slug,
'#' => $anchor,
];
}
贡献
您可以通过拉取请求或问题来为此项目做出贡献。