如何为单个属性自定义原型小部件模板


How can I customize prototype widget templates for a single property?

在我的应用程序中,我有类A和B.类A的对象拥有许多类B的对象。

为了编辑这些对象,我有一个复合形式。外部窗体编辑对象 A 的属性,内部窗体编辑 B 的所有拥有实例。此子窗体应将其条目显示为表行。表本身由外部窗体定义。

我的项目正在使用PHP模板引擎。到目前为止,我已经设法覆盖了模板小部件以编辑 B 类型的对象。保存 B 所有实例的 A 属性作为collection呈现到窗体中。这意味着呈现以下模板:collection_widget.html.php -> form_widget_compound.html.php -> form_rows.html.php -> form_row.html.php ->my_custom_template_widget.html.php

但是,其中一些模板会添加标签以包围它们正在渲染的模板,这会破坏我的表格布局。我已经设法通过创建_formForA_propertyB_widget.html.php并在那里手动渲染所有内容来覆盖此属性的模板来解决此问题。

我现在遇到的问题是应该可以将对象添加到此集合中。我想使用Symfony提供的原型功能来做到这一点。但是,原型似乎不是使用我的覆盖模板创建的(当然不是,因为这是针对集合而不是单行的),而是使用 form_row.html.php 创建的。我尝试通过创建_formForA_propertyB_form.html.php来覆盖它,但这没有任何区别。

如何覆盖此特定属性的原型模板?

本质上,这个问题与如何在Symfony 2表单中自定义数据原型属性非常相似,但这个问题是关于使用PHP作为模板引擎的。另一个问题的答案使用了 TWIG 模板引擎的功能,而这些功能在 PHP 引擎中不可用。


说明问题的示例代码:

视图/编辑A.html.php:

<table data-prototype="<?php echo $view->escape($view['form']->row($form['collectionOfB']->vars['prototype'])) ?>">
    <thead>
    <tr>
        <th>Description</th>
        <th>Prop1</th>
        <th>Prop2</th>
    </tr>
    </thead>
    <tbody>
        <?php echo $view['form']->widget($form['collectionOfB']) ?>
    </tbody>
</table>

视图/表单/_objectA_collectionOfB_widget.html.php:

<?php foreach ($form as $child) : ?>
    <?php echo $view['form']->widget($child) ?>
<?php endforeach; ?>

视图/表单/objectB_widget.html.php:

<tr>
    <td><?php echo $view['form']->widget($form['description']) ?>
        <?php echo $view['form']->errors($form['description']) ?></td>
    <td><?php echo $view['form']->widget($form['prop1']) ?>
        <?php echo $view['form']->errors($form['prop1']) ?></td>
    <td><?php echo $view['form']->widget($form['prop2']) ?>
        <?php echo $view['form']->errors($form['prop2']) ?></td>
</tr>

正如我所说,表单呈现正确,但这是原型:

<div>
    <label class="required" >__name__label__</label>
    <tr>
    <!-- snip more code here -->
    </tr>
</div>

你可以看到它包含 label 和一个div ,两者都我不想要,因为它会破坏桌子。

事实证明,答案比我想象的要简单得多。我只需要渲染小部件,而不是渲染整行(从而渲染包含div的form_row.html.php模板)。

基本上您需要做的就是更换

$view->escape($view['form']->row($form['collectionOfB']->vars['prototype']))

$view->escape($view['form']->widget($form['collectionOfB']->vars['prototype']))