I think you're headed in the right direction, and I would like to add my
voice that I would prefer RC1 be delayed so that something like this can
make it in. Maybe a beta release next week?

I will attempt to put aside some of my time this weekend to go over it and
see if I cant assist to help stuff get done.


T


On Fri, Feb 25, 2011 at 11:13, Bernhard Schussek <[email protected]>wrote:

> Hi dear Symfony2 devs,
>
> I was pushed by several people to refactor the Form component to be
> more decoupled and make better use of DI. Although I wasn't really
> convinced of this approach at first, I decided to give it a try - and
> am pretty satisfied with the results. Most of the features have been
> refactored, but there are still details that need to be worked on. You
> can find the current progress here:
>
> https://github.com/bschussek/symfony/tree/experimental
>
> Important: This is experimental. It is not decided whether this will
> ever be merged into master. I also don't recommend to use this in any
> application yet as CSRF protection is not ported yet.
>
> Thanks to Bulat for helping me.
>
> This post will outline the problems this refactoring tries to fix and
> the benefits that we gain. Also, we need to find out how to deal with
> the RC that is planned for next week.
>
> Fixed problems
> ----------------------
> * The option implementation of Fields/Forms was buggy
> * Forms could not be put into the DIC and retrieved from there
> * Stubbing/mocking of Forms in controllers was impossible, because
> they were created with "new"
> * Dependencies where hidden inside configure() and could not be replaced
> * Dependencies required in a field had to manually be added as options
> of all parent forms (e.g. EntityManager)
> * Field/Form by design contained lots of code that was relevant for
> rendering only (getId(), getName(), getPattern() etc.)
> * Because of the monolithic inheritance structure, it wasn't possible
> to create fields that inherit the rendering of for example TextField
> but the behaviour of another field
> * Rendering was unflexible. It wasn't possible to override for example
> the "row" template for a specific field type (needed for
> RepeatedField, inline forms etc.)
>
> Additional advantages
> --------------------------------
> * Fields and their renderers are now completely separated
> * Rendering is more concise and flexible
> * All fields of a specific type (e.g. text fields) used in an
> application can be overridden/extended
>
> (probably more that I forgot right now)
>
> I want to explain how form creation and form rendering work with the
> changed approach. Note that not all of the stuff I'm explaining here
> is complete yet.
>
> Form handling
> ---------------------
> To create a form, you implement a form factory in your bundle. This
> factory could look like this:
>
> https://gist.github.com/842827
>
> Binding will look like this:
>
> https://gist.github.com/843094
>
> And rendering something like this:
>
> https://gist.github.com/843115
>
> Rendering improvements
> ------------------------------------
> The most interesting part I believe is the rendering. As you can see,
> we passed $form->getRenderer() to the template. This renderer encloses
> variables and methods that are available there. Example variables are
> "id", "name", "value", "class" etc. The methods are "errors",
> "widget", "label", "row" and "rest".
>
> Each field and form has exactly one renderer. Depending on the field
> type, this renderer has additional variables set that can be used in
> the template. The renderer of a money field, for example, offers the
> additional variable "money_pattern". The renderer of a form offers
> "fields", "visible_fields" etc. All these variables can either be
> statically set on the renderer by calling setVar(), or dynamically
> using renderer plugins. They can also be overridden when calling
> individual methods of the renderer, like "widget".
>
> In form themes, these variables are available as global variables in
> the blocks of the field:
>
> {% block money_field %}
>    {{ money_pattern }}
> {% endblock %}
>
> In normal templates, you can access the variables as properties of the
> field renderer:
>
> {# Assuming the field "price" is a money field #}
> {{ form.price.money_pattern }}
>
> As said above, each renderer also offers rendering methods. With
>
> {{ field.widget }}
>
> for example, you can output the widget of a field. You can also
> override any of the variables in the call.
>
> {{ field.wigdet({ 'money_pattern': '...' }) }}
>
> Unlike before, there is no difference between HTML attributes and
> template variables anymore. Each HTML attribute that should be
> settable must be available as variable, for example:
>
> {{ field.wigdet({ 'class': 'myclass' }) }}
>
> {% block money_field %}
> <div class="{{ class }}"> etc.
>
> Because renderers are simple PHP objects, you can extend them and add
> functionality. You could implement this renderer
>
> https://gist.github.com/843139
>
> and create a new form theme with a "help" block. You can then call
>
> {{ field.help('My help text') }}
>
> on all fields that have your custom renderer set. It is also possible
> to override the renderers of all core fields to add functionality
> globally.
>
> An interesting default rendering method is "rest" (not implemented
> yet, if you have better names tell me). Because each field has a
> stateful renderer, we can track which field was rendered at least
> once. With
>
> {{ form.rest }}
>
> you can render all fields that weren't explicitely rendered. This
> replaces the "hidden" helper and solves lots of other problems. If
> you, for example, forgot to render the hidden fields in a subform,
> these will be rendered here. If you added a field in the PHP code, but
> not in your template, it will be rendered here. The designer will
> notice the problem and manually render the field correctly.
>
> What about PHP rendering?
> ----------------------------------------
> So far I've only talked about Twig. All renderers are connected to a
> theme (an instance of ThemeInterface). By default, the component ships
> with TwigTheme. By exchanging this object, you can either change the
> template(s) used as themes or the whole theming engine. You could
> implement a SmartyTheme that renders form fields using Smarty. Note
> that the theming engine of the form and the templating engine where
> you render the form are independent!
>
> For example, currently there is only a TwigTheme, but you can render
> it in PHP template nevertheless. Just pass the form renderer to the
> template and use it like in Twig:
>
> <?php echo $form->getWidget() ?>
> <?php foreach ($form['visible_fields'] as $field): ?>
> etc.
>
> I will cut this post for now. See my implementation if you want to learn
> more.
>
> Conclusion
> ----------------
> Because of DI, lots of problems in the form architecture could be
> fixed and the rendering could be significantly improved. The reason
> for this is that Twig and other dependencies can now be injected.
>
> Of course, there are problems too: The biggest one is that RC1 is
> planned for next week. Most of the existing unit tests are green
> again, but there are still lots of smaller things that need to be
> fixed/worked on, and this won't be done next week.
>
> I am very confident though that this refactoring can be finished very
> soon. Most of the existing features have been ported, for the
> remaining ones (FieldFactoryGuesser, CSRF protection and
> CollectionField) I don't see any showstoppers - it just needs to be
> done.
>
> What I need:
> ------------------
> * to know whether you want to see this in the first Symfony2 release.
> Delivering it in later releases will be difficult because this is a
> major BC break
> * input. I have considered a lot of feedback in this refactoring that
> I have got lately, but more input is always better.
> * help. If you have time to help, you are very welcome.
>
>
> Best wishes,
> Bernhard
>
> --
> Software Architect & Engineer
> Blog: http://webmozarts.com
> Twitter: http://twitter.com/webmozart
>
> --
> If you want to report a vulnerability issue on symfony, please send it to
> security at symfony-project.com
>
> You received this message because you are subscribed to the Google
> Groups "symfony developers" group.
> To post to this group, send email to [email protected]
> To unsubscribe from this group, send email to
> [email protected]
> For more options, visit this group at
> http://groups.google.com/group/symfony-devs?hl=en
>

-- 
If you want to report a vulnerability issue on symfony, please send it to 
security at symfony-project.com

You received this message because you are subscribed to the Google
Groups "symfony developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/symfony-devs?hl=en

Reply via email to