Skip to content

Fix hostname matching articles #3125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 3, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions book/routing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -707,8 +707,8 @@ form via the same URL, while using distinct controllers for the two actions.

If no ``methods`` are specified, the route will match on *all* methods.

Adding a Host
~~~~~~~~~~~~~
Adding a Host Requirement
~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 2.2
Host matching support was added in Symfony 2.2
Expand Down Expand Up @@ -1067,8 +1067,8 @@ from the new routing resource.
:doc:`FrameworkExtraBundle documentation </bundles/SensioFrameworkExtraBundle/annotations/routing>`
to see how.

Adding a Host regex to Imported Routes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Adding a Host requirement to Imported Routes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 2.2
Host matching support was added in Symfony 2.2
Expand Down
157 changes: 136 additions & 21 deletions components/routing/hostname_pattern.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,31 +60,79 @@ You can also match on the HTTP *host* of the incoming request.
Both routes match the same path ``/``, however the first one will match
only if the host is ``m.example.com``.

Placeholders and Requirements in Hostname Patterns
--------------------------------------------------
Using Placeholders
------------------

If you're using the :doc:`DependencyInjection Component </components/dependency_injection/index>`
(or the full Symfony2 Framework), then you can use
:ref:`service container parameters <book-service-container-parameters>` as
variables anywhere in your routes.
The host option uses the same syntax as the path matching system. This means
you can use placeholders in your hostname:

You can avoid hardcoding the domain name by using a placeholder and a requirement.
The ``%domain%`` in requirements is replaced by the value of the ``domain``
dependency injection container parameter.
.. configuration-block::

.. code-block:: yaml

projects_homepage:
path: /
host: "{project_name}.example.com"
defaults: { _controller: AcmeDemoBundle:Main:mobileHomepage }

homepage:
path: /
defaults: { _controller: AcmeDemoBundle:Main:homepage }

.. code-block:: xml

<?xml version="1.0" encoding="UTF-8" ?>

<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing
http://symfony.com/schema/routing/routing-1.0.xsd"
>

<route id="projects_homepage" path="/" host="{project_name}.example.com">
<default key="_controller">AcmeDemoBundle:Main:mobileHomepage</default>
</route>

<route id="homepage" path="/">
<default key="_controller">AcmeDemoBundle:Main:homepage</default>
</route>
</routes>

.. code-block:: php

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

$collection = new RouteCollection();
$collection->add('project_homepage', new Route('/', array(
'_controller' => 'AcmeDemoBundle:Main:mobileHomepage',
), array(), array(), '{project_name}.example.com'));

$collection->add('homepage', new Route('/', array(
'_controller' => 'AcmeDemoBundle:Main:homepage',
)));

return $collection;

You can also set requirements and default options for these placeholders. For
instance, if you want to match both ``m.example.com`` and
``mobile.example.com``, you use this:

.. configuration-block::

.. code-block:: yaml

mobile_homepage:
path: /
host: m.{domain}
defaults: { _controller: AcmeDemoBundle:Main:mobileHomepage }
host: "{subdomain}.example.com"
defaults:
_controller: AcmeDemoBundle:Main:mobileHomepage
subdomain: m
requirements:
domain: %domain%
subdomain: m|mobile

homepage:
path: /
path: /
defaults: { _controller: AcmeDemoBundle:Main:homepage }

.. code-block:: xml
Expand All @@ -93,11 +141,15 @@ dependency injection container parameter.

<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
xsi:schemaLocation="http://symfony.com/schema/routing
http://symfony.com/schema/routing/routing-1.0.xsd"
>

<route id="mobile_homepage" path="/" host="m.example.com">
<route id="mobile_homepage" path="/" host="{subdomain}.example.com">
<default key="_controller">AcmeDemoBundle:Main:mobileHomepage</default>
<requirement key="domain">%domain%</requirement>
<default key="subdomain">m</default>

<requirement key="subdomain">m|mobile</requirement>
</route>

<route id="homepage" path="/">
Expand All @@ -113,22 +165,85 @@ dependency injection container parameter.
$collection = new RouteCollection();
$collection->add('mobile_homepage', new Route('/', array(
'_controller' => 'AcmeDemoBundle:Main:mobileHomepage',
'subdomain' => 'm',
), array(
'domain' => '%domain%',
), array(), 'm.{domain}'));
'subdomain' => 'm|mobile',
), array(), '{subdomain}.example.com'));

$collection->add('homepage', new Route('/', array(
'_controller' => 'AcmeDemoBundle:Main:homepage',
)));

return $collection;

.. tip::

Make sure you also include a default option for the ``subdomain``
placeholder, otherwise you need to include the subdomains value each time
you generate the route.

.. sidebar:: Using Service Parameters

You can also use service parameters if you do not want to hardcode the
hostname:

.. configuration-block::

.. code-block:: yaml

mobile_homepage:
path: /
host: "m.{domain}"
defaults: { _controller: AcmeDemoBundle:Main:mobileHomepage }
requirements:
domain: "%domain%"

homepage:
path: /
defaults: { _controller: AcmeDemoBundle:Main:homepage }

.. code-block:: xml

<?xml version="1.0" encoding="UTF-8" ?>

<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">

<route id="mobile_homepage" path="/" host="m.example.com">
<default key="_controller">AcmeDemoBundle:Main:mobileHomepage</default>
<requirement key="domain">%domain%</requirement>
</route>

<route id="homepage" path="/">
<default key="_controller">AcmeDemoBundle:Main:homepage</default>
</route>
</routes>

.. code-block:: php

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

$collection = new RouteCollection();
$collection->add('mobile_homepage', new Route('/', array(
'_controller' => 'AcmeDemoBundle:Main:mobileHomepage',
), array(
'domain' => '%domain%',
), array(), 'm.{domain}'));

$collection->add('homepage', new Route('/', array(
'_controller' => 'AcmeDemoBundle:Main:homepage',
)));

return $collection;

.. _component-routing-host-imported:

Adding a Host Regex to Imported Routes
--------------------------------------------
Using Host Matching of Imported Routes
--------------------------------------

You can set a host regex on imported routes:
You can also set the host option on imported routes:

.. configuration-block::

Expand Down