umanit / block-bundle
简化 Doctrine 块管理
Requires
- php: ^7.1|^8.0
- doctrine/doctrine-bundle: ^1.6|^2.1
- doctrine/orm: ^2.5
- symfony/form: ^4.4|^5.2|^6.0
- symfony/framework-bundle: ^4.4|^5.2|^6.0
- symfony/translation-contracts: ^1.1|^2.3|^3.0
- symfony/validator: ^4.4|^5.2|^6.0
Suggests
- umanit/translation-bundle: Allow your panel to be translated.
This package is auto-updated.
Last update: 2024-09-09 12:31:32 UTC
README
简化 Doctrine 块管理。
- 简单实现
- 灵活
- 可排序的块
- 数据库一致性
- 用户友好
- 开发者友好
哲学
通常在处理块时,由于需要在单个表中存储许多块类型,开发者会丢失数据库一致性。在单个表中存储多种类型块的最常见方式是将它们存储在 json 列中。
我们认为 json 对数据库一致性和性能不好。搜索、索引、管理关系、主键和唯一键等,没有一个是与 json 兼容的。
UmanitBlockBundle 通过将实体归还给开发者来解决这个问题。
前端要求
- 使用 Symfony UX
安装
将包注册到 config/bundles.php
<?php return [ // ... Umanit\BlockBundle\UmanitBlockBundle::class => ['all' => true], ];
添加 Twig 的一个表单主题
# config/packages/twig.yaml twig: form_themes: # When using Sylius - '@UmanitBlock/sylius/form/panel.html.twig' # Read further for integration with EasyAdmin 4
在 package.json
中添加 @umanit/block-bundle
开发依赖。如果您的项目使用 Flex,这部分会自动完成。
{ //... "devDependencies": { // ... "@umanit/block-bundle": "file:vendor/umanit/block-bundle/Resources/assets" } }
将刺激控制器添加到 assets/controllers.json
。如果您的项目使用 Flex,这部分会自动完成。
{ "controllers": { // ... "@umanit/block-bundle": { "blocks": { "enabled": true, "fetch": "eager" }, "item": { "enabled": true, "fetch": "eager" }, "sortable": { "enabled": true, "fetch": "eager" } } } // ... }
不要忘记安装 JavaScript 依赖项并编译
yarn install --force
yarn encore dev
警告
如果您想使用此包,则必须在您的后端运行 Stimulus 应用程序:确保导入启动它的 bootstrap.js
文件。您的脚本必须使用 encore_entry_script_tags()
加载。
以下是根据您的后端库如何操作的示例,假设您的末端有一个 admin.js
文件
EasyAdmin 4
在您的 DashboardController
中,您可以这样做
class DashboardController extends AbstractDashboardController { public function configureAssets(): Assets { return parent::configureAssets() ->addWebpackEncoreEntry('admin') ; } }
Sonata Admin 4
配置
sonata_admin: templates: form_theme: - 'admin/sonata_form_theme.html.twig' assets: extra_javascripts: - 'build/admin/app.js'
app.js
需要导入您的bootstrap.js
,它加载您自己的 Stimulus 控制器和块包在您的 Stimulus 后端应用程序中的那些- 如果您使用 CKEditor,请参阅 专用文档
您需要修改 webpack.config.js
以允许您的 Stimulus 控制器在您的 Sonata 后端中工作
// DO Encore.disableSingleRuntimeChunk(); // DON'T Encore .splitEntryChunks() .enableSingleRuntimeChunk();
用法
术语
块
是一个简单的 Doctrine 实体,它实现了Umanit\BlockBundle\Model\BlockInterface
。块管理器
是一个用于管理和渲染块
的服务。面板
是一个包含有序块
实例集合的 Doctrine 实体。
创建包含面板的实体
通常,您将有一个内容实体(在此我们将其称为 Page
),它有一个或多个 Panels
。
<?php namespace AppBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Umanit\BlockBundle\Entity\Panel; /** * @ORM\Entity() */ #[ORM\Entity] class Page { // Your other fields... /** * @var Panel * * @ORM\ManyToOne(targetEntity="Umanit\BlockBundle\Entity\Panel", cascade={"persist"}) * @ORM\JoinColumn(name="panel_id", referencedColumnName="id") */ #[ORM\ManyToOne(targetEntity: 'Umanit\BlockBundle\Entity\Panel', cascade: ['persist'])] #[ORM\JoinColumn(name: 'panel_id', referencedColumnName: 'id')] protected $content; // Getters and Setters... }
接下来,使用提供的 PanelType
表单来管理 Page
内容。
use Umanit\BlockBundle\Form\PanelType; $builder->add('content', PanelType::class);
默认情况下,每个块管理器都是可用的。如果想要过滤它们,可以提供一个选项 authorized_blocks
,这是一个包含所有允许选择的块类型的数组,或者 unauthorized_blocks
,这是一个包含所有不允许选择的块类型的数组。
use Umanit\BlockBundle\Form\PanelType; $builder->add('content', PanelType::class, [ 'authorized_blocks' => [MyBlock::class] ]); $builder->add('content', PanelType::class, [ 'unauthorized_blocks' => [MyBlock::class] ]);
阅读更多 以了解与 EasyAdmin 4 的集成以及在您的 CRUDController 中定义 PanelField
创建一个块实体及其块管理器
首先创建您的 Block
实体,它应扩展包的 Block
实体,如下例所示
<?php namespace AppBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Umanit\BlockBundle\Entity\Block; /** * @ORM\Entity() */ #[ORM\Entity] class TitleAndText extends Block { /** * @var string * * @ORM\Column(name="title", type="string") */ #[ORM\Column(name: 'title', type: 'string')] private $title; /** * @var string * * @ORM\Column(name="text", type="text") */ #[ORM\Column(name: 'text', type: 'text')] private $text; // getters and setters ... /** * */ public function __toString() { return $this->getTitle() ? : 'New TitleAndText'; } }
然后,创建一个 块管理器
服务及其 表单类型
,该类型应扩展 AbstractBlockType
。此服务将定义用于管理您的 块
的表单。它还将允许您定义前端中 块
的渲染。
<?php namespace AppBundle\BlockManager; use AppBundle\Entity\TitleAndText; use AppBundle\Form\TitleAndTextType; use Umanit\BlockBundle\Block\AbstractBlockManager; use Umanit\BlockBundle\Model\BlockInterface; use Twig\Environment; use \Twig\Error\LoaderError; use \Twig\Error\RuntimeError; use \Twig\Error\SyntaxError; class TitleAndTextManager extends AbstractBlockManager { /** @var Environment */ private $twig; /** * QuoteBlockManager constructor. * * @param Environment $twig */ public function __construct(Environment $twig) { $this->twig = $twig; } /** * Define which Block type is managed by this Manager * * @return string */ public function getManagedBlockType(): string { return TitleAndText::class; } /** * This method must return the form typemanaged by this block manager. * * @return string */ public function getManagedFormType(): string { return TitleAndTextType::class; } /** * Define how the block should be rendered on the front end. * * @param BlockInterface $block * @param array $parameters * * @return string * @throws LoaderError * @throws RuntimeError * @throws SyntaxError */ public function render(BlockInterface $block, array $parameters = []): string { return $this->twig->render('blocks/title-and-text.html.twig', ['block' => $block]); } }
<?php namespace AppBundle\Form\TitleAndTextType; use Umanit\BlockBundle\Form\AbstractBlockType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Validator\Constraints\NotBlank; class TitleAndTextType extends AbstractBlockType { /** * Define the form used by the back end to administrate the block. * * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('title', TextType::class, [ 'constraints' => [ new NotBlank(), ], ]) ->add('text', TextareaType::class, [ 'constraints' => [ new NotBlank(), ], ]) ; } }
最后,使用 umanit_block.manager
标记您的 块管理器
。
# config/services.yml services: app.block_manager.title_and_text_manager: class: AppBundle\BlockManager\TitleAndTextManager arguments: ['@twig'] tags: ['umanit_block.manager']
渲染您的块
使用 twig 函数 umanit_block_render
来渲染您每个块。
{# page.html.twig #} {% for block in page.content.blocks %} {{ umanit_block_render(block) }} {% endfor %}
umanit_block_render
将找到正确的 BlockManager
并调用其 render
方法。
您可以将参数数组传递给 umanit_block_render
。这些参数将被传递到 BlockManager
的 render
方法。
在集合项中嵌入面板
块包使用 Stimulus,因此您不需要在您的端上做任何事情:控制器将在它们添加到 DOM 中时实例化。
与 UmanitTranslationBundle 的集成
此包与 UmanitTranslationBundle 完全兼容。一旦翻译一个 面板
,所有 块
实例及其属性也将被翻译。如果您的 BlockManager
表单(例如,用于筛选 EntityType
)需要地区参数,请将参数按如下方式传递给 PanelType
$builder->add('content', PanelType::class, ['locale' => 'be']);
与 EasyAdmin 4 的集成
注册提供的表单主题
在您的 DashboardController
中
class DashboardController extends AbstractDashboardController { public function configureCrud(): Crud { return Crud::new() // ... ->setFormThemes([ // ... '@UmanitBlock/easy_admin/form/panel.html.twig' ]) ; } }
使用 PanelField
如果您正在定义 CrudController
,则可以使用提供的 PanelField
public function configureFields(string $pageName): iterable { yield PanelField::new('content'); }
与 PanelType
一样,如果需要将可用的块列表限制为一些选择选项,则可以定义 authorized_blocks
或 unauthorized_blocks
。
->setFormTypeOption('authorized_blocks', [MyBlock::class]) // or ->setFormTypeOption('unauthorized_blocks', [MyBlock::class])
在块中使用 EasyAdmin 的表单类型
例如,您可能想在您的块中使用 FileUploadType
。块包仅与 Symfony 表单类型一起使用,这意味着您将无法在这些字段中使用 EA 字段并利用它们强大的配置器。然而,您仍然可以在您的块表单类型中使用关联的表单类型,但您可能需要手动处理选项。
block.js
Stimulus 控制器在块被添加到 DOM 后分派 ea.collection.item-added
事件,因此 EA JS 将绑定到它。