umanit/block-bundle
Composer 安装命令:
composer require umanit/block-bundle
包简介
Doctrine Block management made easy
README 文档
README
Doctrine Block managment made easy.
- Simple implementation
- Flexible
- Orderable Blocks
- Database consistent
- User friendly
- Dev friendly
Philosophy
Usually when dealing with blocks, developers lose their database consistency because they have to store many block types in a single table. The most common way of storing many types of blocks in one single table is to store them in a json column.
We think json is bad for database consistency and performances. Searching, indexing, managing relations, primary and unique keys... You name it, none of them is possible with json.
UmanitBlockBundle intends to solve this problem by giving back their entities to the developers.
Front requirements
- Use Symfony UX
Install
Register the bundle to your config/bundles.php
<?php return [ // ... Umanit\BlockBundle\UmanitBlockBundle::class => ['all' => true], ];
Add one of the Twig's form theme
# config/packages/twig.yaml twig: form_themes: # When using Sylius - '@UmanitBlock/sylius/form/panel.html.twig' # Read further for integration with EasyAdmin 4
Add @umanit/block-bundle dev-dependency in your package.json. This part is automatically done if you use Flex in
your projet.
{
//...
"devDependencies": {
// ...
"@umanit/block-bundle": "file:vendor/umanit/block-bundle/Resources/assets"
}
}
Add stimulus controllers to your assets/controllers.json. This part is automatically done if you use Flex in your
projet.
{
"controllers": {
// ...
"@umanit/block-bundle": {
"blocks": {
"enabled": true,
"fetch": "eager"
},
"item": {
"enabled": true,
"fetch": "eager"
},
"sortable": {
"enabled": true,
"fetch": "eager"
}
}
}
// ...
}
Don't forget to install the JavaScript dependencies as well and compile
yarn install --force
yarn encore dev
Warning
Your Stimulus app must be running on your back end if you want to use this bundle: make sure the bootstrap.js file
that starts it is imported.
Your script must be loaded using encore_entry_script_tags().
Here are exemples on how to do that depending on your back end library, given an admin.js file on your end:
EasyAdmin 4
In your DashboardController, you can do it this way:
class DashboardController extends AbstractDashboardController { public function configureAssets(): Assets { return parent::configureAssets() ->addWebpackEncoreEntry('admin') ; } }
Sonata Admin 4
Configuration
sonata_admin: templates: form_theme: - 'admin/sonata_form_theme.html.twig' assets: extra_javascripts: - 'build/admin/app.js'
app.jsneeds to import yourbootstrap.js, that loads both your own Stimulus controllers and those of Block Bundle in your Stimulus backend application- if using CKEditor, see the dedicated documentation
You'll have to modify your webpack.config.js to allow your Stimulus controllers to work in your Sonata backend:
// DO Encore.disableSingleRuntimeChunk(); // DON'T Encore .splitEntryChunks() .enableSingleRuntimeChunk();
Usage
Terminology
- A
Blockis a simple Doctrine entity that implementsUmanit\BlockBundle\Model\BlockInterface. - A
Block Manageris a service used to administrate and render aBlock. - A
Panelis a Doctrine entity that contains a collection of orderedBlockinstances.
Create an entity containing the Panel
Usually, you'll have a content entity (here we'll call it Page) having one or more 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... }
Next, use the provided PanelType form to administrate the Page content.
use Umanit\BlockBundle\Form\PanelType; $builder->add('content', PanelType::class);
Every block manager is available by default, if you want to filter them, you can give an option authorized_blocks, an
array of all the block types allowed to be selected, or unauthorized_blocks, an array of all the block types not
allowed to be selected.
use Umanit\BlockBundle\Form\PanelType; $builder->add('content', PanelType::class, [ 'authorized_blocks' => [MyBlock::class] ]); $builder->add('content', PanelType::class, [ 'unauthorized_blocks' => [MyBlock::class] ]);
Read further for integration with EasyAdmin 4 and defining a PanelField in your
CRUDController
Create a Block entity and its Block Manager
Start by creating your Block entity which should extends the bundle Block entity, like the following example:
<?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'; } }
Then, create a Block Manager service and its FormType which should extend AbstractBlockType. This service will
define the form used to administrate your Block. It will also allow you to define the rendering of the Block in the
front end.
<?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(), ], ]) ; } }
Finally, tag your Block Manager with umanit_block.manager.
# config/services.yml services: app.block_manager.title_and_text_manager: class: AppBundle\BlockManager\TitleAndTextManager arguments: ['@twig'] tags: ['umanit_block.manager']
Render your blocks
Use the twig function umanit_block_render to render each of your blocks.
{# page.html.twig #} {% for block in page.content.blocks %} {{ umanit_block_render(block) }} {% endfor %}
umanit_block_render will find the right BlockManager and call its render method.
You can pass an array of parameters to umanit_block_render. This parameters will be passed to the render method of
the BlockManager.
Embedding a panel within a collection item
Block Bundle uses Stimulus, so you don't need to do anything on your end: controllers will be instantiated as they're added to the DOM.
Integration with UmanitTranslationBundle
This bundle is fully compatible with UmanitTranslationBundle. Once
translating a Panel, all the Block instances and their properties will also be translated. If you need a locale
parameter in you BlockManager form (to filter an EntityType for example), pass the parameter to the PanelType like
so:
$builder->add('content', PanelType::class, ['locale' => 'be']);
Integration with EasyAdmin 4
Registering the provided form theme
In your DashboardController:
class DashboardController extends AbstractDashboardController { public function configureCrud(): Crud { return Crud::new() // ... ->setFormThemes([ // ... '@UmanitBlock/easy_admin/form/panel.html.twig' ]) ; } }
Using the PanelField
If defining a CrudController, you can use the provided PanelField:
public function configureFields(string $pageName): iterable { yield PanelField::new('content'); }
As with PanelType, you can define either authorized_blocks or unauthorized_blocks
if you need to restrict the available block list to some chosen options.
->setFormTypeOption('authorized_blocks', [MyBlock::class]) // or ->setFormTypeOption('unauthorized_blocks', [MyBlock::class])
Using a form type from EasyAdmin within a block
You might want to use FileUploadType, for example, in your blocks.
Block Bundle only works with Symfony form types, which means you will not be able to use EA fields in them and leverage
their powerful configurators. You can, however, still use the associated form type in your block form type but you might
need to get your hands dirty with the options.
The block.js Stimulus controllers dispatches the ea.collection.item-added after a block has been added to the DOM,
so EA JS will be bound to it.
CKEditor
Read the dedicated CKEditor documentation if you want to use it in your blocks
umanit/block-bundle 适用场景与选型建议
umanit/block-bundle 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 12.49k 次下载、GitHub Stars 达 6, 最近一次更新时间为 2018 年 06 月 21 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「symfony」 「doctrine」 「block」 「symfony-ux」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 umanit/block-bundle 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 umanit/block-bundle 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 umanit/block-bundle 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Block routes by IP
The bundle for easy using json-rpc api on your project
See how Matrix and Neo blocks are being used across your sections.
Prevent crawlers from creating a session
Make pimcore migration simple
Bundle Symfony DaplosBundle
统计信息
- 总下载量: 12.49k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 6
- 点击次数: 2
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2018-06-21