From cfaf3383ad388145f1bca094fae027f11ee8f3a0 Mon Sep 17 00:00:00 2001 From: Talita Kocjan Zager Date: Sat, 12 Mar 2016 14:49:48 +0100 Subject: [PATCH] routing ch review, part 3 --- book/routing.rst | 238 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 169 insertions(+), 69 deletions(-) diff --git a/book/routing.rst b/book/routing.rst index aa08421c458..0508374fa39 100644 --- a/book/routing.rst +++ b/book/routing.rst @@ -1053,94 +1053,163 @@ a slash. URLs matching this route might look like: Special Routing Parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~ -As you've seen, each routing parameter or default value is eventually available -as an argument in the controller method. Additionally, there are three parameters -that are special: each adds a unique piece of functionality inside your application: +In the examples until now we have seen, beside regular placeholders like +``{slug}``, also three special ones: ``_controller``, ``_format``, and +``_locale``. Each of this special routing parameters adds a unique piece +of functionality inside application: ``_controller`` - As you've seen, this parameter is used to determine which controller is - executed when the route is matched. + Used to determine which controller is executed when the route is + matched. ``_format`` - Used to set the request format (:ref:`read more `). + Used to set the request format + (:ref:`read more `). ``_locale`` - Used to set the locale on the request (:ref:`read more `). + Used to set the locale on the request + (:ref:`read more `). -.. index:: - single: Routing; Controllers - single: Controller; String naming format +There is also a fourth special routing parameter: -.. _controller-string-syntax: +``_route`` + It holds the name of the route that was matched. -Controller Naming Pattern -------------------------- + In the following example, the ``_route`` would be ``homepage``:: -Every route must have a ``_controller`` parameter, which dictates which -controller should be executed when that route is matched. This parameter -uses a simple string pattern called the *logical controller name*, which -Symfony maps to a specific PHP method and class. The pattern has three parts, -each separated by a colon: + .. configuration-block:: - **bundle**:**controller**:**action** + .. code-block:: php-annotations -For example, a ``_controller`` value of ``AppBundle:Blog:show`` means: + // src/AppBundle/Controller/MainController.php -========= ================== ============== -Bundle Controller Class Method Name -========= ================== ============== -AppBundle ``BlogController`` ``showAction`` -========= ================== ============== + // ... + class MainController extends Controller + { + /** + * @Route("/", name="homepage") + */ + public function homepageAction() + { + // ... + } + } + + .. code-block:: yaml -The controller might look like this:: + # app/config/routing.yml + homepage: + path: / + defaults: { _controller: AppBundle:Main:homepage } - // src/AppBundle/Controller/BlogController.php - namespace AppBundle\Controller; +Special Routing Parameters and Controller Arguments +--------------------------------------------------- - use Symfony\Bundle\FrameworkBundle\Controller\Controller; +To review: When executing controller method, Symfony matches each method +argument with a placeholder from the route. So the value for ``{slug}`` +placeholder is passed to ``$slug`` method argument and therefore available +for use in the controller. We just have to make sure that the name of the +placeholder is the same as the name of the argument variable. - class BlogController extends Controller - { - public function showAction($slug) +What we haven't mentioned yet is that in reality, **the entire ``defaults`` +collection is merged with the parameter values to form a single array.** +Each key of that resulting array is available as an argument on the +controller and therefore available inside the controller + +What does this mean? + +* Each routing placeholder, regular, like ``{slug}``, or special one, like + ``_locale`` is eventually available as an argument on the controller; + +* Since the placeholders and ``defaults`` collection are merged together, + even the ``$_controller`` variable is available and :doc:`every default + value for extra parameters ` that we + specify in the ``defaults`` collection but not as route parameters. + +What does this mean for the the advanced example above? Let's look at it again:: + +.. configuration-block:: + + .. code-block:: php-annotations + + // src/AppBundle/Controller/ArticleController.php + + // ... + class ArticleController extends Controller { - // ... + /** + * @Route( + * "/articles/{_locale}/{year}/{title}.{_format}", + * name="article_show", + * defaults={"_format": "html"}, + * requirements={ + * "_locale": "en|fr", + * "_format": "html|rss", + * "year": "\d+" + * } + * ) + */ + public function showAction($_locale, $year, $title) + { + // ... + } } - } -Notice that Symfony adds the string ``Controller`` to the class name (``Blog`` -=> ``BlogController``) and ``Action`` to the method name (``show`` => ``showAction``). + .. code-block:: yaml -You could also refer to this controller using its fully-qualified class name -and method: ``AppBundle\Controller\BlogController::showAction``. But if you -follow some simple conventions, the logical name is more concise and allows -more flexibility. + # app/config/routing.yml + article_show: + path: /articles/{_locale}/{year}/{title}.{_format} + defaults: { _controller: AppBundle:Article:show, _format: html } + requirements: + _locale: en|fr + _format: html|rss + year: \d+ -.. note:: + .. code-block:: xml - In addition to using the logical name or the fully-qualified class name, - Symfony supports a third way of referring to a controller. This method - uses just one colon separator (e.g. ``service_name:indexAction``) and - refers to the controller as a service (see :doc:`/cookbook/controller/service`). + + + -Route Parameters and Controller Arguments ------------------------------------------ + -The route parameters (e.g. ``{slug}``) are especially important because -each is made available as an argument to the controller method:: + AppBundle:Article:show + html + en|fr + html|rss + \d+ - public function showAction($slug) - { - // ... - } + + -In reality, the entire ``defaults`` collection is merged with the parameter -values to form a single array. Each key of that array is available as an -argument on the controller. + .. code-block:: php -In other words, for each argument of your controller method, Symfony looks -for a route parameter of that name and assigns its value to that argument. -In the advanced example above, any combination (in any order) of the following -variables could be used as arguments to the ``showAction()`` method: + // app/config/routing.php + use Symfony\Component\Routing\RouteCollection; + use Symfony\Component\Routing\Route; + + $collection = new RouteCollection(); + $collection->add( + 'article_show', + new Route('/articles/{_locale}/{year}/{title}.{_format}', array( + '_controller' => 'AppBundle:Article:show', + '_format' => 'html', + ), array( + '_locale' => 'en|fr', + '_format' => 'html|rss', + 'year' => '\d+', + )) + ); + + return $collection; + +Any combination (in any order) of the following variables could be used +as arguments to the ``showAction()`` method: * ``$_locale`` * ``$year`` @@ -1149,18 +1218,49 @@ variables could be used as arguments to the ``showAction()`` method: * ``$_controller`` * ``$_route`` -Since the placeholders and ``defaults`` collection are merged together, even -the ``$_controller`` variable is available. For a more detailed discussion, -see :ref:`route-parameters-controller-arguments`. +.. index:: + single: Routing; Controllers + single: Controller; String naming format + +.. _controller-string-syntax: -.. tip:: +Controller Naming Pattern +------------------------- - The special ``$_route`` variable is set to the name of the route that was - matched. +There are three ways to refer to a controller method: + +* Logical controller name; + +* Fully-qualified class name and method; + +* A special single colon (:) notation, for example ``service_name:indexAction``, + used to refer to a controller that's defined as a service which is + explained here: (see :doc:`/cookbook/controller/service`). + +Using YAML every route must have a ``_controller`` parameter, which +dictates which controller should be executed when that route is matched. +This parameter uses a simple string pattern called the **logical +controller name**, which Symfony maps to a specific controller and +controller class. The pattern has three parts, each separated by a colon: + + **bundle**:**controller**:**action** + +For example, a ``_controller`` value of ``AppBundle:Blog:show`` means: + +========= ================== ============== +Bundle Controller Class Method Name +========= ================== ============== +AppBundle ``BlogController`` ``showAction`` +========= ================== ============== + +Notice that Symfony adds the string ``Controller`` to the class name: ``Blog`` +=> ``BlogController``, and ``Action`` to the method name: ``show`` => +``showAction``. -You can even add extra information to your route definition and access it -within your controller. For more information on this topic, -see :doc:`/cookbook/routing/extra_information`. +You could also refer to this controller using its **fully-qualified +class name and method**: ``AppBundle\Controller\BlogController::showAction``. +But if you follow some simple conventions, the logical name is more +concise and allows more flexibility. .. index:: single: Routing; Importing routing resources