From a65b7fb3705b0e6d26260e1aab54593f76be77ac Mon Sep 17 00:00:00 2001 From: dantleech Date: Tue, 1 Jul 2014 10:19:11 +0200 Subject: [PATCH 1/4] Updated routing auto documentation for 1.0 --- bundles/routing_auto/conflict_resolvers.rst | 54 +++++ bundles/routing_auto/customization.rst | 203 +++++++++++------- .../routing_auto/defunct_route_handlers.rst | 105 +++++++++ bundles/routing_auto/exists_actions.rst | 67 ------ bundles/routing_auto/introduction.rst | 202 +++++------------ bundles/routing_auto/not_exists_actions.rst | 60 ------ .../{providers.rst => token_providers.rst} | 0 7 files changed, 345 insertions(+), 346 deletions(-) create mode 100644 bundles/routing_auto/conflict_resolvers.rst create mode 100644 bundles/routing_auto/defunct_route_handlers.rst delete mode 100644 bundles/routing_auto/exists_actions.rst delete mode 100644 bundles/routing_auto/not_exists_actions.rst rename bundles/routing_auto/{providers.rst => token_providers.rst} (100%) diff --git a/bundles/routing_auto/conflict_resolvers.rst b/bundles/routing_auto/conflict_resolvers.rst new file mode 100644 index 00000000..613ace72 --- /dev/null +++ b/bundles/routing_auto/conflict_resolvers.rst @@ -0,0 +1,54 @@ +.. index:: + single: Conflict Resolvers; RoutingAutoBundle + +Conflict Resolvers +------------------- + +These are the conflict resolvers which are provided by default by the +RoutingAutoBundle. + +auto_increment +~~~~~~~~~~~~~~ + +The ``auto_increment`` conflict resolver 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. + +.. configuration-block:: + + .. code-block:: yaml + + stdClass: + url_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: + url_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..cf81d08f 100644 --- a/bundles/routing_auto/customization.rst +++ b/bundles/routing_auto/customization.rst @@ -6,51 +6,63 @@ Customization .. _routingauto_customization_pathproviders: -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 +URL 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\UrlContext; + + class FoobarTokenProvider implements TokenProviderInterface { - public function providePath(RouteStack $routeStack) + /** + * {@inheritDoc} + */ + public function provideValue(UrlContext $urlContext, $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 URL to resolve a +conflict:: + + namespace Symfony\Cmf\Component\RoutingAuto\ConflictResolver; + + use Symfony\Cmf\Component\RoutingAuto\ConflictResolverInterface; + use Symfony\Cmf\Component\RoutingAuto\UrlContext; + use Symfony\Cmf\Component\RoutingAuto\Adapter\AdapterInterface; + + class UniqidConflictResolver implements ConflictResolverInterface + { + public function resolveConflict(UrlContext $urlContext) + { + $url = $urlContext->getUrl(); + 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 URL 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\UrlContextCollection; + 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(UrlContextCollection $urlContextCollection) { - throw new CouldNotFindRouteException('/'.$routeStack->getFullPath()); + $referringAutoRouteCollection = $this->adapter->getReferringAutoRoutes($urlContextCollection->getSubjectObject()); + + foreach ($referringAutoRouteCollection as $referringAutoRoute) { + if (false === $urlContextCollection->containsAutoRoute($referringAutoRoute)) { + $newRoute = $urlContextCollection->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..27f82fc7 --- /dev/null +++ b/bundles/routing_auto/defunct_route_handlers.rst @@ -0,0 +1,105 @@ +.. index:: + single: Customization; RoutingAutoBundle + +Defunct Route Handlers +---------------------- + +.. _routingauto_customization_pathproviders: + +When an already-persisted document is updated and the URL 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: + url_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: + url_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/introduction.rst b/bundles/routing_auto/introduction.rst index a8e4c61c..8fe60c0d 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 URL 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 @@ -68,142 +66,62 @@ 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 URL: -.. image:: ../../_images/bundles/routing_auto_post_schema.png +.. code-block:: -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. + https://mywebsite.com/my-forum/drinks/coffee -.. note:: +The RoutingAutoBundle uses a URL schema to define how routes are generated. A +schema for the above URL would look like this (the bundle does not care about +the host or protocol): + +.. code-block:: + + /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: + url_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,37 +134,35 @@ 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. -Provided Providers and Action ------------------------------ +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 URL is changed (defunct route handling). -The RoutingAutoBundle comes with a couple path providers and actions by -default. Read more about them in the other sections: +Token Providers, Conflict Resolvers and Defunct Routes +------------------------------------------------------ * :doc:`providers` * :doc:`exists_actions` 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/token_providers.rst similarity index 100% rename from bundles/routing_auto/providers.rst rename to bundles/routing_auto/token_providers.rst From 03b8e3f2419be97ac223ba5c57d35168596e93a6 Mon Sep 17 00:00:00 2001 From: dantleech Date: Tue, 1 Jul 2014 10:35:28 +0200 Subject: [PATCH 2/4] Added token providers section --- bundles/map.rst.inc | 6 +- bundles/routing_auto/conflict_resolvers.rst | 12 +- bundles/routing_auto/customization.rst | 2 +- .../routing_auto/defunct_route_handlers.rst | 4 +- bundles/routing_auto/index.rst | 7 +- bundles/routing_auto/introduction.rst | 20 +- bundles/routing_auto/token_providers.rst | 223 ++++++------------ 7 files changed, 100 insertions(+), 174 deletions(-) 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 index 613ace72..f65f0386 100644 --- a/bundles/routing_auto/conflict_resolvers.rst +++ b/bundles/routing_auto/conflict_resolvers.rst @@ -2,16 +2,18 @@ single: Conflict Resolvers; RoutingAutoBundle Conflict Resolvers -------------------- +------------------ -These are the conflict resolvers which are provided by default by the -RoutingAutoBundle. +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 ``my/path`` would first become ``my/path-1`` and if that path *also* +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. @@ -34,7 +36,7 @@ it finds a path which *doesn't* exist. throw_exception ~~~~~~~~~~~~~~~ -The ``throw_exception`` efficiently resolves conflicts by throwing exceptions. +The ``throw_exception`` efficiently "resolves" conflicts by throwing exceptions. This is the default action. .. configuration-block:: diff --git a/bundles/routing_auto/customization.rst b/bundles/routing_auto/customization.rst index cf81d08f..492ad0b0 100644 --- a/bundles/routing_auto/customization.rst +++ b/bundles/routing_auto/customization.rst @@ -4,7 +4,7 @@ Customization ------------- -.. _routingauto_customization_pathproviders: +.. _routingauto_customization_tokenproviders: Token Providers ~~~~~~~~~~~~~~~ diff --git a/bundles/routing_auto/defunct_route_handlers.rst b/bundles/routing_auto/defunct_route_handlers.rst index 27f82fc7..8e2f6bde 100644 --- a/bundles/routing_auto/defunct_route_handlers.rst +++ b/bundles/routing_auto/defunct_route_handlers.rst @@ -4,7 +4,7 @@ Defunct Route Handlers ---------------------- -.. _routingauto_customization_pathproviders: +.. _routingauto_customization_defunctroutehandlers: When an already-persisted document is updated and the URL generated by the RoutingAuto system is changed, a *new* route is always created. Defunct route @@ -64,8 +64,6 @@ path. - - For the redirect to work you will also need to configure a redirect controller in the ``cmf_routing`` configuration:: 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 8fe60c0d..32e3fb41 100644 --- a/bundles/routing_auto/introduction.rst +++ b/bundles/routing_auto/introduction.rst @@ -69,17 +69,13 @@ Usage Imagine you have a fictional forum application and that you want to access the forum topic with the following fictional URL: -.. code-block:: - - https://mywebsite.com/my-forum/drinks/coffee +- ``https://mywebsite.com/my-forum/drinks/coffee`` The RoutingAutoBundle uses a URL schema to define how routes are generated. A schema for the above URL would look like this (the bundle does not care about the host or protocol): -.. code-block:: - - /my-forum/{category}/{title} +- ``/my-forum/{category}/{title}`` You can see that ``my-forum`` is static (it will not change) but that ``drinks`` has been replaced with ``{category}`` and ``coffee`` with @@ -161,12 +157,14 @@ 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 URL is changed (defunct route handling). -Token Providers, Conflict Resolvers and Defunct Routes ------------------------------------------------------- +Read more +--------- + +* :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/token_providers.rst b/bundles/routing_auto/token_providers.rst index fb4fead3..a1fde2dd 100644 --- a/bundles/routing_auto/token_providers.rst +++ b/bundles/routing_auto/token_providers.rst @@ -1,92 +1,10 @@ .. index:: single: Path Providers; RoutingAutoBundle -Path Providers --------------- +Token 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. +Token providers provide values for the tokens specified in the URL schemas. content_method ~~~~~~~~~~~~~~ @@ -94,8 +12,7 @@ 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. +route. Options ....... @@ -107,88 +24,98 @@ Options .. code-block:: yaml - provider: [content_method, { method: getTitle }] - - .. code-block:: xml - - - + # src/Acme/ForumBundle/Resources/config/routing_auto.yml + Acme\ForumBundle\Document\Topic: + url_schema: /my-forum/{title} + token_providers: + title: [content_method, {method: getTitle} ] - .. code-block:: php + .. code-block: xml - 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; - } - } +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_datettime`` provider will provide a path from a ``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 - provider: [content_datetime, { method: getDate, date_format: Y/m/d }] + # src/Acme/ForumBundle/Resources/config/routing_auto.yml + Acme\ForumBundle\Document\Topic: + url_schema: /blog/{date}/my-post + token_providers: + date: [content_datetime, {method: getDate} ] + + .. code-block: xml - .. code-block:: xml + + + + + + + + + - - +Options +....... - .. code-block:: php +* ``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``. - array( - // ... - 'provider' => array('content_datetime', array( - 'method' => 'getDate', - 'date_format' => 'Y/m/d', - )), - ); +content_locale +~~~~~~~~~~~~~~ -.. note:: +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. - 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. +.. configuration-block:: + + .. code-block:: yaml + + # src/Acme/ForumBundle/Resources/config/routing_auto.yml + Acme\ForumBundle\Document\Topic: + url_schema: /blog/{locale}/my-post + token_providers: + locale: [content_locale ] + + .. code-block: xml + + + + + + + + Options ....... @@ -196,5 +123,5 @@ 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 +* ``locale_format``: Any locale format accepted by the `DateTime` class, default ``Y-m-d``. From 81c51b320217de77fd3c1b7af3f5b236589a31b0 Mon Sep 17 00:00:00 2001 From: dantleech Date: Sat, 19 Jul 2014 18:56:15 +0200 Subject: [PATCH 3/4] Updated extensions for Python3 --- _exts/sensio/sphinx/configurationblock.py | 1 - _exts/sensio/sphinx/phpcode.py | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) 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 From 548109c9c43b4ecd12edf77f8350ab9571562a5f Mon Sep 17 00:00:00 2001 From: dantleech Date: Sun, 10 Aug 2014 18:34:00 +0200 Subject: [PATCH 4/4] Renamed URL to URI --- bundles/routing_auto/conflict_resolvers.rst | 8 +++--- bundles/routing_auto/customization.rst | 28 +++++++++---------- .../routing_auto/defunct_route_handlers.rst | 10 +++---- bundles/routing_auto/introduction.rst | 22 +++++++-------- bundles/routing_auto/token_providers.rst | 14 +++++----- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/bundles/routing_auto/conflict_resolvers.rst b/bundles/routing_auto/conflict_resolvers.rst index f65f0386..eec96aba 100644 --- a/bundles/routing_auto/conflict_resolvers.rst +++ b/bundles/routing_auto/conflict_resolvers.rst @@ -22,13 +22,13 @@ it finds a path which *doesn't* exist. .. code-block:: yaml stdClass: - url_schema: /cmf/blog + uri_schema: /cmf/blog conflict_resolver: auto_increment .. code-block:: xml - + @@ -44,13 +44,13 @@ This is the default action. .. code-block:: yaml stdClass: - url_schema: /cmf/blog + 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 492ad0b0..cd3d123c 100644 --- a/bundles/routing_auto/customization.rst +++ b/bundles/routing_auto/customization.rst @@ -10,7 +10,7 @@ Token Providers ~~~~~~~~~~~~~~~ The goal of a ``TokenProvider`` class is to provide values for tokens in the -URL schema. Such values can be derived form the object for which the route +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). @@ -21,14 +21,14 @@ The following token provider will simply provide the value "foobar":: use Symfony\Cmf\Component\RoutingAuto\TokenProviderInterface; use Symfony\Component\OptionsResolver\OptionsResolverInterface; - use Symfony\Cmf\Component\RoutingAuto\UrlContext; + use Symfony\Cmf\Component\RoutingAuto\UriContext; class FoobarTokenProvider implements TokenProviderInterface { /** * {@inheritDoc} */ - public function provideValue(UrlContext $urlContext, $options) + public function provideValue(UriContext $uriContext, $options) { return 'foobar'; } @@ -52,7 +52,7 @@ To use the path provider you must register it in the container and add the acme_cms.token_provider.foobar: class: Acme\CmsBundle\RoutingAuto\PathProvider\FoobarTokenProvider tags: - - { name: cmf_routing_auto.token_provider, alias: "foobar"} + - { name: cmf_routing_auto.token_provider, alias: "foobar" } .. code-block:: xml @@ -84,20 +84,20 @@ 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 URL to resolve a +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\UrlContext; + use Symfony\Cmf\Component\RoutingAuto\UriContext; use Symfony\Cmf\Component\RoutingAuto\Adapter\AdapterInterface; class UniqidConflictResolver implements ConflictResolverInterface { - public function resolveConflict(UrlContext $urlContext) + public function resolveConflict(UriContext $uriContext) { - $url = $urlContext->getUrl(); + $uri = $uriContext->getUri(); return sprintf('%s-%s', uniqid()); } } @@ -139,7 +139,7 @@ Defunct Route Handlers ~~~~~~~~~~~~~~~~~~~~~~ Defunct Route Handlers decide what happens to old routes when an object is -updated and its generated URL changes. +updated and its generated URI changes. They are not all-together trivial - the following handler removes old routes and is the default handler:: @@ -147,7 +147,7 @@ the default handler:: namespace Symfony\Cmf\Component\RoutingAuto\DefunctRouteHandler; use Symfony\Cmf\Component\RoutingAuto\DefunctRouteHandlerInterface; - use Symfony\Cmf\Component\RoutingAuto\UrlContextCollection; + use Symfony\Cmf\Component\RoutingAuto\UriContextCollection; use Symfony\Cmf\Component\RoutingAuto\Adapter\AdapterInterface; class RemoveDefunctRouteHandler implements DefunctRouteHandlerInterface @@ -159,13 +159,13 @@ the default handler:: $this->adapter = $adapter; } - public function handleDefunctRoutes(UrlContextCollection $urlContextCollection) + public function handleDefunctRoutes(UriContextCollection $uriContextCollection) { - $referringAutoRouteCollection = $this->adapter->getReferringAutoRoutes($urlContextCollection->getSubjectObject()); + $referringAutoRouteCollection = $this->adapter->getReferringAutoRoutes($uriContextCollection->getSubjectObject()); foreach ($referringAutoRouteCollection as $referringAutoRoute) { - if (false === $urlContextCollection->containsAutoRoute($referringAutoRoute)) { - $newRoute = $urlContextCollection->getAutoRouteByTag($referringAutoRoute->getAutoRouteTag()); + if (false === $uriContextCollection->containsAutoRoute($referringAutoRoute)) { + $newRoute = $uriContextCollection->getAutoRouteByTag($referringAutoRoute->getAutoRouteTag()); $this->adapter->migrateAutoRouteChildren($referringAutoRoute, $newRoute); $this->adapter->removeAutoRoute($referringAutoRoute); diff --git a/bundles/routing_auto/defunct_route_handlers.rst b/bundles/routing_auto/defunct_route_handlers.rst index 8e2f6bde..caced977 100644 --- a/bundles/routing_auto/defunct_route_handlers.rst +++ b/bundles/routing_auto/defunct_route_handlers.rst @@ -6,7 +6,7 @@ Defunct Route Handlers .. _routingauto_customization_defunctroutehandlers: -When an already-persisted document is updated and the URL generated by the +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. @@ -21,13 +21,13 @@ action. .. code-block:: yaml stdClass: - url_schema: /cmf/blog + uri_schema: /cmf/blog defunct_route_handler: remove .. code-block:: xml - + @@ -53,13 +53,13 @@ path. .. code-block:: yaml stdClass: - url_schema: /cmf/blog + uri_schema: /cmf/blog defunct_route_handler: leave_redirect .. code-block:: xml - + diff --git a/bundles/routing_auto/introduction.rst b/bundles/routing_auto/introduction.rst index 32e3fb41..98b31a34 100644 --- a/bundles/routing_auto/introduction.rst +++ b/bundles/routing_auto/introduction.rst @@ -6,7 +6,7 @@ RoutingAutoBundle ================= The RoutingAutoBundle allows you to automatically persist routes when -documents are persisted based on URL schemas and contextual information. +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 @@ -28,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 @@ -49,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; @@ -67,12 +67,12 @@ Usage ----- Imagine you have a fictional forum application and that you want to access the -forum topic with the following fictional URL: +forum topic with the following fictional URI: - ``https://mywebsite.com/my-forum/drinks/coffee`` -The RoutingAutoBundle uses a URL schema to define how routes are generated. A -schema for the above URL would look like this (the bundle does not care about +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): - ``/my-forum/{category}/{title}`` @@ -98,7 +98,7 @@ document could be defined as follows: # src/Acme/ForumBundle/Resources/config/routing_auto.yml Acme\ForumBundle\Document\Topic: - url_schema: /my-forum/{category}/{title} + 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 @@ -108,7 +108,7 @@ document could be defined as follows: - + @@ -155,7 +155,7 @@ idea. 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 URL is changed (defunct route handling). +when the generated URI is changed (defunct route handling). Read more --------- diff --git a/bundles/routing_auto/token_providers.rst b/bundles/routing_auto/token_providers.rst index a1fde2dd..809c3f38 100644 --- a/bundles/routing_auto/token_providers.rst +++ b/bundles/routing_auto/token_providers.rst @@ -4,7 +4,7 @@ Token Providers --------------- -Token providers provide values for the tokens specified in the URL schemas. +Token providers provide values for the tokens specified in the URI schemas. content_method ~~~~~~~~~~~~~~ @@ -26,7 +26,7 @@ Options # src/Acme/ForumBundle/Resources/config/routing_auto.yml Acme\ForumBundle\Document\Topic: - url_schema: /my-forum/{title} + uri_schema: /my-forum/{title} token_providers: title: [content_method, {method: getTitle} ] @@ -35,7 +35,7 @@ Options - + @@ -64,7 +64,7 @@ object provided by a designated method on the content document. # src/Acme/ForumBundle/Resources/config/routing_auto.yml Acme\ForumBundle\Document\Topic: - url_schema: /blog/{date}/my-post + uri_schema: /blog/{date}/my-post token_providers: date: [content_datetime, {method: getDate} ] @@ -73,7 +73,7 @@ object provided by a designated method on the content document. - + @@ -103,7 +103,7 @@ feature. # src/Acme/ForumBundle/Resources/config/routing_auto.yml Acme\ForumBundle\Document\Topic: - url_schema: /blog/{locale}/my-post + uri_schema: /blog/{locale}/my-post token_providers: locale: [content_locale ] @@ -112,7 +112,7 @@ feature. - +