diff --git a/_exts/sensio/sphinx/configurationblock.py b/_exts/sensio/sphinx/configurationblock.py
index 7269f192..e0077c02 100644
--- a/_exts/sensio/sphinx/configurationblock.py
+++ b/_exts/sensio/sphinx/configurationblock.py
@@ -6,7 +6,6 @@
from docutils.parsers.rst import Directive, directives
from docutils import nodes
-from string import upper
class configurationblock(nodes.General, nodes.Element):
pass
diff --git a/_exts/sensio/sphinx/phpcode.py b/_exts/sensio/sphinx/phpcode.py
index c9230a3f..8379129b 100644
--- a/_exts/sensio/sphinx/phpcode.py
+++ b/_exts/sensio/sphinx/phpcode.py
@@ -7,7 +7,7 @@
from docutils import nodes, utils
from sphinx.util.nodes import split_explicit_title
-from string import lower
+import sys
def php_namespace_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
text = utils.unescape(text)
@@ -82,7 +82,7 @@ def php_phpclass_role(typ, rawtext, text, lineno, inliner, options={}, content=[
text = utils.unescape(text)
has_explicit_title, title, full_class = split_explicit_title(text)
- full_url = 'http://php.net/manual/en/class.%s.php' % lower(full_class)
+ full_url = 'http://php.net/manual/en/class.%s.php' % full_class.lower()
if not has_explicit_title:
title = full_class
@@ -94,7 +94,7 @@ def php_phpfunction_role(typ, rawtext, text, lineno, inliner, options={}, conten
text = utils.unescape(text)
has_explicit_title, title, full_function = split_explicit_title(text)
- full_url = 'http://php.net/manual/en/function.%s.php' % lower(full_function.replace('_', '-'))
+ full_url = 'http://php.net/manual/en/function.%s.php' % full_function.replace('_', '-').lower()
if not has_explicit_title:
title = full_function
diff --git a/bundles/map.rst.inc b/bundles/map.rst.inc
index a8e67e34..af8c003e 100644
--- a/bundles/map.rst.inc
+++ b/bundles/map.rst.inc
@@ -50,9 +50,9 @@ library or they introduce a complete new concept.
* :doc:`routing_auto/index`
* :doc:`routing_auto/introduction`
- * :doc:`routing_auto/providers`
- * :doc:`routing_auto/exists_actions`
- * :doc:`routing_auto/not_exists_actions`
+ * :doc:`routing_auto/token_providers`
+ * :doc:`routing_auto/conflict_resolvers`
+ * :doc:`routing_auto/defunct_route_handlers`
* :doc:`routing_auto/customization`
* :doc:`search/index`
diff --git a/bundles/routing_auto/conflict_resolvers.rst b/bundles/routing_auto/conflict_resolvers.rst
new file mode 100644
index 00000000..eec96aba
--- /dev/null
+++ b/bundles/routing_auto/conflict_resolvers.rst
@@ -0,0 +1,56 @@
+.. index::
+ single: Conflict Resolvers; RoutingAutoBundle
+
+Conflict Resolvers
+------------------
+
+Conflict resolvers are invoked when the system detects that a newly generated
+route would conflict with an route already existing in the route repository.
+
+This section details the conflict resolvers which are provided by default.
+
+auto_increment
+~~~~~~~~~~~~~~
+
+The ``auto_increment`` conflict resolver will add a numerical suffix to the path, for
+example if ``my/path`` already exists, it would first become ``my/path-1`` and if that path *also*
+exists it will try ``my/path-2``, ``my/path-3`` and so on into infinity until
+it finds a path which *doesn't* exist.
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ stdClass:
+ uri_schema: /cmf/blog
+ conflict_resolver: auto_increment
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+throw_exception
+~~~~~~~~~~~~~~~
+
+The ``throw_exception`` efficiently "resolves" conflicts by throwing exceptions.
+This is the default action.
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ stdClass:
+ uri_schema: /cmf/blog
+ conflict_resolver: throw_exception
+
+ .. code-block:: xml
+
+
+
+
+
+
diff --git a/bundles/routing_auto/customization.rst b/bundles/routing_auto/customization.rst
index b293ebfe..cd3d123c 100644
--- a/bundles/routing_auto/customization.rst
+++ b/bundles/routing_auto/customization.rst
@@ -4,53 +4,65 @@
Customization
-------------
-.. _routingauto_customization_pathproviders:
+.. _routingauto_customization_tokenproviders:
-Adding Path Providers
-~~~~~~~~~~~~~~~~~~~~~
+Token Providers
+~~~~~~~~~~~~~~~
-The goal of a ``PathProvider`` class is to add one or several path elements to
-the route stack. For example, the following provider will add the path
-``foo/bar`` to the route stack::
+The goal of a ``TokenProvider`` class is to provide values for tokens in the
+URI schema. Such values can be derived form the object for which the route
+is being generated, or from the environment (e.g. the you could use the
+current locale in the route).
- // src/Acme/CmsBundle/RoutingAuto/PathProvider/FoobarProvider.php
- namespace Acme\CmsBundle\RoutingAuto\PathProvider;
+The following token provider will simply provide the value "foobar"::
- use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathProviderInterface;
- use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\RouteStack;
+ // src/Acme/CmsBundle/RoutingAuto/PathProvider/FoobarTokenProvider.php
+ namespace Symfony\Cmf\Component\RoutingAuto\TokenProvider;
- class FoobarProvider implements PathProviderInterface
+ use Symfony\Cmf\Component\RoutingAuto\TokenProviderInterface;
+ use Symfony\Component\OptionsResolver\OptionsResolverInterface;
+ use Symfony\Cmf\Component\RoutingAuto\UriContext;
+
+ class FoobarTokenProvider implements TokenProviderInterface
{
- public function providePath(RouteStack $routeStack)
+ /**
+ * {@inheritDoc}
+ */
+ public function provideValue(UriContext $uriContext, $options)
+ {
+ return 'foobar';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function configureOptions(OptionsResolverInterface $optionsResolver)
{
- $routeStack->addPathElements(array('foo', 'bar'));
}
}
To use the path provider you must register it in the container and add the
-``cmf_routing_auto.provider`` tag and set the **alias** accordingly:
+``cmf_routing_auto.token_provider`` tag and set the **alias** accordingly:
.. configuration-block::
.. code-block:: yaml
services:
- acme_cms.path_provider.foobar:
- class: Acme\CmsBundle\RoutingAuto\PathProvider\FoobarProvider
- scope: prototype
+ acme_cms.token_provider.foobar:
+ class: Acme\CmsBundle\RoutingAuto\PathProvider\FoobarTokenProvider
tags:
- - { name: cmf_routing_auto.provider, alias: "foobar"}
+ - { name: cmf_routing_auto.token_provider, alias: "foobar" }
.. code-block:: xml
-
+
@@ -58,54 +70,110 @@ To use the path provider you must register it in the container and add the
use Symfony\Component\DependencyInjection\Definition;
- $definition = new Definition('Acme\CmsBundle\RoutingAuto\PathProvider\FoobarProvider');
- $definition->addTag('cmf_routing_auto.provider', array('alias' => 'foobar'));
- $definition->setScope('prototype');
+ $definition = new Definition('Acme\CmsBundle\RoutingAuto\PathProvider\FoobarTokenProvider');
+ $definition->addTag('cmf_routing_auto.token_provider', array('alias' => 'foobar'));
- $container->setDefinition('acme_cms.path_provider.foobar', $definition);
+ $container->setDefinition('acme_cms.token_provider.foobar', $definition);
-The ``FoobarProvider`` is now available as **foobar** in the routing auto
+The ``FoobarTokenProvider`` is now available as **foobar** in the routing auto
configuration.
-.. caution::
+Conflict Resolvers
+~~~~~~~~~~~~~~~~~~
+
+Conflict resolvers decide what happens if a generated route already exists in
+the route repository and is not related to the context object.
+
+The following example will append an unique string to the URI to resolve a
+conflict::
+
+ namespace Symfony\Cmf\Component\RoutingAuto\ConflictResolver;
+
+ use Symfony\Cmf\Component\RoutingAuto\ConflictResolverInterface;
+ use Symfony\Cmf\Component\RoutingAuto\UriContext;
+ use Symfony\Cmf\Component\RoutingAuto\Adapter\AdapterInterface;
+
+ class UniqidConflictResolver implements ConflictResolverInterface
+ {
+ public function resolveConflict(UriContext $uriContext)
+ {
+ $uri = $uriContext->getUri();
+ return sprintf('%s-%s', uniqid());
+ }
+ }
+
+It is registered in the DI configuration as follows:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ services:
+ acme_cms.conflict_resolver.foobar:
+ class: Acme\CmsBundle\RoutingAuto\ConflictResolver\UniqidConflictResolver
+ tags:
+ - { name: cmf_routing_auto.conflict_resolver, alias: "uniqid"}
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ use Symfony\Component\DependencyInjection\Definition;
- Both path providers and path actions need to be defined with a scope of
- "prototype". This ensures that each time the auto routing system requests
- the class a new one is given and you do not have any state problems.
+ $definition = new Definition('Acme\CmsBundle\RoutingAuto\ConflictResolver\UniqidConflictResolver');
+ $definition->addTag('cmf_routing_auto.conflict_resolver', array('alias' => 'foobar'));
-Adding Path Actions
-~~~~~~~~~~~~~~~~~~~
+ $container->setDefinition('acme_cms.conflict_resolver.uniqid', $definition);
-In the auto routing system, a "path action" is an action to take if the path
-provided by the "path provider" exists or not.
+Defunct Route Handlers
+~~~~~~~~~~~~~~~~~~~~~~
-You can add a path action by extending the ``PathActionInterface`` and
-registering your new class correctly in the DI configuration.
+Defunct Route Handlers decide what happens to old routes when an object is
+updated and its generated URI changes.
-This is a very simple implementation from the bundle - it is used to throw an
-exception when a path already exists::
+They are not all-together trivial - the following handler removes old routes and is
+the default handler::
- namespace Symfony\Cmf\Bundle\RoutingAutoBundle\RoutingAuto\PathNotExists;
+ namespace Symfony\Cmf\Component\RoutingAuto\DefunctRouteHandler;
- use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathActionInterface;
- use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Exception\CouldNotFindRouteException;
- use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\RouteStack;
+ use Symfony\Cmf\Component\RoutingAuto\DefunctRouteHandlerInterface;
+ use Symfony\Cmf\Component\RoutingAuto\UriContextCollection;
+ use Symfony\Cmf\Component\RoutingAuto\Adapter\AdapterInterface;
- class ThrowException implements PathActionInterface
+ class RemoveDefunctRouteHandler implements DefunctRouteHandlerInterface
{
- public function init(array $options)
+ protected $adapter;
+
+ public function __construct(AdapterInterface $adapter)
{
+ $this->adapter = $adapter;
}
- public function execute(RouteStack $routeStack)
+ public function handleDefunctRoutes(UriContextCollection $uriContextCollection)
{
- throw new CouldNotFindRouteException('/'.$routeStack->getFullPath());
+ $referringAutoRouteCollection = $this->adapter->getReferringAutoRoutes($uriContextCollection->getSubjectObject());
+
+ foreach ($referringAutoRouteCollection as $referringAutoRoute) {
+ if (false === $uriContextCollection->containsAutoRoute($referringAutoRoute)) {
+ $newRoute = $uriContextCollection->getAutoRouteByTag($referringAutoRoute->getAutoRouteTag());
+
+ $this->adapter->migrateAutoRouteChildren($referringAutoRoute, $newRoute);
+ $this->adapter->removeAutoRoute($referringAutoRoute);
+ }
+ }
}
}
-The ``init()`` method configures the provider (throwing errors when required
-options do not exists) and the ``execute()`` method executes the action.
-
It is registered in the DI configuration as follows:
.. configuration-block::
@@ -113,22 +181,20 @@ It is registered in the DI configuration as follows:
.. code-block:: yaml
services:
- cmf_routing_auto.not_exists_action.throw_exception:
- class: Symfony\Cmf\Bundle\RoutingAutoBundle\RoutingAuto\PathNotExists\ThrowException
- scope: prototype
+ acme_cms.defunct_route_handler.foobar:
+ class: Acme\CmsBundle\RoutingAuto\DefunctRouteHandler\RemoveConflictResolver
tags:
- - { name: cmf_routing_auto.not_exists_action, alias: "throw_exception"}
+ - { name: cmf_routing_auto.defunct_route_handler, alias: "remove"}
.. code-block:: xml
-
+ id="acme_cms.defunct_route_handler.foobar"
+ class="Acme\CmsBundle\RoutingAuto\DefunctRouteHandler\RemoveConflictResolver"
+ >
+
@@ -136,22 +202,7 @@ It is registered in the DI configuration as follows:
use Symfony\Component\DependencyInjection\Definition;
- $definition = new Definition('Symfony\Cmf\Bundle\RoutingAutoBundle\RoutingAuto\PathNotExists\ThrowException');
- $definition->addTag('cmf_routing_auto.provider', array('alias' => 'throw_exception'));
- $definition->setScope('prototype');
-
- $container->setDefinition('cmf_routing_auto.not_exists_action.throw_exception', $definition);
-
-Note the following:
-
-* **Scope**: Must *always* be set to *prototype*;
-* **Tag**: The tag registers the service with the auto routing system, it can
- be one of the following:
-
- * ``cmf_routing_auto.exists.action`` - if the action is to be used when a
- path exists;
- * ``cmf_routing_auto.not_exists.action`` - if the action is to be used when
- a path does not exist;
+ $definition = new Definition('Acme\CmsBundle\RoutingAuto\DefunctRouteHandler\RemoveConflictResolver');
+ $definition->addTag('cmf_routing_auto.defunct_route_handler', array('alias' => 'foobar'));
-* **Alias**: The alias of the tag is the name by which you will reference this
- action in the auto routing configuration.
+ $container->setDefinition('acme_cms.defunct_route_handler.remove', $definition);
diff --git a/bundles/routing_auto/defunct_route_handlers.rst b/bundles/routing_auto/defunct_route_handlers.rst
new file mode 100644
index 00000000..caced977
--- /dev/null
+++ b/bundles/routing_auto/defunct_route_handlers.rst
@@ -0,0 +1,103 @@
+.. index::
+ single: Customization; RoutingAutoBundle
+
+Defunct Route Handlers
+----------------------
+
+.. _routingauto_customization_defunctroutehandlers:
+
+When an already-persisted document is updated and the URI generated by the
+RoutingAuto system is changed, a *new* route is always created. Defunct route
+handlers decide what to do with the *old* routes.
+
+remove
+~~~~~~
+
+The remove handler will simply delete any old routes. This is the **default**
+action.
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ stdClass:
+ uri_schema: /cmf/blog
+ defunct_route_handler: remove
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+.. note::
+
+ The above example is illustrative only. Removing old routes is the default
+ action, so it is not necessary to explicitly configure this handler.
+
+leave_redirect
+~~~~~~~~~~~~~~
+
+The ``LeaveRedirectDefunctRouteHandler`` will automatically update old routes
+to redirect the browser to the route which has replaced it. This effectively
+means you can rename your objects without worrying about users recieving HTTP
+404 responses.
+
+The handler will replace the old route with a ``RedirectRoute`` at the same
+path.
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ stdClass:
+ uri_schema: /cmf/blog
+ defunct_route_handler: leave_redirect
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+For the redirect to work you will also need to configure a redirect controller
+in the ``cmf_routing`` configuration::
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ cmf_routing:
+ dynamic:
+ controllers_by_class:
+ Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\RedirectRoute: cmf_routing.redirect_controller:redirectAction
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+ cmf_routing.redirect_controller:redirectAction
+
+
+
+
+
+
+ .. code-block:: php
+
+ $container->loadFromExtension('cmf_routing', array(
+ 'dynamic' => array(
+ 'controllers_by_class' => array(
+ 'Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\RedirectRoute' => 'cmf_routing.redirect_controller:redirectAction',
+ ),
+ ),
+ ));
diff --git a/bundles/routing_auto/exists_actions.rst b/bundles/routing_auto/exists_actions.rst
deleted file mode 100644
index 476ce4f8..00000000
--- a/bundles/routing_auto/exists_actions.rst
+++ /dev/null
@@ -1,67 +0,0 @@
-.. index::
- single: Exists Actions; RoutingAutoBundle
-
-Path Exists Actions
--------------------
-
-These are the default actions available to take if the path provided by a
-``path_provider`` already exists and so creating a new path would create a
-conflict.
-
-auto_increment
-~~~~~~~~~~~~~~
-
-The ``auto_increment`` action will add a numerical suffix to the path, for
-example ``my/path`` would first become ``my/path-1`` and if that path *also*
-exists it will try ``my/path-2``, ``my/path-3`` and so on into infinity until
-it finds a path which *doesn't* exist.
-
-This action should typically be used in the ``content_name`` builder unit to
-resolve conflicts. Using it in the ``content_path`` builder chain would not
-make much sense.
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- exists_action: auto_increment
-
- .. code-block:: xml
-
-
-
- .. code-block:: php
-
- array(
- // ...
- 'exists_action' => 'auto_increment',
- );
-
-use
-~~~
-
-The ``use`` action will simply take the existing path and use it. For example,
-in a forum the builder unit must first determine the category path, ``/my-category``,
-if this path exists (and it should) then it will be *used* in the stack.
-
-This action should typically be used in one of the content path builder units
-to specify that it should use the existing route. On the other hand, using
-this as the content name builder action should cause the old route to be
-overwritten.
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- exists_action: use
-
- .. code-block:: xml
-
-
-
- .. code-block:: php
-
- array(
- // ...
- 'exists_action' => 'use',
- );
diff --git a/bundles/routing_auto/index.rst b/bundles/routing_auto/index.rst
index 1ddaf6b6..0f82770f 100644
--- a/bundles/routing_auto/index.rst
+++ b/bundles/routing_auto/index.rst
@@ -5,7 +5,8 @@ RoutingAutoBundle
:maxdepth: 2
introduction
- providers
- exists_actions
- not_exists_actions
+ token_providers
+ conflict_resolvers
+ defunct_route_handlers
customization
+
diff --git a/bundles/routing_auto/introduction.rst b/bundles/routing_auto/introduction.rst
index a8e4c61c..98b31a34 100644
--- a/bundles/routing_auto/introduction.rst
+++ b/bundles/routing_auto/introduction.rst
@@ -5,10 +5,8 @@
RoutingAutoBundle
=================
- The RoutingAutoBundle allows you to define automatically created routes for
- documents.
-
-.. include:: ../_not-stable-caution.rst.inc
+The RoutingAutoBundle allows you to automatically persist routes when
+documents are persisted based on URI schemas and contextual information.
This implies a separation of the ``Route`` and ``Content`` documents. If your
needs are simple this bundle may not be for you and you should have a look at
@@ -30,7 +28,7 @@ content documents - a category and the topics. These documents are called
If you create a new category with the title "My New Category", the
RoutingAutoBundle will automatically create the route
``/forum/my-new-cateogry``. For each new ``Topic`` it could create a route
-like ``/forum/my-new-category/my-new-topic``. This URL resolves to a special
+like ``/forum/my-new-category/my-new-topic``. This URI resolves to a special
type of route that is called an *auto route*.
By default, when you update a content document that has an auto route, the
@@ -51,13 +49,13 @@ pattern ``/forum/my-new-forum/{topic}``, which could be handled by a controller.
Why not just do that?
#. By having a route for each page in the system, the application has a
- knowledge of which URLs are accessible. This can be very useful, for
+ knowledge of which URIs are accessible. This can be very useful, for
example, when specifying endpoints for menu items that are used when generating
a site map;
#. By separating the route from the content you allow the route to be
customized independently of the content, for example, a topic may have
- the same title as another topic but might need a different URL;
-#. Separate route documents are translateable - this means you can have a URL
+ the same title as another topic but might need a different URI;
+#. Separate route documents are translateable - this means you can have a URI
for *each language*, "/welcome" and "/bienvenue" would each reference the
same document in English and French respectively. This would be difficult
if the slug was embedded in the content document;
@@ -68,142 +66,58 @@ Why not just do that?
Usage
-----
-The diagram below shows a fictional URL for a forum topic. The first 6 elements
-of the URL are called the *content path*. The last element is called the *content name*.
+Imagine you have a fictional forum application and that you want to access the
+forum topic with the following fictional URI:
-.. image:: ../../_images/bundles/routing_auto_post_schema.png
+- ``https://mywebsite.com/my-forum/drinks/coffee``
-The content path is further broken down into *path units* and *path elements*. A
-path unit is a group of path elements and path elements are simply documents
-in the PHPCR tree.
+The RoutingAutoBundle uses a URI schema to define how routes are generated. A
+schema for the above URI would look like this (the bundle does not care about
+the host or protocol):
-.. note::
+- ``/my-forum/{category}/{title}``
- Although path elements can be of any document class in this case, only
- objects which extend the :class:`Symfony\\Component\\Routing\\Route`
- object will be considered when matching a URL.
+You can see that ``my-forum`` is static (it will not change) but that
+``drinks`` has been replaced with ``{category}`` and ``coffee`` with
+``{title}``. The replacements are called *tokens*.
- The default behavior is to use ``Generic`` documents when generating a content
- path, and these documents will result in a 404 when accessed directly.
+The value for tokens are provided by *token providers*.
-Internally, each path unit is built up by a *builder unit*. Builder units
-contain one *path provider* class and two actions classes - one action to take
-if the provided path exists in the PHPCR tree, the other if it does not. The
-goal of each builder unit is to generate a path and then provide a route
-object for each element in that path.
+The schema, token providers, and other configurations (more on this later) are
+contained within ``routing_auto.format`` files (currently ``xml`` and ``yaml`` are
+supported). These files are contained either in your bundles
+``Resources/config`` directory or in a custom location specified in
+the bundle configuration.
-The configuration for the example above could be as follows:
+The configuration files for the above schema as applied to a ``Topic``
+document could be defined as follows:
.. configuration-block::
.. code-block:: yaml
- # app/config/config.yml
- cmf_routing_auto:
- mappings:
-
- Acme\ForumBundle\Document\Topic
- content_path:
- # corresponds first path unit in diagram: my-forum
- forum_path:
- provider: [specified, { path: my-form }]
- exists_action: use
- not_exists_action: create
-
- # corresponds second path unit in diagram: my-category
- category_path:
- provider: [content_object, { method: getCategory }]
- exists_action: use
- not_exists_action: throw_exception
-
- # corresponds to the content name: my-new-topic
- content_name:
- provider: [content_method, { method: getTitle }]
- exists_action: [auto_increment, { pattern: -%d }]
- not_exists_action: create
-
- .. code-block:: xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- .. code-block:: php
-
- // app/config/config.php
- $container->loadFromExtension('cmf_routing_auto', array(
- 'mappings' => array(
- 'Acme\ForumBundle\Document\Topic' => array(
- 'content_path' => array(
- // corresponds first path unit in diagram: my-forum
- 'forum_path' => array(
- 'provider' => array('specified', array(
- 'path' => 'my-forum',
- )),
- 'exists_action' => 'use',
- 'not_exists_action' => 'create',
- ),
-
- // corresponds second path unit in diagram: my-category
- 'category_path' => array(
- 'provider' => array('content_object', array(
- 'method' => 'getCategory',
- )),
- 'exists_action' => 'use',
- 'not_exists_action' => 'throw_exception',
- ),
- ),
-
- // corresponds to the content name: my-new-topic
- 'content_name' => array(
- 'provider' => array('content_method', array(
- 'method' => 'getTitle',
- )),
- 'exists_action' => array('auto_increment', array(
- 'pattern' => '-%d',
- )),
- 'not_exists_action' => 'create',
- ),
- ),
- ),
- ));
+ # src/Acme/ForumBundle/Resources/config/routing_auto.yml
+ Acme\ForumBundle\Document\Topic:
+ uri_schema: /my-forum/{category}/{title}
+ token_providers:
+ category: [content_method, {method: getCategoryTitle, slugify: true} ]
+ title: [content_method, {method: getTitle} ] # slugify is true by default
+
+ .. code-block: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The ``Topic`` document would then need to implement the methods named above as
follows::
@@ -216,41 +130,41 @@ follows::
/**
* Returns the category object associated with the topic.
*/
- public function getCategory()
- {
- return $this->category;
- }
-
- public function getPublishedDate()
+ public function getCategoryName()
{
- return new \DateTime('2013/04/06');
+ return 'Drinks';
}
public function getTitle()
{
- return "My Topic Title";
+ return 'Coffee';
}
}
-After persisting this object, the route will be created. Of course, you need to make
-the properties editable and then you have a fully working routing system.
+After persisting this object, the route will be created. You will of course
+be wanting to return property values and not static strings, but you get the
+idea.
.. note::
Any mapping applied to an object will also apply to subclasses of that
object. Imagine you have 2 documents, ``ContactPage`` and ``Page``, which
both extend ``AbstractPage``. When you map the ``AbstractPage`` class, it
- will be applied to both documents.
+ will be applied to both documents. You can also use the ``extend`` keyword
+ to achieve the same thing with objects which are not related.
+
+This is just a basic example. You can also configure what should happen when
+a route already exists (confict resolution) and what to do with old routes
+when the generated URI is changed (defunct route handling).
-Provided Providers and Action
------------------------------
+Read more
+---------
-The RoutingAutoBundle comes with a couple path providers and actions by
-default. Read more about them in the other sections:
+* :doc:`token_providers`
+* :doc:`conflict_resolvers`
+* :doc:`defunct_route_handlers`
+* :doc:`customization`
-* :doc:`providers`
-* :doc:`exists_actions`
-* :doc:`not_exists_actions`
Customization
-------------
diff --git a/bundles/routing_auto/not_exists_actions.rst b/bundles/routing_auto/not_exists_actions.rst
deleted file mode 100644
index 3ce12694..00000000
--- a/bundles/routing_auto/not_exists_actions.rst
+++ /dev/null
@@ -1,60 +0,0 @@
-.. index::
- single: Not Exists Actions; RoutingAutoBundle
-
-Path not Exists Actions
------------------------
-
-These are the default actions available to take if the path provided by a
-``path_provider`` does not exist.
-
-create
-~~~~~~
-
-The ``create`` action will create the path.
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- not_exists_action: create
-
- .. code-block:: xml
-
-
-
- .. code-block:: php
-
- array(
- // ...
- 'not_exists_action' => 'create',
- );
-
-.. note::
-
- **Currently** all routes provided by the content path builder units will be
- created as ``Generic`` documents, whilst the content name route will be
- created as an ``AutoRoute`` document.
-
-throw_exception
-~~~~~~~~~~~~~~~
-
-This action will throw an exception if the route provided by the path provider
-does not exist. You should take this action if you are sure that the route
-*should* exist.
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- not_exists_action: throw_exception
-
- .. code-block:: xml
-
-
-
- .. code-block:: php
-
- array(
- // ...
- 'not_exists_action' => 'throw_exception',
- );
diff --git a/bundles/routing_auto/providers.rst b/bundles/routing_auto/providers.rst
deleted file mode 100644
index fb4fead3..00000000
--- a/bundles/routing_auto/providers.rst
+++ /dev/null
@@ -1,200 +0,0 @@
-.. index::
- single: Path Providers; RoutingAutoBundle
-
-Path Providers
---------------
-
-Path providers specify a target path which is used by the subsequent path
-actions to provide the actual route documents.
-
-**Base** providers must be the first configured as the first builder in the
-content path chain. This is because the paths that they provide correspond
-directly to an existing path, i.e. they have an absolute reference.
-
-specified (base provider)
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This is the most basic path provider and allows you to specify an exact
-(fixed) path.
-
-Options
-.......
-
-* ``path`` - **required** The path to provide.
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- provider: [specified, { path: this/is/a/path }]
-
- .. code-block:: xml
-
-
-
-
-
- .. code-block:: php
-
- array(
- // ...
- 'provider' => array('specified', array('path' => 'this/is/a/path')),
- );
-
-.. caution::
-
- You should never specifiy absolute paths in the auto route system. If the
- builder unit is the first content path chain it is understood that it is
- the base of an absolute path.
-
-content_object (base provider)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The content object provider will try and provide a path from an object
-implementing ``RouteReferrersInterface`` provided by a designated method on the
-content document. For example, if you have a ``Topic`` class, which has a
-``getCategory`` method, using this provider you can tell the ``Topic`` auto route
-to use the route of the category as a base.
-
-So basically, if your category document has a path of ``/this/is/my/category``,
-you can use this path as the base of your ``Category`` auto-route.
-
-Options
-.......
-
- - ``method``: **required** Method used to return the document whose route path you wish to use.
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- provider: [content_object, { method: getCategory }]
-
- .. code-block:: xml
-
-
-
-
-
- .. code-block:: php
-
- array(
- // ...
- 'provider' => array('content_object', array('method' => 'getCategory')),
- );
-
-.. note::
-
- At the time of writing translated objects are not supported. But a patch
- is already created for this feature.
-
-content_method
-~~~~~~~~~~~~~~
-
-The ``content_method`` provider allows the content object (e.g. a forum
-``Topic``) to specify a path using one of its methods. This is quite a powerful
-method as it allows the content document to do whatever it can to produce the
-route, the disadvantage is that your content document will have extra code in
-it.
-
-Options
-.......
-
-* ``method``: **required** Method used to return the route name/path/path elements.
-* ``slugify``: If the return value should be slugified, default is ``true``.
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- provider: [content_method, { method: getTitle }]
-
- .. code-block:: xml
-
-
-
-
-
- .. code-block:: php
-
- array(
- // ...
- 'provider' => array('content_method', array('method' => 'getTitle')),
- );
-
-This example will use the existing method "getTitle" of the ``Topic`` document
-to retrieve the title. By default all strings are *slugified*.
-
-The method can return the path either as a single string, an array of path
-elements or an object which can be converted into a string, as shown in the
-following example::
-
- class Topic
- {
- /* Using a string */
- public function getTitle()
- {
- return "This is a topic";
- }
-
- /* Using an array */
- public function getPathElements()
- {
- return array('this', 'is', 'a', 'path');
- }
-
- /* Using an object */
- public function getStringObject()
- {
- $object = ...; // an object which has a __toString() method
-
- return $object;
- }
- }
-
-content_datetime
-~~~~~~~~~~~~~~~~
-
-The ``content_datettime`` provider will provide a path from a ``DateTime``
-object provided by a designated method on the content document.
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- provider: [content_datetime, { method: getDate, date_format: Y/m/d }]
-
- .. code-block:: xml
-
-
-
-
-
-
- .. code-block:: php
-
- array(
- // ...
- 'provider' => array('content_datetime', array(
- 'method' => 'getDate',
- 'date_format' => 'Y/m/d',
- )),
- );
-
-.. note::
-
- This method extends `content_method`_ and inherits the slugify feature.
- Internally, it returns a string using the `DateTime->format()` method. This
- means that you can specify your date in anyway you like and it will be
- automatically slugified. Also, by adding path separators in the
- ``date_format`` you are effectively creating routes for each date component
- as slugify applies to **each element** of the path.
-
-Options
-.......
-
-* ``method``: **required** Method used to return the route name/path/path
- elements.
-* ``slugify``: If the return value should be slugified, default is ``true``.
-* ``date_format``: Any date format accepted by the `DateTime` class, default
- ``Y-m-d``.
diff --git a/bundles/routing_auto/token_providers.rst b/bundles/routing_auto/token_providers.rst
new file mode 100644
index 00000000..809c3f38
--- /dev/null
+++ b/bundles/routing_auto/token_providers.rst
@@ -0,0 +1,127 @@
+.. index::
+ single: Path Providers; RoutingAutoBundle
+
+Token Providers
+---------------
+
+Token providers provide values for the tokens specified in the URI schemas.
+
+content_method
+~~~~~~~~~~~~~~
+
+The ``content_method`` provider allows the content object (e.g. a forum
+``Topic``) to specify a path using one of its methods. This is quite a powerful
+method as it allows the content document to do whatever it can to produce the
+route.
+
+Options
+.......
+
+* ``method``: **required** Method used to return the route name/path/path elements.
+* ``slugify``: If the return value should be slugified, default is ``true``.
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # src/Acme/ForumBundle/Resources/config/routing_auto.yml
+ Acme\ForumBundle\Document\Topic:
+ uri_schema: /my-forum/{title}
+ token_providers:
+ title: [content_method, {method: getTitle} ]
+
+ .. code-block: xml
+
+
+
+
+
+
+
+
+
+
+
+This example will use the existing method "getTitle" of the ``Topic`` document
+to retrieve the title. By default all strings are *slugified*.
+
+Options
+.......
+
+* ``method``: **required** Method used to return the route name/path/path
+ elements.
+* ``slugify``: If the return value should be slugified, default is ``true``.
+
+content_datetime
+~~~~~~~~~~~~~~~~
+
+The ``content_datetime`` provider will provide a path from a ``DateTime``
+object provided by a designated method on the content document.
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # src/Acme/ForumBundle/Resources/config/routing_auto.yml
+ Acme\ForumBundle\Document\Topic:
+ uri_schema: /blog/{date}/my-post
+ token_providers:
+ date: [content_datetime, {method: getDate} ]
+
+ .. code-block: xml
+
+
+
+
+
+
+
+
+
+
+
+Options
+.......
+
+* ``method``: **required** Method used to return the route name/path/path
+ elements.
+* ``slugify``: If the return value should be slugified, default is ``true``.
+* ``date_format``: Any date format accepted by the `DateTime` class, default
+ ``Y-m-d``.
+
+content_locale
+~~~~~~~~~~~~~~
+
+The ``content_locale`` provider will provide the locale (e.g. ``fr``, ``de``,
+etc) from the subject object. It ultimately it determines the locale from the
+storage specific adapter - so it is dependent upon the adapter supporting this
+feature.
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # src/Acme/ForumBundle/Resources/config/routing_auto.yml
+ Acme\ForumBundle\Document\Topic:
+ uri_schema: /blog/{locale}/my-post
+ token_providers:
+ locale: [content_locale ]
+
+ .. code-block: xml
+
+
+
+
+
+
+
+
+
+Options
+.......
+
+* ``method``: **required** Method used to return the route name/path/path
+ elements.
+* ``slugify``: If the return value should be slugified, default is ``true``.
+* ``locale_format``: Any locale format accepted by the `DateTime` class, default
+ ``Y-m-d``.