Good morning. As promised I'll try to explain the basic stuff about form rendering implemented in Symfony. Here it goes:
Note: if in a hurry go straight to section 3 :)
1. Rendering the Form
1.1 In a Twig template form is rendered as follows:
<form action="submit.php" method="post" {{ form_enctype(form) }}>
{{ form_widget(form) }}
<input type="submit" />
</form>
1.2 Equivalent for Smarty
<form action="submit.php" method="post" {$form|form_enctype}>
{$form|form_widget}
<input type="submit" />
</form>
2. How to customize Form Rendering
2.1 Form Themes
"Symfony uses form fragments - a small piece of a template that renders just one part of a form - to render every part of a form - - field labels, errors, input text fields, select tags, etc. The fragments are defined as blocks in Twig and as template files in PHP." Smarty also uses blocks as Twig does.
The idea behind this is to have several blocks that are responsible for rendering a specific element like a text input or a checkbox and have "bigger" blocks that include other more specific blocks.
So, a {block "form_widget"} includes a {block "field_rows"}. Inside {block "field_rows"} a foreach is executed to include {block "field_row"}.
A "field_row" block looks like this:
{block "field_row"}
<div>
{$form|form_label}
{$form|form_errors}
{$form|form_widget}
</div>
{/block}
and "field_label" is (edited for simplicity):
{block "field_label"}
<label>{$label}</label>
{/block}
The user is then able to extend the form_div_layout.htm.tpl file and override/customize each block.
3. Implementation
3.1 Twig way
In Twig the form rendering function follows this logic:
1. The function first looks for a block named "_<view id>_<section>".
2. if such a block is not found the function will look for a block named "<type name>_<section>".
3. the type name is recursively replaced by the parent type name until a corresponding block is found.
Before the rendering Twig calls a $template->getBlocks() method to gather all blocks in the template. Then a $template->displayBlock() is executed with variables pulled from the $form instance. I guess this is how it populates each block variables.
3.2 Smarty way
I see that Smarty has a getTags() method but it just return tags names not a data structure. So I guess bottom the problem/challenge here is to gather all blocks (to the parent) and set variables inside them. Is this feasible? What would you suggest?
4. Documentation resources
Sorry for the really long email.
Regards,
Vítor.