The Symfony default Router was developed to handle static Route definitions,
as they are usually declared in configuration files, prior to execution.
The complete routing configuration is injected in the constructor. It then
UrlMatcher with this
configuration, rather than having the matcher injected as a service. This makes
the default router a poor choice to handle dynamically defined routes. To
handle large numbers of user created routes, this component contains the
DynamicRouter that is configured with a
The actual matching logic depends on the underlying matcher implementation you
choose. You can easily use you own matching strategy by passing it to the
DynamicRouter constructor. As part of this component, the
NestedMatcher is already provided.
The DynamicRouter further allows to modify the resulting parameters of the
routing match, using a set of
RouteEnhancerInterface that can be easily
DynamicRouter is also able to generate URLs from
ProviderBasedGenerator can generate URLs loaded from a
RouteProviderInterface instance. The
Route to generate the URL from any content object that
RouteReferrersInterface, meaning you can generate a URL
directly from a content object.
Optionally, you can provide an Event Dispatcher to the dynamic router. If you do, it will trigger one of the pre-match events during the match process, depending on which method is used and another event before generating a URL:
- cmf_routing.pre_dynamic_match (Dispatched at the beginning of the
- cmf_routing.pre_dynamic_match_request (Dispatched at the beginning of the
matchRequestmethod. In the context of the Symfony full stack framework, only this event will be triggered.)
- cmf_routing.pre_dynamic_generate (Dispatched at the beginning of the
Pre-match events are of class
the generate event is of class
The generate event also allows you to manipulate the route name, parameters and
reference type in the event, by updating the values in the event.
Symfony\Cmf\Component\Routing\Event\Events class contains the event
constants. To learn how to register the events, see
"How to create an Event Listener" in the core documentation.
Optionally, and following the matching process, a set of
RouteEnhancerInterface instances can be applied by the
Route enhancers are a way to manipulate the parameters from the matched route
before the framework continues. They can be used, for example, to dynamically
assign a controller or to keep logic out of the controller by determining
parameters or "upcasting" request parameters to the objects they correspond
The component already provides some general purpose enhancers. They all follow the principle to never change an existing field but only add fields if they do not exist yet:
- If the route is an instance of
RouteObjectInterface, this enhancer sets the target field to the return value of
- Configured with a key-value map. If a specified field of the match contains a key, the target field is set to the value.
- Configured with a map of class names to values. If the specified field
contains an object that is an instance of a class in the map, sets the
target field to the corresponding value. Note that the first match is
taken, should the objects be instance of more than one of the classes. This
enhancer is for example used to determine the controller and template based
on the class of a Content document. This enhancer is similar to
FieldMapEnhancer, but doing an instanceof check rather than string comparison for the map keys.
- If a field is present in the route match, sets an other field to a specified value if that field is not set yet.
- If the source field is present in the route match, sets target field to the
content returned by the
ContentRepositoryInterfacewith value of the source field, if target field is not yet set.
You can also create your own route enhancer by creating a class which
Route enhancers are registered using the
addRouteEnhancer method, which has
an optional second argument to provide the priority.
Route Enhancer Compiler Pass¶
This component provides a
RegisterRouteEnhancersPass. If you use the
Symfony Dependency Injection Component, you can use this compiler pass to
register all enhancers having a specific tag with the dynamic router:
1 2 3 4 5 6 7 8
use Symfony\Cmf\Component\Routing\DependencyInjection\Compiler\RegisterRouterEnhancersPass; use Symfony\Component\DependencyInjection\ContainerBuilder; // a ContainerBuilder $container = ...; $pass = new RegisterRouterEnhancersPass('cmf_routing.dynamic_router', 'dynamic_router_route_enhancer'); $container->addCompilerPass($pass);
After adding the passes and configuring the container builder, you continue with compiling the container as explained in the Symfony DI Component compilation section.
You can optionally configure the dynamic router service name. The compiler pass
will modify this service definition to register the enhancers when the dynamic
router is loaded from the container. If you do not specify anything, the
default service name is
You can also configure the tag name you want to use with the second argument to
the compiler pass constructor. If you don't, the default tag is
dynamic_router_route_enhancer. If you are using the
Symfony CMF RoutingBundle, this tag is
already active with the default name.
You can create redirections by implementing the
It can redirect to an absolute URI, a route name that can be generated by any
Router in the chain or to another
Notice that the actual redirection logic is not handled by the bundle. You should implement your own logic to handle the redirection. For an example of implementing that redirection under the full Symfony stack, refer to the RoutingBundle.
Apart from matching an incoming request to a set of parameters, a Router
is also responsible for generating an URL from a route and its parameters.
ChainRouter iterates over its known routers until one of them is
able to generate a matching URL.
UrlMatcherInterface to match a
Request/URL to its corresponding parameters, the
DynamicRouter also uses
UrlGeneratorInterface instance, which allows it to generate an URL from
The generator method looks like this:
public function generate($name, $parameters = , $referenceType = self::ABSOLUTE_PATH);
In Symfony core, the
$name has to be a string with the configured name
of the route to generate. The CMF routing component adds generators that handle
alternative semantics of
New in version 2.3: Since symfony-cmf/routing: 2.3.0, the route document should be passed in the route parameters as _route_object, and the special route name cmf_routing_object is to be used. When using older versions of routing, you need to pass the route document as route name.
ProviderBasedGenerator extends Symfony's default
UrlGenerator (which, in turn,
and asks the route provider to find a route based on the name and parameters. It
then lets the core logic generate the URL from that
The CMF component also includes the
ContentAwareGenerator, which extends
ProviderBasedGenerator, that checks if
_route_object parameter is an object
RouteReferrersReadInterface. If it is, it gets the
from that object. Using the
ContentAwareGenerator, you can generate URLs
for your content in three ways:
- Either pass a
Routeobject as the
- Or pass a
RouteReferrersInterfaceobject that is your content as the
- Or provide an implementation of
ContentRepositoryInterfaceand pass the id of the content object as parameter
If you want to implement your own generator, implement the
to get better debug messages for when a route can not be generated.
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.