Skip to content

Commit f49e5e0

Browse files
Added cookbook on using _method in hidden form fields
1 parent 7aa023d commit f49e5e0

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

cookbook/routing/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ Routing
77
scheme
88
slash_in_parameter
99
redirect_in_config
10+
method_parameters
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
.. index::
2+
single: Routing; _method
3+
4+
Using HTTP Methods beyond GET and POST in Routes
5+
================================================
6+
7+
When you are defining routes one of the restrictions you can put on whether
8+
a request matches the route is the HTTP method of the request. This is introduced
9+
in the routing chapter of the book ":doc:`/book/routing`" with examples using
10+
GET and POST. You can also use other HTTP verbs in this way. For example, if
11+
you have a blog post entry then you could use the same url pattern to show
12+
it, make changes to it and delete it by matching on GET, PUT and DELETE.
13+
14+
.. configuration-block::
15+
16+
.. code-block:: yaml
17+
18+
blog_show:
19+
pattern: /blog/{slug}
20+
defaults: { _controller: AcmeDemoBundle:Blog:show }
21+
requirements:
22+
_method: GET
23+
24+
blog_update:
25+
pattern: /blog/{slug}
26+
defaults: { _controller: AcmeDemoBundle:Blog:update }
27+
requirements:
28+
_method: PUT
29+
30+
blog_delete:
31+
pattern: /blog/{slug}
32+
defaults: { _controller: AcmeDemoBundle:Blog:delete }
33+
requirements:
34+
_method: DELETE
35+
36+
.. code-block:: xml
37+
38+
<?xml version="1.0" encoding="UTF-8" ?>
39+
40+
<routes xmlns="http://symfony.com/schema/routing"
41+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
42+
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
43+
44+
<route id="blog_show" pattern="/blog/{slug}">
45+
<default key="_controller">AcmeDemoBundle:Blog:show</default>
46+
<requirement key="_method">GET</requirement>
47+
</route>
48+
49+
<route id="blog_update" pattern="/blog/{slug}">
50+
<default key="_controller">AcmeDemoBundle:Blog:update</default>
51+
<requirement key="_method">PUT</requirement>
52+
</route>
53+
54+
<route id="blog_delete" pattern="/blog/{slug}">
55+
<default key="_controller">AcmeDemoBundle:Blog:delete</default>
56+
<requirement key="_method">DELETE</requirement>
57+
</route>
58+
</routes>
59+
60+
.. code-block:: php
61+
62+
use Symfony\Component\Routing\RouteCollection;
63+
use Symfony\Component\Routing\Route;
64+
65+
$collection = new RouteCollection();
66+
$collection->add('blog_show', new Route('/blog/{slug}', array(
67+
'_controller' => 'AcmeDemoBundle:Blog:show',
68+
), array(
69+
'_method' => 'GET',
70+
)));
71+
72+
$collection->add('blog_update', new Route('/blog/{slug}', array(
73+
'_controller' => 'AcmeDemoBundle:Blog:update',
74+
), array(
75+
'_method' => 'PUT',
76+
)));
77+
78+
$collection->add('blog_delete', new Route('/blog/{slug}', array(
79+
'_controller' => 'AcmeDemoBundle:Blog:delete',
80+
), array(
81+
'_method' => 'DELETE',
82+
)));
83+
84+
return $collection;
85+
86+
Unfortunately it is not as simple as that is you are creating a website
87+
because most browsers do not support sending PUT and DELETE requests. Fortunately
88+
Symfony2 provides you with a simple way of working around this limitation.
89+
By including the ``_method`` parameter in the query string or parameters of an
90+
HTTP request Symfony2 will use this as the method when matching routes. This
91+
can be done easily in forms with a hidden field. So we could have a forms for
92+
editing and blog posts that looks like this:
93+
94+
.. code-block:: html+jinja
95+
96+
<form action="{{ path('blog_update', { 'slug': blog.slug }) }}" method="post">
97+
<input type="hidden" name="_method" value="PUT"/>
98+
{{ form_widget(form) }}
99+
<button type="submit">Updare</button>
100+
</form>
101+
102+
The submitted request will now match the ``blog_update`` route and the ``updateAction``
103+
will be used to process the form.
104+
105+
Likewise the delete form could be changed to look like this:
106+
107+
.. code-block:: html+jinja
108+
109+
<form action="{{ path('blog_delete', { 'slug': blog.slug }) }}" method="post">
110+
<input type="hidden" name="_method" value="DELETE"/>
111+
{{ form_widget(delete_form) }}
112+
<button type="submit">Delete</button>
113+
</form>
114+
115+
It will then match the ``blog_delete`` route.

0 commit comments

Comments
 (0)