# HG changeset patch # User Damien Correia # Date 1545403949 -3600 # Node ID 9ab9f762abed2eb4f1c34ac65336f8fc6fb57f91 # Parent df3106def670ab9aebd8ce2d91c6e7de153720a2 Updated doc diff -r df3106def670 -r 9ab9f762abed src/source/dev_guide/internals.rst --- a/src/source/dev_guide/internals.rst Fri Dec 21 15:48:43 2018 +0100 +++ b/src/source/dev_guide/internals.rst Fri Dec 21 15:52:29 2018 +0100 @@ -13,6 +13,56 @@ Namespaces ---------- +.. _traverser: + +PyAMS namespace traverser +------------------------- + + +PyAMS_utils provide a custom URL traverser, defined in package :py:mod:`pyams_utils.traversing`. + +The :py:class:`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 ` 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... + + .. _renderer: diff -r df3106def670 -r 9ab9f762abed src/source/dev_guide/traverser.rst --- a/src/source/dev_guide/traverser.rst Fri Dec 21 15:48:43 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -.. _traverser: - -PyAMS namespace traverser -========================= - -PyAMS_utils provide a custom URL traverser, defined in package :py:mod:`pyams_utils.traversing`. - -The :py:class:`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 ` 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... diff -r df3106def670 -r 9ab9f762abed src/source/dev_guide/utilities.rst --- a/src/source/dev_guide/utilities.rst Fri Dec 21 15:48:43 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -.. _utilities: - -Custom PyAMS utilities -====================== - -PyAMS_utils provides a small set of utilities. You can create some of them as global utilities registered in -the global components registry; other ones can be created manually by a site administrator and -are then registered automatically. - - -Server timezone ---------------- - -To manage timezones correctly, and display datetimes based on current server timezone, all datetimes should -be defined and stored in UTC. - -PyAMS_utils provides a :py:class:`ServerTimezoneUtility ` which -allows you to assign a default timezone to your server. - -To display a datetime with correct timezone, you can use the :py:func:`tztime ` function, -which assign server timezone to the given parameter: - -.. code-block:: python - - from datetime import datetime - from pyams_utils.timezone import tztime - - now = datetime.utcnow() - my_date = tztime(now) # converts *now* to server timezone - -We could imagine that datetimes could be displayed with current user timezone. But it's quite impossible to know -the user timazone from a server request. The only options are: - -- you ask an authenticated user to update a timezone setting in his profile - -- you can include Javascript libraries which will try to detect browser timezone from their computer configuration, and - do an AJAX request to update data in their session. - -That should require an update of :py:func:`tzinfo` adapter to get timezone info from session, request or user profile. - -