# Zend_Controller_Router_Route_Chain

`Zend_Controller_Router_Route_Chain` is a route which allows to chain multiple routes together. This allows you to chain hostname-routes and path routes, or multiple path routes for example. Chaining can be done either programatically or within a configuration file.

## Parameter Priority

When chaining routes together, the parameters of the outer route have a higher priority than the parameters of the inner route. Thus if you define a controller in the outer and in the inner route, the controller of the outer route will be selected.

When chaining programatically, there are two ways to achieve this. The first one is to create a new `Zend_Controller_Router_Route_Chain` instance and then calling the `chain()` method multiple times with all routes which should be chained together. The other way is to take the first route, e.g. a hostname route, and calling the `chain()` method on it with the route which should be appended to it. This will not modify the hostname route, but return a new instance of `Zend_Controller_Router_Route_Chain`, which then has both routes chained together:

    // Create two routes
    $hostnameRoute = new Zend_Controller_Router_Route_Hostname(...);
    $pathRoute     = new Zend_Controller_Router_Route(...);

    // First way, chain them via the chain route
    $chainedRoute = new Zend_Controller_Router_Route_Chain();
    $chainedRoute->chain($hostnameRoute)
                 ->chain($pathRoute);

    // Second way, chain them directly
    $chainedRoute = $hostnameRoute->chain($pathRoute);

When chaining routes together, their separator is a slash by default. There may be cases when you want to have a different separator:

    // Create two routes
    $firstRoute  = new Zend_Controller_Router_Route('foo');
    $secondRoute = new Zend_Controller_Router_Route('bar');

    // Chain them together with a different separator
    $chainedRoute = $firstRoute->chain($secondRoute, '-');

    // Assemble the route: "foo-bar"
    echo $chainedRoute->assemble();

## Chain Routes via Zend_Config

To chain routes together in a config file, there are additional parameters for the configuration of those. The simpler approach is to use the chains parameters. This one is simply a list of routes, which will be chained with the parent route. Neither the parent- nor the child-route will be added directly to the router but only the resulting chained route. The name of the chained route in the router will be the parent route name and the child route name concatenated with a dash (-) by default. A simple config in XML would look like this:

    <routes>
        <www type="Zend_Controller_Router_Route_Hostname">
            <route>www.example.com</route>
            <chains>
                <language type="Zend_Controller_Router_Route">
                    <route>:language</route>
                    <reqs language="[a-z]{2}">
                    <chains>
                        <index type="Zend_Controller_Router_Route_Static">
                            <route></route>
                            <defaults module="default" controller="index"
                                      action="index" />
                        </index>
                        <imprint type="Zend_Controller_Router_Route_Static">
                            <route>imprint</route>
                            <defaults module="default" controller="index"
                                      action="index" />
                        </imprint>
                    </chains>
                </language>
            </chains>
        </www>
        <users type="Zend_Controller_Router_Route_Hostname">
            <route>users.example.com</route>
            <chains>
                <profile type="Zend_Controller_Router_Route">
                    <route>:username</route>
                    <defaults module="users" controller="profile" action="index" />
                </profile>
            </chains>
        </users>
        <misc type="Zend_Controller_Router_Route_Static">
            <route>misc</route>
        </misc>
    </routes>

This will result in the three routes `www-language-index`, `www-language-imprint` and `users-language-profile` which will only match based on the hostname and the route `misc`, which will match with any hostname.

The alternative way of creating a chained route is via the chain parameter, which can only be used with the chain-route type directly, and also just works in the root level:

    <routes>
        <www type="Zend_Controller_Router_Route_Chain">
            <route>www.example.com</route>
        </www>
        <language type="Zend_Controller_Router_Route">
            <route>:language</route>
            <reqs language="[a-z]{2}">
        </language>
        <index type="Zend_Controller_Router_Route_Static">
            <route></route>
            <defaults module="default" controller="index" action="index" />
        </index>
        <imprint type="Zend_Controller_Router_Route_Static">
            <route>imprint</route>
            <defaults module="default" controller="index" action="index" />
        </imprint>

        <www-index type="Zend_Controller_Router_Route_Chain">
            <chain>www, language, index</chain>
        </www-index>
        <www-imprint type="Zend_Controller_Router_Route_Chain">
            <chain>www, language, imprint</chain>
        </www-imprint>
    </routes>

You can also give the chain parameter as array instead of separating the routes with a comma:

    <routes>
        <www-index type="Zend_Controller_Router_Route_Chain">
            <chain>www</chain>
            <chain>language</chain>
            <chain>index</chain>
        </www-index>
        <www-imprint type="Zend_Controller_Router_Route_Chain">
            <chain>www</chain>
            <chain>language</chain>
            <chain>imprint</chain>
        </www-imprint>
    </routes>

When you configure chain routes with `Zend_Config` and want the chain name separator to be different from a dash, you need to specify this separator separately:

    $config = new Zend_Config(array(
        'chainName' => array(
            'type'   => 'Zend_Controller_Router_Route_Static',
            'route'  => 'foo',
            'chains' => array(
                'subRouteName' => array(
                    'type'     => 'Zend_Controller_Router_Route_Static',
                    'route'    => 'bar',
                    'defaults' => array(
                        'module'      => 'module',
                         'controller' => 'controller',
                         'action'     => 'action'
                    )
                )
            )
        )
    ));

    // Set separator before adding config
    $router->setChainNameSeparator('_separator_')

    // Add config
    $router->addConfig($config);

    // The name of our route now is: chainName_separator_subRouteName
    echo $this->_router->assemble(array(), 'chainName_separator_subRouteName');

    // The proof: it echoes /foo/bar