From 3d2b6a36983bc345f5fae7f99da952e11bfd0262 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Wed, 8 Jun 2011 13:33:26 +0200 Subject: [PATCH 1/2] [Form] Twig themes have been moved to the Twig bridge --- book/forms.rst | 93 ++++++++++++----------- cookbook/form/twig_form_customization.rst | 70 ++++++++--------- 2 files changed, 82 insertions(+), 81 deletions(-) diff --git a/book/forms.rst b/book/forms.rst index 4fabe7310d6..b2f49937b67 100644 --- a/book/forms.rst +++ b/book/forms.rst @@ -30,13 +30,13 @@ going to need to build a form. But before you begin, let's focus on the generic // src/Acme/StoreBundle/Entity/Product.php namespace Acme\StoreBundle\Entity; - + class Product { public $name; - + protected $price; - + public function getPrice() { return $this->price; @@ -53,9 +53,9 @@ going to need to build a form. But before you begin, let's focus on the generic If you're coding along with this example, be sure to create and enable the ``AcmeStoreBundle``. Run the following command and follow the on-screen directions: - + .. code-block:: text - + php app/console init:bundle Acme/StoreBundle src/ This type of class is commonly called a "plain-old-PHP-object" because, so far, @@ -134,17 +134,17 @@ helper functions: .. code-block:: html+jinja {# src/Acme/StoreBundle/Resources/views/Default/index.html.twig #} - +
{{ form_widget(form) }} - +
.. code-block:: html+php - + - +
enctype($form) ?> > widget($form) ?> @@ -187,7 +187,7 @@ controller: { // just setup a fresh $product object (no dummy data) $product = new Product(); - + $form = $this->createFormBuilder($product) ->add('name', 'text') ->add('price', 'money', array('currency' => 'USD')) @@ -203,7 +203,7 @@ controller: return $this->redirect($this->generateUrl('store_product_success')); } } - + // ... } @@ -221,7 +221,7 @@ of the ``$product`` object. This all happens via the ``bindRequest()`` method. $product = new Product(); $product->name = 'Test product'; - + $form->bindRequest($this->get('request')); echo $product->name; @@ -328,7 +328,7 @@ number: public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addPropertyConstraint('name', new NotBlank()); - + $metadata->addPropertyConstraint('price', new NotBlank()); $metadata->addPropertyConstraint('price', new Min(0)); } @@ -423,10 +423,10 @@ guess (``text``). The ``createFormBuilder()`` method takes up to two arguments neither of which are required): - + * The default data to initialize the form fields. This argument can be an associative array or a plain old PHP object like in this example; - + * an array of options for the form. This example is pretty trivial, but field guessing can be a major time saver. @@ -449,7 +449,7 @@ of code. Of course, you'll usually need much more flexibility when rendering: .. code-block:: html+jinja {# src/Acme/StoreBundle/Resources/views/Default/index.html.twig #} - + {{ form_errors(form) }} @@ -462,9 +462,9 @@ of code. Of course, you'll usually need much more flexibility when rendering:
.. code-block:: html+php - + - +
enctype($form) ?>> errors($form) ?> @@ -631,30 +631,30 @@ It can be used to quickly build a form object in the controller: { $product = // ... $form = $this->createForm(new ProductType(), $product); - + // ... } .. note:: You can also set the data on the form via the ``setData()`` method: - + .. code-block:: php - + $form = $this->createForm(new ProductType()); $form->setData($product); If you use the ``setData`` method - and want to take advantage of field type guessing, be sure to add the following to your form class: - + .. code-block:: php - + public function getDefaultOptions(array $options) { return array( 'data_class' => 'Acme\StoreBundle\Entity\Product', ); } - + This is necessary because the object is passed to the form after field type guessing. @@ -859,7 +859,7 @@ the following inside ``ProductType``: // ... $builder->add('reviews', 'collection', array( - 'type' => new ProductReviewType(), + 'type' => new ProductReviewType(), )); } @@ -885,10 +885,10 @@ do this, create a new template file that will store the new markup: .. configuration-block:: .. code-block:: html+jinja - + {# src/Acme/StoreBundle/Resources/views/Form/fields.html.twig #} - {% extends 'TwigBundle:Form:div_layout.html.twig' %} - + {% extends 'div_layout.html.twig' %} + {% block field_row %} {% spaceless %}
@@ -919,7 +919,7 @@ the form: {# src/Acme/StoreBundle/Resources/views/Default/index.html.twig #} {% form_theme form 'AcmeStoreBundle:Form:fields.html.twig' %} - + The ``form_theme`` tag "imports" the template and uses all of its form-related @@ -942,7 +942,7 @@ Form Template Blocks Every part of a form that is rendered - HTML form elements, errors, labels, etc - is defined in a base template as individual Twig blocks. By default, every block needed is defined in the `div_layout.html.twig`_ file that lives inside -the core ``TwigBundle``. Inside this file, you can see every block needed +the `Twig Bridge`_. Inside this file, you can see every block needed to render a form and every default field type. Each block follows the same basic pattern and is broken up into two pieces, @@ -978,14 +978,14 @@ a form that can be rendered: By knowing the field type (e.g. ``textarea``) and which part you want to customize (e.g. ``widget``), you can construct the block name that needs to be overridden (e.g. ``textarea_widget``). The best way to customize the -block is to copy it from ``div_layout.html.twig`` to a new template, customize +block is to copy it from `div_layout.html.twig`_ to a new template, customize it, and then use the ``form_theme`` tag as shown in the earlier example. Form Type Block Inheritance ~~~~~~~~~~~~~~~~~~~~~~~~~~~ In some cases, the block you want to customize will appear to be missing. -For example, if you look in the ``div_layout.html.twig`` file, you'll find +For example, if you look in the `div_layout.html.twig`_ file, you'll find no ``textarea_errors`` block. So how are the errors for a textarea field rendered? @@ -1010,18 +1010,18 @@ templates in your application. To automatically include the customized blocks from the ``fields.html.twig`` template created earlier, modify your application configuration file: -.. configuration-block:: +.. configuration-block:: .. code-block:: yaml - + # app/config/config.yml twig: form: resources: ['AcmeStoreBundle:Form:fields.html.twig'] # ... - + .. code-block:: xml - + @@ -1039,20 +1039,20 @@ configuration file: )); Any blocks inside the ``fields.html.twig`` template are now used globally -to define form output. +to define form output. .. sidebar:: Customizing Form Output all in a Single File You can also customize a form block right inside the template where that customization is needed. Note that this method will only work if the template used extends some base template via the ``{% extends %}``: - + .. code-block:: html+jinja - + {% extends '::base.html.twig' %} - + {% form_theme form _self %} - {% use 'TwigBundle:Form:div_layout.html.twig' %} + {% use 'div_layout.html.twig' %} {% block field_row %} {# custom field row output #} @@ -1060,7 +1060,7 @@ to define form output. {% block content %} {# ... #} - + {{ form_row(form.name) }} {% endblock %} @@ -1068,11 +1068,11 @@ to define form output. directly inside the template that will use those customizations. Use this method to quickly make form output customizations that will only ever be needed in a single template. - + The ``use`` tag is also helpful as it gives you access to all of the - blocks defined inside ``div_layout.html.twig``. For example, this ``use`` + blocks defined inside `div_layout.html.twig`_. For example, this ``use`` statement is necessary to make the following form customization, as it - gives you access to the ``attributes`` block defined in ``div_layout.html.twig``: + gives you access to the ``attributes`` block defined in `div_layout.html.twig`_: .. code-block:: html+jinja @@ -1158,5 +1158,6 @@ Learn more from the Cookbook * :doc:`/cookbook/form/twig_form_customization` .. _`Symfony2 Form Component`: https://github.com/symfony/Form -.. _`div_layout.html.twig`: https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/TwigBundle/Resources/views/Form/div_layout.html.twig +.. _`Twig Bridge`: https://github.com/symfony/symfony/tree/master/src/Symfony/Bridge/Twig +.. _`div_layout.html.twig`: https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Twig/Resources/views/Form/div_layout.html.twig .. _`Cross-site request forgery`: http://en.wikipedia.org/wiki/Cross-site_request_forgery diff --git a/cookbook/form/twig_form_customization.rst b/cookbook/form/twig_form_customization.rst index a4e15b7f9f5..0965aab846b 100644 --- a/cookbook/form/twig_form_customization.rst +++ b/cookbook/form/twig_form_customization.rst @@ -66,10 +66,10 @@ For example, when the widget of a ``text`` type field is rendered, an ``input`` .. code-block:: html+jinja {{ form_widget(form.name) }} - + -Internally, Symfony uses the ``text_widget`` block from the ``div_layout.html.twig`` +Internally, Symfony uses the ``text_widget`` block from the `div_layout.html.twig`_ template to render the field. This is because the field type is ``text`` and you're rendering its ``widget`` (as opposed to its ``label`` or ``errors``). The default implementation of the ``text_widget`` block looks like this: @@ -82,7 +82,7 @@ The default implementation of the ``text_widget`` block looks like this: {% endblock text_widget %} As you can see, this block itself renders another block - ``field_widget`` -that lives in ``div_layout.html.twig``: +that lives in `div_layout.html.twig`_: .. code-block:: html+jinja @@ -91,7 +91,7 @@ that lives in ``div_layout.html.twig``: {% endblock field_widget %} -The point is, the blocks inside ``div_layout.html.twig`` dictate the HTML +The point is, the blocks inside `div_layout.html.twig`_ dictate the HTML output of each part of a form. To customize form output, you just need to identify and override the correct block. When any number of these form block customizations are put into a template, that template is known as a from "theme". @@ -104,12 +104,12 @@ When rendering a form, you can choose which form theme(s) you want to apply. In this example, the customized block name is ``text_widget`` because you want to override the HTML ``widget`` for all ``text`` field types. If you need to customize textarea fields, you would customize ``textarea_widget``. - + As you can see, the block name is a combination of the field type and which part of the field is being rendered (e.g. ``widget``, ``label``, ``errors``, ``row``). As such, to customize how errors are rendered for just input ``text`` fields, you should customize the ``text_errors`` block. - + More commonly, however, you'll want to customize how errors are displayed across *all* fields. You can do this by customizing the ``field_errors`` block. This takes advantage of field type inheritance. Specifically, @@ -156,7 +156,7 @@ directly in the template that's actually rendering the form. {% extends '::base.html.twig' %} {% form_theme form _self %} - {% use 'TwigBundle:Form:div_layout.html.twig' %} + {% use 'div_layout.html.twig' %} {% block text_widget %}
@@ -166,7 +166,7 @@ directly in the template that's actually rendering the form. {% block content %} {# render the form #} - + {{ form_row(form.name) }} {% endblock %} @@ -190,12 +190,12 @@ several (or all) forms in your application, read on to the next section. .. note:: Be sure also to include the ``use`` statement somewhere in your template when using this method: - + .. code-block:: jinja - - {% use 'TwigBundle:Form:div_layout.html.twig' %} - - This "imports" all of the blocks from the base ``div_layout.html.twig`` + + {% use 'div_layout.html.twig' %} + + This "imports" all of the blocks from the base `div_layout.html.twig`_ template, which gives you access to the ``attributes`` block. In general, the ``use`` tag is helpful when your template *already* extends a base template, but you still need to import blocks from a second template. @@ -213,7 +213,7 @@ can now re-use the form customization across many templates: .. code-block:: html+jinja {# src/Acme/DemoBundle/Resources/views/Form/fields.html.twig #} - {% extends 'TwigBundle:Form:div_layout.html.twig' %} + {% extends 'div_layout.html.twig' %} {% block text_widget %}
@@ -223,7 +223,7 @@ can now re-use the form customization across many templates: .. note:: - The template extends the base template (``TwigBundle:Form:div_layout.html.twig``) + The template extends the base template (`div_layout.html.twig`_) so that you have access to the ``field_widget`` block defined there. If you forget the ``extends`` tag, the HTML input element will be missing several HTML attributes (since the ``attributes`` block isn't defined). @@ -237,7 +237,7 @@ tell Symfony to use the template via the ``form_theme`` tag: .. code-block:: html+jinja {% form_theme form 'AcmeDemoBundle:Form:fields.html.twig' %} - + {{ form_widget(form.name) }} When the ``form.name`` widget is rendered, Symfony will use the ``text_widget`` @@ -250,7 +250,7 @@ Referencing Base Form Blocks ---------------------------- So far, to override a particular form block, the best method is to copy -the default block from ``div_layout.html.twig``, paste it into a different template, +the default block from `div_layout.html.twig`_, paste it into a different template, and the customize it. In many cases, you can avoid doing this by referencing the base block when customizing it. @@ -265,9 +265,9 @@ the form: .. code-block:: jinja - {% use 'TwigBundle:Form:div_layout.html.twig' with text_widget as base_text_widget %} + {% use 'div_layout.html.twig' with text_widget as base_text_widget %} -Now, when the blocks from ``div_layout.html.twig`` are imported, the ``text_widget`` +Now, when the blocks from `div_layout.html.twig`_ are imported, the ``text_widget`` block is called ``base_text_widget``. This means that when you redefine the ``text_widget`` block, you can reference the default markup via ``base_text_widget``: @@ -288,7 +288,7 @@ the base block by using the ``parent()`` Twig function: .. code-block:: html+jinja {# src/Acme/DemoBundle/Resources/views/Form/fields.html.twig #} - {% extends 'TwigBundle:Form:div_layout.html.twig' %} + {% extends 'div_layout.html.twig' %} {% block text_widget %}
@@ -305,18 +305,18 @@ If you'd like a certain form customization to be global to your application, you can accomplish this by making the form customizations to an external template and then importing it inside your application configuration: -.. configuration-block:: +.. configuration-block:: .. code-block:: yaml - + # app/config/config.yml twig: form: resources: ['AcmeDemoBundle:Form:fields.html.twig'] # ... - + .. code-block:: xml - + @@ -340,14 +340,14 @@ By default, twig uses a *div* layout when rendering forms. Some people, however, may prefer to render forms in a *table* layout. The technique to change to the table layout is the same as shown above, except you will need to change: -``AcmeDemoBundle:Form:fields.html.twig`` to ``TwigBundle:Form:table_layout.html.twig`` +``AcmeDemoBundle:Form:fields.html.twig`` to ``table_layout.html.twig`` If you only want to make the change in one template, do the following: .. code-block:: html+jinja - - {% form_theme form 'TwigBundle:Form:table_layout.html.twig' %} - + + {% form_theme form 'table_layout.html.twig' %} + Note that the ``form`` variable in the above code is the form view variable that you passed to your template. @@ -364,14 +364,14 @@ part of the field is being customized. For example: .. code-block:: html+jinja {% form_theme form _self %} - {% use 'TwigBundle:Form:div_layout.html.twig' %} + {% use 'div_layout.html.twig' %} {% block _product_name_widget %}
{% endblock %} - + {{ form_widget(form.name) }} Here, the ``_product_name_widget`` defines the template to use for the field @@ -388,7 +388,7 @@ You can also override the markup for an entire field row using the same method: .. code-block:: html+jinja {% form_theme form _self %} - {% use 'TwigBundle:Form:div_layout.html.twig' %} + {% use 'div_layout.html.twig' %} {% block _product_name_row %}
@@ -397,7 +397,7 @@ You can also override the markup for an entire field row using the same method: {{ form_widget(form) }}
{% endblock %} - + {{ form_row(form.name) }} Other Common Customizations @@ -503,7 +503,7 @@ form, modify the ``use`` tag and add the following: .. code-block:: html+jinja - {% use 'TwigBundle:Form:div_layout.html.twig' with field_label as base_field_label %} + {% use 'div_layout.html.twig' with field_label as base_field_label %} {% block field_label %} {{ block('base_field_label') }} @@ -539,7 +539,7 @@ form, modify the ``use`` tag and add the following: .. code-block:: html+jinja - {% use 'TwigBundle:Form:div_layout.html.twig' with field_widget as base_field_widget %} + {% use 'div_layout.html.twig' with field_widget as base_field_widget %} {% block field_widget %} {{ block('base_field_widget') }} @@ -571,5 +571,5 @@ To render a help message below a field, pass in a ``help`` variable: .. tip:: See :ref:`cookbook-form-twig-two-methods` for how to apply this customization. -.. _`div_layout.html.twig`: https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/TwigBundle/Resources/views/Form/div_layout.html.twig +.. _`div_layout.html.twig`: https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Twig/Resources/views/Form/div_layout.html.twig .. _`Horizontal Reuse`: http://www.twig-project.org/doc/templates.html#horizontal-reuse \ No newline at end of file From 06b48edab7a41187d8380f332154c38bee4834df Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Wed, 8 Jun 2011 13:36:51 +0200 Subject: [PATCH 2/2] [Form] Clarify the individual field customization section --- cookbook/form/twig_form_customization.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cookbook/form/twig_form_customization.rst b/cookbook/form/twig_form_customization.rst index 0965aab846b..1c391cd7413 100644 --- a/cookbook/form/twig_form_customization.rst +++ b/cookbook/form/twig_form_customization.rst @@ -358,8 +358,8 @@ So far, you've seen the different ways you can customize the widget output of all text field types. You can also customize individual fields. For example, suppose you have two ``text`` fields - ``first_name`` and ``last_name`` - but you only want to customize one of the fields. This can be accomplished by -customizing a block whose name is a combination of the field name and which -part of the field is being customized. For example: +customizing a block whose name is a combination of the field id attribute and +which part of the field is being customized. For example: .. code-block:: html+jinja