Simplifying the drawing of forms in Symfony

No Gravatar

Implementing forms in 2011 is still a challenge, even with a framework like Symfony helping you along. sfForm is great for defining widgets and validators but it sucks at outputting practical markup.

Practical Markup

For me, the ideal markup for a form field looks like:

This gives me a lot of flexiblity for styling. Unfortunately I was never able to find a way to acheive this using formatters, and so I continued on writing very verbose forms. Luckily I grew weary of this and decided to see if I could create a helper to ease the output of forms. The following is what I cam up with:

<?php
function my_form_field($form, $key, $label = null)
{
  if (is_array($form)) {
    $embedded_keys = array_slice($form, 1);
    $form = $field_schema = $form[0];
    foreach ($embedded_keys as $embedded_key) {
      $field_schema = $field_schema[$embedded_key];
      $form = $form->getEmbeddedForm($embedded_key);
    }
  } else {
    $field_schema = $form->getFormFieldSchema();
  }

  $widget_type = str_replace('_', '-', sfInflector::tableize(str_replace('sfWidgetForm', '', get_class($form->getWidget($key)))));
  $classes = array('my-form-field', $widget_type, $field_schema[$key]->renderId());
  if ($field_schema[$key]->hasError())
    $classes[] = 'has-error';

  if (is_null($label)) {
    $label = $field_schema[$key]->renderLabelName();
  }  

  if ($form->getValidator($key)->getOption('required')) {
    $label .= '*';
  }

  ?>
<?php echo $field_schema[$key]->renderLabel($label) ?> <?php echo $field_schema[$key]->renderError() ?>
<?php echo $field_schema[$key]->render() ?>
<?php }

Now in I’m able to generate markup for my forms fairly concisely:

<?php my_form_field($form, 'field_1', 'custom label 1') ?> <?php my_form_field($form, 'field_1', 'custom label 2') ?> <?php my_form_field($form, 'field_1', 'custom label 3') ?>

This even works form embedded forms:

<?php my_form_field(array($form, 'embedded_form_key'), 'field_1', 'custom label 1') ?>

Making the helper was surprisingly complex due to the magic in sfForm, so much so that I hope I went about this the wrong way. If there’s a better way please leave me some feedback!

Tags: ,

Leave a Reply