2
2
single: Form; Form type extension
3
3
4
4
How to Create a Form Type Extension
5
- ====================================
5
+ ===================================
6
6
7
7
:doc: `Custom form field types<create_custom_field_type> ` are great when
8
8
you need field types with a specific purpose, such as a gender selector,
@@ -12,7 +12,7 @@ But sometimes, you don't really need to add new field types - you want
12
12
to add features on top of existing types. This is where form type
13
13
extensions come in.
14
14
15
- Form type extensions have 2 main use cases:
15
+ Form type extensions have 2 main use- cases:
16
16
17
17
#. You want to add a **generic feature to several types ** (such as
18
18
adding a "help" text to every field type);
@@ -33,24 +33,23 @@ to a file. Your ``Media`` form uses a file type, but when editing the entity,
33
33
you would like to see its image automatically rendered next to the file
34
34
input.
35
35
36
- You could of course do this by customizing how this field is rendered in a template. But field
37
- type extensions allow you to do this in a nice DRY fashion.
36
+ You could of course do this by customizing how this field is rendered in a
37
+ template. But field type extensions allow you to do this in a nice DRY fashion.
38
38
39
39
Defining the Form Type Extension
40
- ---------------------------------
40
+ --------------------------------
41
41
42
42
Your first task will be to create the form type extension class. Let's
43
- call it ``ImageTypeExtension ``. You will store the class in a file called
44
- `` ImageTypeExtension.php ``, in the ``<BundleName>\ Form\Type `` directory.
43
+ call it ``ImageTypeExtension ``. By standard, form extensions usually live
44
+ in the ``Form\Extension `` directory of one of your bundles .
45
45
46
46
When creating a form type extension, you can either implement the
47
- :class: `Symfony\\ Component\\ Form\\ FormTypeExtensionInterface ` interface,
47
+ :class: `Symfony\\ Component\\ Form\\ FormTypeExtensionInterface ` interface
48
48
or extend the :class: `Symfony\\ Component\\ Form\\ AbstractTypeExtension `
49
- class. Most of the time, you will end up extending the abstract class.
50
- That's what you will do in this tutorial::
49
+ class. In most cases, it's easier to extend the abstract class::
51
50
52
- // src/Acme/DemoBundle/Form/Type /ImageTypeExtension.php
53
- namespace Acme\DemoBundle\Form\Type ;
51
+ // src/Acme/DemoBundle/Form/Extension /ImageTypeExtension.php
52
+ namespace Acme\DemoBundle\Form\Extension ;
54
53
55
54
use Symfony\Component\Form\AbstractTypeExtension;
56
55
@@ -65,7 +64,6 @@ That's what you will do in this tutorial::
65
64
{
66
65
return 'file';
67
66
}
68
-
69
67
}
70
68
71
69
The only method you **must ** implement is the ``getExtendedType `` function.
@@ -128,37 +126,28 @@ The ``alias`` key of the tag is the type of field that this extension should
128
126
be applied to. In your case, as you want to extend the ``file `` field type,
129
127
you will use ``file `` as an alias.
130
128
131
- Adding the extension business logic
129
+ Adding the extension Business Logic
132
130
-----------------------------------
133
131
134
- The goal of your extension is to display a nice image next to file inputs
132
+ The goal of your extension is to display nice images next to file inputs
135
133
(when the underlying model contains images). For that purpose, let's assume
136
134
that you use an approach similar to the one described in
137
135
:doc: `How to handle File Uploads with Doctrine</cookbook/doctrine/file_uploads> `:
138
136
you have a Media model with a file property (corresponding to the file field
139
137
in the form) and a path property (corresponding to the image path in the
140
- database).
141
-
142
- .. code-block :: php
138
+ database)::
143
139
144
140
// src/Acme/DemoBundle/Entity/Media.php
145
141
namespace Acme\DemoBundle\Entity;
146
142
147
- use Doctrine\ORM\Mapping as ORM;
148
143
use Symfony\Component\Validator\Constraints as Assert;
149
144
150
- /**
151
- * @ORM\Entity
152
- * @ORM\Table
153
- */
154
145
class Media
155
146
{
156
147
// ...
157
148
158
149
/**
159
- * @var string
160
- *
161
- * @ORM\Column(name="path", type="string", length=255)
150
+ * @var string The path - typically stored in the database
162
151
*/
163
152
private $path;
164
153
@@ -182,7 +171,8 @@ database).
182
171
return $webPath;
183
172
}
184
173
185
- Your form type extension class will need to do two things:
174
+ Your form type extension class will need to do two things in order to extend
175
+ the ``file `` form type:
186
176
187
177
#. Override the ``getDefaultOptions `` method in order to add an image_path
188
178
option;
@@ -192,12 +182,10 @@ Your form type extension class will need to do two things:
192
182
The logic is the following: when adding a form field of type ``file ``,
193
183
you will be able to specify a new option: ``image_path ``. This option will
194
184
tell the file field how to get the actual image url in order to display
195
- it in the view.
185
+ it in the view::
196
186
197
- .. code-block :: php
198
-
199
- // src/Acme/DemoBundle/Form/Type/ImageTypeExtension.php
200
- namespace Acme\DemoBundle\Form\Type;
187
+ // src/Acme/DemoBundle/Form/Extension/ImageTypeExtension.php
188
+ namespace Acme\DemoBundle\Form\Extension;
201
189
202
190
use Symfony\Component\Form\AbstractTypeExtension;
203
191
use Symfony\Component\Form\FormBuilder;
@@ -253,22 +241,23 @@ it in the view.
253
241
254
242
$propertyPath = new PropertyPath($form->getAttribute('image_path'));
255
243
$imageUrl = $propertyPath->getValue($parentData);
244
+ // set an "image_url" variable that will be available when rendering this field
256
245
$view->set('image_url', $imageUrl);
257
246
}
258
247
}
259
248
260
249
}
261
250
262
- Override the file widget template fragment
251
+ Override the File Widget Template Fragment
263
252
------------------------------------------
264
253
265
254
Each field type is rendered by a template fragment. Those template fragments
266
- can be overridden in order to customize form rendering; for more information,
255
+ can be overridden in order to customize form rendering. For more information,
267
256
you can refer to the :ref: `cookbook-form-customization-form-themes ` article.
268
257
269
258
In your extension class, you have added a new variable (``image_url ``), but
270
259
you still need to take advantage of this new variable in your templates.
271
- You need to override the ``file_widget `` block:
260
+ Specifically, you need to override the ``file_widget `` block:
272
261
273
262
.. configuration-block ::
274
263
@@ -298,7 +287,7 @@ You need to override the ``file_widget`` block:
298
287
299
288
.. note ::
300
289
301
- You will need to change your config file or to explicitly specify how
290
+ You will need to change your config file or explicitly specify how
302
291
you want your form to be themed in order for Symfony to use your overridden
303
292
block. See :ref: `cookbook-form-customization-form-themes ` for more
304
293
information.
@@ -308,10 +297,10 @@ Using the Form Type Extension
308
297
309
298
From now on, when adding a field of type ``file `` in your form, you can
310
299
specify an ``image_path `` option that will be used to display an image
311
- next to the file field. As an example::
300
+ next to the file field. For example::
312
301
313
302
// src/Acme/DemoBundle/Form/Type/MediaType.php
314
- namespace Acme\DemoBundle\Form;
303
+ namespace Acme\DemoBundle\Form\Type ;
315
304
316
305
use Symfony\Component\Form\AbstractType;
317
306
use Symfony\Component\Form\FormBuilder;
0 commit comments