表单主题 - 在 n block_name 匹配处添加代码
Form themes - Add code at n block_name match
我有一个前端 symfony 应用程序,它从 API 中获取序列化的 symfony 形式,解析它并最终呈现它。
这个应用程序应该是愚蠢的,不应该以任何方式知道任何远程应用程序的逻辑。
只是取json形式,解析后显示
序列化表单中的字段具有自定义(远程应用程序定义)块名称,然后在前端应用程序的表单主题中使用这些名称来构建字段结构。
表示字段示例:
"field_1": {
"options": {
"block_name": "block_name_example",
"label": "Example",
"required": true,
"disabled": false,
"choices": {
"Choice 1": "1",
"Choice 2": "2"
},
"help_description": "",
"attr": {
"name": "field_name_1",
"short_name": "fieldName1"
}
},
"type": "Symfony\Component\Form\Extension\Core\Type\ChoiceType"
}
我想在 form_theme 块中添加一些内容 "the first time this block name is matched"(例如),无需在远程应用程序端添加任何逻辑 , 类似 :
{% block _form_block_name_example %}
{% if match_occurrence = 1 %}
{# do something here #}
{% endif %}
{{ form_widget(form) }}
{% endblock %}
我知道有很多方法(表单字段额外选项,将其包装到集合类型字段中......)通过远程应用程序代码编辑来解决这个问题,但由于各种原因我不想这样做,主要一个是避免远程应用程序代码的任何额外复杂性。
找不到解决此问题的简洁方法。你会成为我的英雄吗?
我想到了一种仅在前端应用程序上处理此问题的非常简洁的方法。从不相关的代码中最大限度地剥离 类 并重命名一些东西,使其尽可能通用。
我通过表单扩展向我的字段添加了一个新的额外 first_of_type
选项,这是我在生成表单时设置的。然后我将它用作表单主题块中的一个随意选项。下面的代码。
表单扩展:
class ExtraOptionsExtension extends AbstractTypeExtension
{
/**
* Add the width option.
*
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefined([
/* ... */
'first_of_type'
]);
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
/* ... */
$view->vars['first_of_type'] = false;
if (!empty($options['first_of_type'])) {
$view->vars['first_of_type'] = true;
}
}
/**
* Returns the name of the type being extended.
*
* @return string The name of the type being extended
*/
public function getExtendedType()
{
return FormType::class;
}
}
表单类型:
abstract class AbstractType extends BaseAbstractType
{
/* ... */
/**
* {@inheritdoc}
*
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$blockNames = [];
if (is_array($this->fields)) {
foreach ($this->fields as $property => $data) {
$type = $data['type'] ?? null;
$opts = $data['options'] ?? [];
if (!in_array($type, $this::TYPES_WITHOUT_EXTRA) &&
isset($data['options']['block_name']) &&
!in_array($data['options']['block_name'], $blockNames)) {
$blockNames[] = $data['options']['block_name'];
$opts['first_of_type'] = true;
}
$builder->add($property, $type, $opts);
}
}
}
/* ... */
}
表单主题块:
{% block custom_block %}
<div class="form-group form-inline {% if not first_of_type %} hide {% else %}">
{{ form_label(form, null, {'label_attr': {'class': 'control-label'}}) }}
{{ form_widget(form) }}
</div>
{% endblock %}
仍然可以改进以提供更多关于元素与其成对相比的位置的信息(不仅仅是它是第一个的事实)。
我有一个前端 symfony 应用程序,它从 API 中获取序列化的 symfony 形式,解析它并最终呈现它。
这个应用程序应该是愚蠢的,不应该以任何方式知道任何远程应用程序的逻辑。 只是取json形式,解析后显示
序列化表单中的字段具有自定义(远程应用程序定义)块名称,然后在前端应用程序的表单主题中使用这些名称来构建字段结构。
表示字段示例:
"field_1": {
"options": {
"block_name": "block_name_example",
"label": "Example",
"required": true,
"disabled": false,
"choices": {
"Choice 1": "1",
"Choice 2": "2"
},
"help_description": "",
"attr": {
"name": "field_name_1",
"short_name": "fieldName1"
}
},
"type": "Symfony\Component\Form\Extension\Core\Type\ChoiceType"
}
我想在 form_theme 块中添加一些内容 "the first time this block name is matched"(例如),无需在远程应用程序端添加任何逻辑 , 类似 :
{% block _form_block_name_example %}
{% if match_occurrence = 1 %}
{# do something here #}
{% endif %}
{{ form_widget(form) }}
{% endblock %}
我知道有很多方法(表单字段额外选项,将其包装到集合类型字段中......)通过远程应用程序代码编辑来解决这个问题,但由于各种原因我不想这样做,主要一个是避免远程应用程序代码的任何额外复杂性。
找不到解决此问题的简洁方法。你会成为我的英雄吗?
我想到了一种仅在前端应用程序上处理此问题的非常简洁的方法。从不相关的代码中最大限度地剥离 类 并重命名一些东西,使其尽可能通用。
我通过表单扩展向我的字段添加了一个新的额外 first_of_type
选项,这是我在生成表单时设置的。然后我将它用作表单主题块中的一个随意选项。下面的代码。
表单扩展:
class ExtraOptionsExtension extends AbstractTypeExtension
{
/**
* Add the width option.
*
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefined([
/* ... */
'first_of_type'
]);
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
/* ... */
$view->vars['first_of_type'] = false;
if (!empty($options['first_of_type'])) {
$view->vars['first_of_type'] = true;
}
}
/**
* Returns the name of the type being extended.
*
* @return string The name of the type being extended
*/
public function getExtendedType()
{
return FormType::class;
}
}
表单类型:
abstract class AbstractType extends BaseAbstractType
{
/* ... */
/**
* {@inheritdoc}
*
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$blockNames = [];
if (is_array($this->fields)) {
foreach ($this->fields as $property => $data) {
$type = $data['type'] ?? null;
$opts = $data['options'] ?? [];
if (!in_array($type, $this::TYPES_WITHOUT_EXTRA) &&
isset($data['options']['block_name']) &&
!in_array($data['options']['block_name'], $blockNames)) {
$blockNames[] = $data['options']['block_name'];
$opts['first_of_type'] = true;
}
$builder->add($property, $type, $opts);
}
}
}
/* ... */
}
表单主题块:
{% block custom_block %}
<div class="form-group form-inline {% if not first_of_type %} hide {% else %}">
{{ form_label(form, null, {'label_attr': {'class': 'control-label'}}) }}
{{ form_widget(form) }}
</div>
{% endblock %}
仍然可以改进以提供更多关于元素与其成对相比的位置的信息(不仅仅是它是第一个的事实)。