brandcom/cakephp-content-blocks

CakePHP的内容块插件

安装: 126

依赖项: 0

建议者: 0

安全性: 0

星标: 0

关注者: 1

分支: 0

开放问题: 0

类型:cakephp-plugin

v0.3.2 2022-11-18 15:08 UTC

This package is auto-updated.

Last update: 2024-09-18 18:56:30 UTC


README

安装

您可以使用 composer 将此插件安装到您的 CakePHP 应用程序中。

安装 composer 包的推荐方法是

composer require brandcom/cakephp-content-blocks

加载插件

bin/cake plugin load ContentBlocks

... 并运行迁移

bin/cake migrations migrate --plugin ContentBlocks

入门指南

1. 创建块

该插件不附带任何块,因此您需要自己创建它们。

让我们创建一个简单的 TextContentBlock,它具有 titlecontent 字段。

注意:每个 ContentBlock 必须以 *ContentBlock 结尾

  1. 在您的数据库中,创建一个名为 text_content_blocks 的表,具有字段 title(Varchar 255)和 content(Text)。注意:您还需要一个 id 字段和一个 content_blocks_block_id 字段,类型为 int(11), unsigned

  2. 然后,运行 bin/cake bake model text_content_blocks 命令。您不需要任何模板或控制器。

  3. 编辑生成的 TextContentBlock.php 文件,并将类扩展为 ContentBlocks\Model\Entity\Block 而不是 Entity

  4. 修改您的 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

  1. 让您的幻灯片实体使用ContentBlocks\Model\Entity\Traits\BelongsToBlockTrait
  2. 如第6点所述包含幻灯片
  3. 在您的SliderContentBlock中,重写BlockgetManagedModels()方法。这应该返回一个数组,包含所有在管理表单中可编辑的相关模型。
public function getManagedModels(): array
{
    return [
        "SliderBlockSlides,"
    ];
}
  1. 要自定义管理表单中的外观,您可以重写来自BelongsToBlockTrait的方法,例如定义更漂亮的标题或控制哪些字段可编辑(类似于第5点“修改管理界面”)。

8. 向块模板传递自定义数据

默认情况下,块区域的包含模型作为$owner传递到模板中,因此,例如,如果您有一个具有TextContentBlockArticle实体,您的文章实体将在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,
    ];
}

贡献

您可以通过拉取请求或问题来为此项目做出贡献。