|
4 | 4 | How to Create a Custom Route Loader
|
5 | 5 | ===================================
|
6 | 6 |
|
| 7 | +A custom route loader allows you to add routes to an application, without |
| 8 | +writing them down in for instance a Yaml file. This comes in handy when |
| 9 | +you have made a bundle and don't want to manually add the routes for the |
| 10 | +bundle to ``app/config/routing.yml``. Especially when you want to make the |
| 11 | +bundle reusable, or when you have open-sourced it, this would slow down |
| 12 | +the installation process and make it error-prone. |
| 13 | + |
| 14 | +But you can also use a custom route loader when your routes correspond |
| 15 | +to a certain pattern and you don't want to or can't write them all out by |
| 16 | +hand. For instance when you have CRUD controllers of which the routes all |
| 17 | +correspond to a pattern like ``*_new``, ``*_edit``, etc. |
| 18 | + |
7 | 19 | Loading Routes
|
8 | 20 | --------------
|
9 | 21 |
|
10 | 22 | The routes in a Symfony application are loaded by the
|
11 | 23 | :class:`Symfony\\Bundle\\FrameworkBundle\\Routing\\DelegatingLoader`.
|
12 | 24 | This loader uses several other loaders (delegates) to load resources of
|
13 | 25 | different types, for instance Yaml files or ``@Route`` and ``@Method`` annotations
|
14 |
| -in controller files. The specialized loaders implement :class:`Symfony\\Component\\Config\\Loader\\LoaderInterface` |
15 |
| -and therefore have two important methods: :method:`Symfony\\Component\\Config\\Loader\\LoaderInterface::supports` |
| 26 | +in controller files. The specialized loaders implement |
| 27 | +:class:`Symfony\\Component\\Config\\Loader\\LoaderInterface` |
| 28 | +and therefore have two important methods: |
| 29 | +:method:`Symfony\\Component\\Config\\Loader\\LoaderInterface::supports` |
16 | 30 | and :method:`Symfony\\Component\\Config\\Loader\\LoaderInterface::load`.
|
17 | 31 |
|
18 | 32 | Take these lines from ``routing.yml``:
|
@@ -85,12 +99,12 @@ name itself is not used in the example::
|
85 | 99 |
|
86 | 100 | public function getResolver()
|
87 | 101 | {
|
88 |
| - // irrelevant to us, since we don't use a loader resolver |
| 102 | + // will be explained later |
89 | 103 | }
|
90 | 104 |
|
91 | 105 | public function setResolver(LoaderResolver $resolver)
|
92 | 106 | {
|
93 |
| - // also irrelevant |
| 107 | + // same here |
94 | 108 | }
|
95 | 109 | }
|
96 | 110 |
|
@@ -169,13 +183,64 @@ Finally, we only need to add a few extra lines to the routing configuration:
|
169 | 183 |
|
170 | 184 | return $collection;
|
171 | 185 |
|
172 |
| -The ``resource`` key is irrelevant, but required. The important part here |
173 |
| -is the ``type`` key. Its value should be "extra". This is the type which |
174 |
| -our ``ExtraLoader`` supports and this will make sure its ``load()`` method |
175 |
| -is called. |
| 186 | +The important part here is the ``type`` key. Its value should be "extra". |
| 187 | +This is the type which our ``ExtraLoader`` supports and this will make sure |
| 188 | +its ``load()`` method gets called. The ``resource`` key is insignificant |
| 189 | +for the ``ExtraLoader``, so we set it to ".". |
| 190 | + |
| 191 | +.. note:: |
| 192 | + |
| 193 | + The routes defined using custom route loaders will be automatically |
| 194 | + cached by the framework. So whenever you change something to the behavior |
| 195 | + of the loader, don't forget to clear the cache. |
| 196 | + |
| 197 | + |
| 198 | +More Advanced Loaders |
| 199 | +--------------------- |
| 200 | + |
| 201 | +In most cases it's better not to implement |
| 202 | +:class:`Symfony\\Component\\Config\\Loader\\LoaderInterface` |
| 203 | +yourself, but extend from :class:`Symfony\\Component\\Config\\Loader\\Loader`. |
| 204 | +This class knows how to use a :class:`Symfony\\Component\\Config\\Loader\\LoaderResolver` |
| 205 | +to load secondary routing resources. |
| 206 | + |
| 207 | +Of course you still need to implement |
| 208 | +:method:`Symfony\\Component\\Config\\Loader\\LoaderInterface::supports` |
| 209 | +and :method:`Symfony\\Component\\Config\\Loader\\LoaderInterface::load`. |
| 210 | +Whenever you want to load another resource, for instance a Yaml routing |
| 211 | +configuration file, you can call the |
| 212 | +:method:`Symfony\\Component\\Config\\Loader\\Loader::import` method:: |
| 213 | + |
| 214 | + namespace Acme\DemoBundle\Routing; |
| 215 | + |
| 216 | + use Symfony\Component\Config\Loader\Loader; |
| 217 | + use Symfony\Component\Routing\RouteCollection; |
| 218 | + |
| 219 | + class AdvancedLoader extends Loader |
| 220 | + { |
| 221 | + public function load($resource, $type = null) |
| 222 | + { |
| 223 | + $collection = new RouteCollection(); |
| 224 | + |
| 225 | + $resource = '@AcmeDemoBundle/Resources/config/import_routing.yml'; |
| 226 | + $type = 'yaml'; |
| 227 | + |
| 228 | + $importedRoutes = $this->import($resource, $type); |
| 229 | + |
| 230 | + $collection->addCollection($importedRoutes); |
| 231 | + |
| 232 | + return $collection; |
| 233 | + } |
| 234 | + |
| 235 | + public function supports($resource, $type = null) |
| 236 | + { |
| 237 | + return $type === 'advanced_extra'; |
| 238 | + } |
| 239 | + } |
176 | 240 |
|
177 | 241 | .. note::
|
178 | 242 |
|
179 |
| - The routes defined using the extra loader will be automatically cached |
180 |
| - by the framework. So whenever you change something to the behavior of |
181 |
| - the loader, don't forget to clear the cache. |
| 243 | + The resource name and type of the imported routing configuration can |
| 244 | + be anything that would normally be supported by the routing configuration |
| 245 | + loader (Yaml, XML, PHP, annotation, etc.). |
| 246 | + |
0 commit comments