--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/source/traverser.rst Thu Dec 06 08:24:10 2018 +0100
@@ -0,0 +1,47 @@
+.. _traverser:
+
+PyAMS namespace traverser
+=========================
+
+PyAMS_utils provide a custom URL traverser, defined in package :py:mod:`pyams_utils.traversing`.
+
+The :py:class:`NamespaceTraverser <pyams_utils.traversing.NamespaceTraverser>` is a custom traverser based on default
+Pyramid's *ResourceTreeAdapter*, but it adds the ability to use *namespaces*. Inherited from *Zope3* concept, a
+namespace is a resource path element starting with the « *++* » characters, like this:
+
+.. code-block:: none
+
+ http://localhost:5432/folder/content/++ns++argument/@@view.html
+
+In this sample, *ns* is the namespace name. When the traverser detects a namespace, it looks for several named
+adapters (or multi-adapters) to the :py:class:`ITraversable <zope.traversing.interfaces.ITraversable>` interface
+defined in *zope.traversing* package. Adapters lookup with name *ns* is done for the current *context* and *request*,
+then only for the context and finally for the request, in this order. If a traversing adapter is found, it's
+:py:func:`traverse` method is called, with the *attr* value as first argument, and the rest of the traversal stack
+as second one.
+
+This is for example how a custom *etc* namespace traverser is defined:
+
+.. code-block:: python
+
+ from pyams_utils.interfaces.site import ISiteRoot
+ from zope.traversing.interfaces import ITraversable
+
+ from pyams_utils.adapter import adapter_config, ContextAdapter
+
+ @adapter_config(name='etc', context=ISiteRoot, provides=ITraversable)
+ class SiteRootEtcTraverser(ContextAdapter):
+ """Site root ++etc++ namespace traverser"""
+
+ def traverse(self, name, furtherpath=None):
+ if name == 'site':
+ return self.context.getSiteManager()
+ raise NotFound
+
+By using an URL like '++etc++site' on your site root, you can then get access to your local site manager.
+
+*argument* is not mandatory for the namespace traverser. If it is not provided, the *traverse* method is called with
+an empty string (with is a default adapter name) as first argument.
+
+Several PyAMS components use custom traversal adapters. For example, getting thumbnails from an image is done
+through a traversing adapter, which results in nicer URLs than when using classic URLs with arguments...