heimrichhannot / contao-form-type-bundle
为contao表单生成器添加类型。
Requires
- php: ^8.1
- contao/core-bundle: ^4.13 || ^5.0.8
- symfony/event-dispatcher-contracts: ^1.0 || ^2.0 || ^3.0
- symfony/translation-contracts: ^1.0 || ^2.0 || ^3.0
README
表单类型包是Contao CMS的扩展,提供了一种通用的方式来使用contao表单生成器创建特定方法的表单。它面向开发者,不包含内置的表单类型。
特性
- 使用contao表单生成器创建特定方法的表单的通用方式
- 为选择、复选框和单选框表单字段提供选项事件
- 表单类型可以支持一个首次向导来设置基本表单字段
安装
通过composer安装包,然后更新数据库
composer require heimrichhannot/contao-form-type-bundle
使用方法
创建新的表单类型
创建一个新的类,该类扩展了AbstractFormType
。将其注册为服务,并启用自动配置。
可以在$GLOBALS['TL_LANG']['tl_form']['FORMTYPE']
中设置标签
# contao/languages/de/tl_form.php $GLOBALS['TL_LANG']['tl_form']['FORMTYPE']['huh_mediathek'] = 'Mediathek';
首次向导
您可以通过实现getDefaultFields()
方法向您的表单类型添加首次向导。它期望以数组格式返回字段定义作为返回值。这些字段将在执行向导时创建。
public function getDefaultFields(FormModel $formModel): array { return [ [ 'type' => 'text', 'name' => 'title', 'label' => $this->translator->trans('tl_example.title.0', [], 'contao_tl_example'), 'mandatory' => '1', ], [ 'type' => 'textarea', 'name' => 'text', 'label' => $this->translator->trans('tl_example.text.0', [], 'contao_tl_example'), ], ]; }
表单事件
您可以为表单生命周期中的事件注册事件监听器。这些事件是对相应Contao表单钩子的映射,但只会为特定表单类型触发。
以下事件可用
选项事件
如果您想为选择、复选框或单选框表单字段提供选项,您可以注册事件监听器。事件名称为huh.form_type.<formtype>.<field>.options'
。
// src/EventListener/OptionsEventListener.php use HeimrichHannot\FormTypeBundle\Event\FieldOptionsEvent; class OptionsEventListener implements EventSubscriberInterface { public static function getSubscribedEvents() { return [ 'huh.form_type.huh_media_library.licence.options' => 'onLicenceOptions', ]; } public function onLicenceOptions(FieldOptionsEvent $event): void { $event->addOption('free', 'Free'); $event->addOption('adobe', 'Adobe'); $event->addOption('istock', 'iStock'); } }
字段选项的统一分发器
使用FieldOptionsDispatcherTrait
来分发FieldOptionsEvent
huh.form_type.<formtype>.<field>.options
和Contao fields.<field>.options
回调。
示例
use HeimrichHannot\MediaLibraryBundle\Trait\FieldOptionsDispatcherTrait; class MyContainerOrFormType { use FieldOptionsDispatcherTrait; #[AsCallback(table: 'tl_ml_product', target: 'fields.licence.options')] #[AsEventListener('huh.form_type.huh_media_library.licence.options')] public function getLicenceOptions(): array { return $this->dispatchFieldOptions([ 'free' => 'Released for use under indication of copyright', 'locked' => 'Subject to licence' ]); } }
表单上下文
在您的表单类型上实现表单上下文评估器,允许您根据表单的使用上下文改变表单的行为。这可以用来将现有数据加载到表单字段中,例如创建一个编辑表单。
内置的表单编辑上下文
该包内置了一个基本的默认表单上下文评估器,提供编辑功能。只需在您的表单类型中重写DEFAULT_FORM_CONTEXT_TABLE
即可允许编辑相应的数据库模型。
protected const DEFAULT_FORM_CONTEXT_TABLE = 'tl_my_table';
- 在Contao中创建您的表单。
- 根据您想要编辑的数据库字段命名您的表单字段,例如
title
用于tl_my_table.title
。 - 将查询参数
?edit=<id>
追加到包含表单的页面URL,以编辑具有主键<id>
的现有行。
如果没有设置DEFAULT_FORM_CONTEXT_TABLE
,则默认将表单视为创建表单。
创建您自己的表单上下文
要实现自己的表单上下文评估器,在您的表单类型中重写evaluateFormContext()
。
protected function evaluateFormContext(): FormContext { $request = $this->container->get('request_stack')->getCurrentRequest(); $editParameter = 'edit'; $databaseTable = 'tl_my_table'; if ($modelPk = $request->query->get($editParameter)) { /** @var class-string<Model> $modelClass */ $modelClass = Model::getClassFromTable($databaseTable); $modelInstance = $modelClass::findByPk($modelPk); if ($modelInstance === null) { return FormContext::invalid($databaseTable, 'Could not find object.'); } return FormContext::update($databaseTable, $modelInstance->row()); } return FormContext::create($databaseTable); }
示例显示了一个表单上下文评估器的实现,该评估器允许通过查询参数edit
提供的键编辑数据库模型。
要检索当前的表单上下文,请调用您的表单类型上的getter。
$formContext = $this->getFormContext();
我们不推荐直接调用$this->evaluateFormContext()
,因为这会跳过您这样做时的未来缓存实现。
表单上下文操作
最常用的表单上下文操作已经实现。
use HeimrichHannot\FormTypeBundle\FormType\FormContextAction; FormContextAction::CREATE; FormContextAction::READ; FormContextAction::UPDATE; FormContextAction::DELETE; FormContextAction::CLONE; FormContextAction::INVALID;
FormContextAction::INVALID
可用于指示表单不应被处理。
要使用内置操作实例化一个FormContext
对象,请使用静态工厂方法
use HeimrichHannot\FormTypeBundle\FormType\FormContext; $createContext = FormContext::create('tl_my_table'); $readContext = FormContext::read('tl_my_table', $data); $updateContext = FormContext::update('tl_my_table', $data); $deleteContext = FormContext::delete('tl_my_table', $data); $cloneContext = FormContext::clone('tl_my_table', $data); $invalidContext = FormContext::invalid('tl_my_table', 'This is error detail.', $additionalData ?? []);
或者,您也可以使用FormContext
构造函数
use HeimrichHannot\FormTypeBundle\FormType\FormContext; use HeimrichHannot\FormTypeBundle\FormType\FormContextAction; $formContext = new FormContext(FormContextAction::UPDATE, 'tl_my_table', $data);
然而,在构建 FormContext
对象时,您也可以指定自己的操作,或者通过覆盖现有对象的操作来实现。
use HeimrichHannot\FormTypeBundle\FormType\FormContext; use HeimrichHannot\FormTypeBundle\FormType\FormContextAction; $formContext = new FormContext('my_custom_action', 'tl_my_table', $data); // or $formContext->setAction('this_can_be_any_string_or_action'); // or $formContext->setAction(FormContextAction::DELETE);
这样,您就不受内置操作的约束。