From 46d10a2341069da2a6db2a10d7fa18e2363be0a6 Mon Sep 17 00:00:00 2001 From: Alexander Schwenn Date: Wed, 7 Jan 2015 22:43:03 +0100 Subject: [PATCH 1/4] [Cookbook][Routing] Update custom_route_loader.rst --- cookbook/routing/custom_route_loader.rst | 76 ++++++++++++++---------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/cookbook/routing/custom_route_loader.rst b/cookbook/routing/custom_route_loader.rst index a6e682ffe70..5e9b7f25b2e 100644 --- a/cookbook/routing/custom_route_loader.rst +++ b/cookbook/routing/custom_route_loader.rst @@ -14,13 +14,14 @@ slow down the installation process and make it error-prone. Alternatively, you could also use a custom route loader when you want your routes to be automatically generated or located based on some convention or pattern. One example is the `FOSRestBundle`_ where routing is generated based -off the names of the action methods in a controller. +on the names of the action methods in a controller. .. note:: There are many bundles out there that use their own route loaders to accomplish cases like those described above, for instance - `FOSRestBundle`_, `JMSI18nRoutingBundle`_, `KnpRadBundle`_ and `SonataAdminBundle`_. + `FOSRestBundle`_, `JMSI18nRoutingBundle`_, `KnpRadBundle`_ and + `SonataAdminBundle`_. Loading Routes -------------- @@ -35,20 +36,18 @@ and therefore have two important methods: :method:`Symfony\\Component\\Config\\Loader\\LoaderInterface::supports` and :method:`Symfony\\Component\\Config\\Loader\\LoaderInterface::load`. -Take these lines from the ``routing.yml`` in the AcmeDemoBundle of the Standard -Edition: +Take these lines from the ``routing.yml`` in the Symfony Standard Edition: .. code-block:: yaml - # src/Acme/DemoBundle/Resources/config/routing.yml - _demo: - resource: "@AcmeDemoBundle/Controller/DemoController.php" + # app/config/routing.yml + app: + resource: @AppBundle/Controller/ type: annotation - prefix: /demo -When the main loader parses this, it tries all the delegate loaders and calls +When the main loader parses this, it tries all registered delegate loaders and calls their :method:`Symfony\\Component\\Config\\Loader\\LoaderInterface::supports` -method with the given resource (``@AcmeDemoBundle/Controller/DemoController.php``) +method with the given resource (``@AppBundle/Controller/``) and type (``annotation``) as arguments. When one of the loader returns ``true``, its :method:`Symfony\\Component\\Config\\Loader\\LoaderInterface::load` method will be called, which should return a :class:`Symfony\\Component\\Routing\\RouteCollection` @@ -59,13 +58,13 @@ Creating a custom Loader To load routes from some custom source (i.e. from something other than annotations, YAML or XML files), you need to create a custom route loader. This loader -should implement :class:`Symfony\\Component\\Config\\Loader\\LoaderInterface`. +has to implement :class:`Symfony\\Component\\Config\\Loader\\LoaderInterface`. The sample loader below supports loading routing resources with a type of ``extra``. The type ``extra`` isn't important - you can just invent any resource type you want. The resource name itself is not actually used in the example:: - namespace Acme\DemoBundle\Routing; + namespace AppBundle\Routing; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\Loader\LoaderResolverInterface; @@ -87,14 +86,14 @@ type you want. The resource name itself is not actually used in the example:: // prepare a new route $path = '/extra/{parameter}'; $defaults = array( - '_controller' => 'AcmeDemoBundle:Demo:extra', + '_controller' => 'AppBundle:Extra:extra', ); $requirements = array( 'parameter' => '\d+', ); $route = new Route($path, $defaults, $requirements); - // add the new route to the route collection: + // add the new route to the route collection $routeName = 'extraRoute'; $routes->add($routeName, $route); @@ -120,9 +119,21 @@ type you want. The resource name itself is not actually used in the example:: } } -.. note:: +Make sure the controller you specify really exists. In this case you +have to create an ``extraAction`` method in the ``ExtraController`` +of the ``AppBundle``:: + + namespace AppBundle\Controller; - Make sure the controller you specify really exists. + use Symfony\Component\HttpFoundation\Response; + + class ExtraController extends Controller + { + public function extraAction($parameter) + { + return new Response($parameter); + } + } Now define a service for the ``ExtraLoader``: @@ -130,9 +141,10 @@ Now define a service for the ``ExtraLoader``: .. code-block:: yaml + # app/config/services.yml services: - acme_demo.routing_loader: - class: Acme\DemoBundle\Routing\ExtraLoader + app.routing_loader: + class: AppBundle\Routing\ExtraLoader tags: - { name: routing.loader } @@ -144,7 +156,7 @@ Now define a service for the ``ExtraLoader``: xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - + @@ -156,14 +168,15 @@ Now define a service for the ``ExtraLoader``: $container ->setDefinition( - 'acme_demo.routing_loader', - new Definition('Acme\DemoBundle\Routing\ExtraLoader') + 'app.routing_loader', + new Definition('AppBundle\Routing\ExtraLoader') ) ->addTag('routing.loader') ; -Notice the tag ``routing.loader``. All services with this tag will be marked -as potential route loaders and added as specialized routers to the +Notice the tag ``routing.loader``. All services with this *tag* will be marked +as potential route loaders and added as specialized route loaders to the +``routing.loader`` *service*, which is an instance of :class:`Symfony\\Bundle\\FrameworkBundle\\Routing\\DelegatingLoader`. Using the custom Loader @@ -177,7 +190,7 @@ Instead, you only need to add a few extra lines to the routing configuration: .. code-block:: yaml # app/config/routing.yml - AcmeDemoBundle_Extra: + app_extra: resource: . type: extra @@ -201,8 +214,8 @@ Instead, you only need to add a few extra lines to the routing configuration: return $collection; -The important part here is the ``type`` key. Its value should be "extra". -This is the type which the ``ExtraLoader`` supports and this will make sure +The important part here is the ``type`` key. Its value should be "extra" as +this is the type which the ``ExtraLoader`` supports and this will make sure its ``load()`` method gets called. The ``resource`` key is insignificant for the ``ExtraLoader``, so it is set to ".". @@ -218,8 +231,9 @@ More advanced Loaders In most cases it's better not to implement :class:`Symfony\\Component\\Config\\Loader\\LoaderInterface` yourself, but extend from :class:`Symfony\\Component\\Config\\Loader\\Loader`. -This class knows how to use a :class:`Symfony\\Component\\Config\\Loader\\LoaderResolver` -to load secondary routing resources. +This class knows how to use a +:class:`Symfony\\Component\\Config\\Loader\\LoaderResolver` to load secondary +routing resources. Of course you still need to implement :method:`Symfony\\Component\\Config\\Loader\\LoaderInterface::supports` @@ -228,7 +242,7 @@ Whenever you want to load another resource - for instance a YAML routing configuration file - you can call the :method:`Symfony\\Component\\Config\\Loader\\Loader::import` method:: - namespace Acme\DemoBundle\Routing; + namespace AppBundle\Routing; use Symfony\Component\Config\Loader\Loader; use Symfony\Component\Routing\RouteCollection; @@ -239,7 +253,7 @@ configuration file - you can call the { $collection = new RouteCollection(); - $resource = '@AcmeDemoBundle/Resources/config/import_routing.yml'; + $resource = '@AppBundle/Resources/config/import_routing.yml'; $type = 'yaml'; $importedRoutes = $this->import($resource, $type); @@ -251,7 +265,7 @@ configuration file - you can call the public function supports($resource, $type = null) { - return $type === 'advanced_extra'; + return 'advanced_extra' === $type; } } From bd6e3f31c7a4dda9efb5eb9f8664d382e94975d5 Mon Sep 17 00:00:00 2001 From: Alexander Schwenn Date: Sun, 29 Mar 2015 15:18:16 +0200 Subject: [PATCH 2/4] Rewrite first paragraph --- cookbook/routing/custom_route_loader.rst | 26 ++++++++++++++---------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/cookbook/routing/custom_route_loader.rst b/cookbook/routing/custom_route_loader.rst index 5e9b7f25b2e..d93bac0bd67 100644 --- a/cookbook/routing/custom_route_loader.rst +++ b/cookbook/routing/custom_route_loader.rst @@ -4,17 +4,21 @@ How to Create a custom Route Loader =================================== -A custom route loader allows you to add routes to an application without -including them, for example, in a YAML file. This comes in handy when -you have a bundle but don't want to manually add the routes for the bundle -to ``app/config/routing.yml``. This may be especially important when you want -to make the bundle reusable, or when you have open-sourced it as this would -slow down the installation process and make it error-prone. - -Alternatively, you could also use a custom route loader when you want your -routes to be automatically generated or located based on some convention or -pattern. One example is the `FOSRestBundle`_ where routing is generated based -on the names of the action methods in a controller. +What is a Custom Route Loader +----------------------------- + +A custom route loader enables you to generate routes based on some +conventions or patterns. A great example for this use-case is the +`FOSRestBundle`_ where routes are generated based on the names of the +action methods in a controller. + +A custom route loader does not enable your bundle to inject routes +without the need to modify the routing configuration +(e.g. ``app/config/routing.yml``) manually. +If your bundle provides routes, whether via a configuration file, like +the `WebProfilerBundle` does, or via a custom route loader, like the +`FOSRestBundle`_ does, an entry in the routing configuration is always +necessary. .. note:: From fe1a574db6ed904667dc164c88328aa870562b00 Mon Sep 17 00:00:00 2001 From: Alexander Schwenn Date: Sun, 29 Mar 2015 23:01:29 +0200 Subject: [PATCH 3/4] Change code example to extend from Loader class --- cookbook/routing/custom_route_loader.rst | 30 +++++++++--------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/cookbook/routing/custom_route_loader.rst b/cookbook/routing/custom_route_loader.rst index d93bac0bd67..bff77ee78cf 100644 --- a/cookbook/routing/custom_route_loader.rst +++ b/cookbook/routing/custom_route_loader.rst @@ -64,18 +64,21 @@ To load routes from some custom source (i.e. from something other than annotatio YAML or XML files), you need to create a custom route loader. This loader has to implement :class:`Symfony\\Component\\Config\\Loader\\LoaderInterface`. +In most cases it's better not to implement +:class:`Symfony\\Component\\Config\\Loader\\LoaderInterface` +yourself, but extend from :class:`Symfony\\Component\\Config\\Loader\\Loader`. + The sample loader below supports loading routing resources with a type of ``extra``. The type ``extra`` isn't important - you can just invent any resource type you want. The resource name itself is not actually used in the example:: namespace AppBundle\Routing; - use Symfony\Component\Config\Loader\LoaderInterface; - use Symfony\Component\Config\Loader\LoaderResolverInterface; + use Symfony\Component\Config\Loader\Loader; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; - class ExtraLoader implements LoaderInterface + class ExtraLoader extends Loader { private $loaded = false; @@ -110,17 +113,6 @@ type you want. The resource name itself is not actually used in the example:: { return 'extra' === $type; } - - public function getResolver() - { - // needed, but can be blank, unless you want to load other resources - // and if you do, using the Loader base class is easier (see below) - } - - public function setResolver(LoaderResolverInterface $resolver) - { - // same as above - } } Make sure the controller you specify really exists. In this case you @@ -130,6 +122,7 @@ of the ``AppBundle``:: namespace AppBundle\Controller; use Symfony\Component\HttpFoundation\Response; + use Symfony\Bundle\FrameworkBundle\Controller\Controller; class ExtraController extends Controller { @@ -232,11 +225,10 @@ for the ``ExtraLoader``, so it is set to ".". More advanced Loaders --------------------- -In most cases it's better not to implement -:class:`Symfony\\Component\\Config\\Loader\\LoaderInterface` -yourself, but extend from :class:`Symfony\\Component\\Config\\Loader\\Loader`. -This class knows how to use a -:class:`Symfony\\Component\\Config\\Loader\\LoaderResolver` to load secondary +If your custom route loader extends from +:class:`Symfony\\Component\\Config\\Loader\\Loader` as shown above, you +can also make use of the provided resolver, an instance of +:class:`Symfony\\Component\\Config\\Loader\\LoaderResolver`, to load secondary routing resources. Of course you still need to implement From 08b1527eea08d0b2ebcd81eacc50c6e5d659a956 Mon Sep 17 00:00:00 2001 From: Alexander Schwenn Date: Wed, 29 Apr 2015 20:52:48 +0200 Subject: [PATCH 4/4] Add filename comments to code blocks --- cookbook/routing/custom_route_loader.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cookbook/routing/custom_route_loader.rst b/cookbook/routing/custom_route_loader.rst index bff77ee78cf..046ea128409 100644 --- a/cookbook/routing/custom_route_loader.rst +++ b/cookbook/routing/custom_route_loader.rst @@ -72,6 +72,7 @@ The sample loader below supports loading routing resources with a type of ``extra``. The type ``extra`` isn't important - you can just invent any resource type you want. The resource name itself is not actually used in the example:: + // src/AppBundle/Routing/ExtraLoader.php namespace AppBundle\Routing; use Symfony\Component\Config\Loader\Loader; @@ -119,6 +120,7 @@ Make sure the controller you specify really exists. In this case you have to create an ``extraAction`` method in the ``ExtraController`` of the ``AppBundle``:: + // src/AppBundle/Controller/ExtraController.php namespace AppBundle\Controller; use Symfony\Component\HttpFoundation\Response; @@ -238,6 +240,7 @@ Whenever you want to load another resource - for instance a YAML routing configuration file - you can call the :method:`Symfony\\Component\\Config\\Loader\\Loader::import` method:: + // src/AppBundle/Routing/AdvancedLoader.php namespace AppBundle\Routing; use Symfony\Component\Config\Loader\Loader;