Если кому-то все равно, я думаю, я нашел замечательное решение, которое позволяет рекурсивно перебирать флажки в шаблоне. Идея заключается в том, что вы настраиваете виджет «relatedmodel_list» в виде единого флажка и многократно визуализируете его в своем шаблоне (при переборе коллекции связанных моделей).
class ModelForm extends BaseBookForm
{
public function configure()
{
$this->setWidget('relatedmodel_list', new myWidgetFormInputCheckbox());
}
}
Флажки теперь имеют неверные атрибуты имени и значения. Это можно исправить очень легко:
class myWidgetFormInputCheckbox extends sfWidgetFormInputCheckbox
{
public function render($name, $value = null, $attributes = array(), $errors = array())
{
//fix value checking
if (in_array($attributes['value'], (array)$value))
{
$attributes['checked'] = 'checked';
}
//fix name for multiple
$name = $name . "[]";
return parent::render($name, null, $attributes, $errors);
}
}
Теперь мы можем рекурсивно визуализировать наш виджет формы в шаблоне:
//_form.php
<ul>
// Model::getRelatedTree() is proxy to Relatedmodel::fetchTree()
<?php include_partial('node', array('node' => $form->getObject()->getRelatedTree(), 'form' => $form)) ?>
</ul>
//_node.php
<?php foreach ($node as $item): ?>
<li>
<?php echo $form['pages_list']->render(array('value'=>$item->id)) ?>
<?php echo $form['pages_list']->renderLabel((string)$item) ?>
<?php if (isset($item['__children']) && count($item['__children']) > 0): ?>
<ul>
<?php include_partial('node', array('node' => $item['__children'], 'form' => $form)) ?>
</ul>
<?php endif; ?>
</li>
<?php endforeach; ?>