Merge branch 'master' of github.com:Pylons/pyramid
| | |
| | | For example, the asset specification |
| | | ``my.package:static/baz.css`` identifies the file named |
| | | ``baz.css`` in the ``static`` subdirectory of the ``my.package`` |
| | | Python :term:`package`. See :ref:`asset_specifications` for more |
| | | Python :term:`package`. See :ref:`asset_specifications` for more |
| | | info. |
| | | |
| | | package |
| | |
| | | |
| | | module |
| | | A Python source file; a file on the filesystem that typically ends with |
| | | the extension ``.py`` or ``.pyc``. Modules often live in a |
| | | the extension ``.py`` or ``.pyc``. Modules often live in a |
| | | :term:`package`. |
| | | |
| | | project |
| | |
| | | a :term:`context` resource. A permission is associated with a view name |
| | | and a resource type by the developer. Resources are decorated with |
| | | security declarations (e.g. an :term:`ACL`), which reference these |
| | | tokens also. Permissions are used by the active to security policy to |
| | | tokens also. Permissions are used by the active security policy to |
| | | match the view permission against the resources's statements about which |
| | | permissions are granted to which principal in a context in order to to |
| | | permissions are granted to which principal in a context in order to |
| | | answer the question "is this user allowed to do this". Examples of |
| | | permissions: ``read``, or ``view_blog_entries``. |
| | | |
| | |
| | | METAL |
| | | `Macro Expansion for TAL <http://wiki.zope.org/ZPT/METAL>`_, a |
| | | part of :term:`ZPT` which makes it possible to share common look |
| | | and feel between templates. |
| | | and feel between templates. |
| | | |
| | | Genshi |
| | | An `XML templating language <http://pypi.python.org/pypi/Genshi/>`_ |
| | | by Christopher Lenz. |
| | | |
| | | Jinja2 |
| | | A `text templating language <http://jinja.pocoo.org/2/>`_ by Armin |
| | | A `text templating language <http://jinja.pocoo.org/2/>`_ by Armin |
| | | Ronacher. |
| | | |
| | | Routes |
| | |
| | | root |
| | | The object at which :term:`traversal` begins when :app:`Pyramid` |
| | | searches for a :term:`context` resource (for :term:`URL Dispatch`, the |
| | | root is *always* the context resource unless the ``traverse=`` argument |
| | | root is *always* the context resource unless the ``traverse=`` argument |
| | | is used in route configuration). |
| | | |
| | | subpath |
| | |
| | | ZCML |
| | | `Zope Configuration Markup Language |
| | | <http://www.muthukadan.net/docs/zca.html#zcml>`_, an XML dialect |
| | | used by Zope and :term:`pyramid_zcml` for configuration tasks. |
| | | used by Zope and :term:`pyramid_zcml` for configuration tasks. |
| | | |
| | | ZCML directive |
| | | A ZCML "tag" such as ``<view>`` or ``<route>``. |
| | |
| | | http://docs.python.org/distutils/index.html for more information. |
| | | :term:`setuptools` is actually an *extension* of the Distutils. |
| | | |
| | | |
| | | |
| | | |
| | |
| | | Root factories related to a route were explained previously within |
| | | :ref:`route_factories`. Both the global root factory and default |
| | | root factory were explained previously within |
| | | :ref:`the_resource_tree`. |
| | | :ref:`the_resource_tree`. |
| | | |
| | | .. _using_traverse_in_a_route_pattern: |
| | | |
| | |
| | | have been invoked in a "pure" traversal-based application. |
| | | |
| | | Let's assume there is no *global* :term:`root factory` configured in |
| | | this application. The *default* :term:`root factory` cannot be traversed: |
| | | this application. The *default* :term:`root factory` cannot be traversed: |
| | | it has no useful ``__getitem__`` method. So we'll need to associate |
| | | this route configuration with a custom root factory in order to |
| | | create a useful hybrid application. To that end, let's imagine that |
| | |
| | | def __getitem__(self, name): |
| | | return self.subobjects[name] |
| | | |
| | | root = Traversable( |
| | | {'a':Resource({'b':Resource({'c':Resource({})})})} |
| | | root = Resource( |
| | | {'a': Resource({'b': Resource({'c': Resource({})})})} |
| | | ) |
| | | |
| | | def root_factory(request): |
| | |
| | | .. code-block:: python |
| | | :linenos: |
| | | |
| | | config.add_route('home', '{foo}/{bar}/*traverse', |
| | | config.add_route('home', '{foo}/{bar}/*traverse', |
| | | factory='mypackage.routes.root_factory') |
| | | |
| | | The ``factory`` above points at the function we've defined. It will return |
| | | an instance of the ``Traversable`` class as a root object whenever this route |
| | | is matched. Instances of the``Resource`` class can be used for tree |
| | | is matched. Instances of the ``Resource`` class can be used for tree |
| | | traversal because they have a ``__getitem__`` method that does something |
| | | nominally useful. Since traversal uses ``__getitem__`` to walk the resources |
| | | of a resource tree, using traversal against the root resource implied by our |
| | |
| | | |
| | | .. note:: |
| | | |
| | | We could have also used our ``root_factory`` callable as the |
| | | We could have also used our ``root_factory`` function as the |
| | | ``root_factory`` argument of the |
| | | :class:`~pyramid.config.Configurator` constructor, instead |
| | | of associating it with a particular route inside the route's |
| | |
| | | If the URL that matched a route with the pattern ``{foo}/{bar}/*traverse``, |
| | | is ``http://example.com/one/two/a/b/c``, the traversal path used |
| | | against the root object will be ``a/b/c``. As a result, |
| | | :app:`Pyramid` will attempt to traverse through the edges ``a``, |
| | | ``b``, and ``c``, beginning at the root object. |
| | | :app:`Pyramid` will attempt to traverse through the edges ``'a'``, |
| | | ``'b'``, and ``'c'``, beginning at the root object. |
| | | |
| | | In our above example, this particular set of traversal steps will mean that |
| | | the :term:`context` resource of the view would be the ``Traversable`` object |
| | | we've named ``c`` in our bogus resource tree and the :term:`view name` |
| | | the :term:`context` resource of the view would be the ``Resource`` object |
| | | we've named ``'c'`` in our bogus resource tree and the :term:`view name` |
| | | resulting from traversal will be the empty string; if you need a refresher |
| | | about why this outcome is presumed, see :ref:`traversal_algorithm`. |
| | | |
| | |
| | | .. code-block:: python |
| | | :linenos: |
| | | |
| | | config.add_route('home', '{foo}/{bar}/*traverse', |
| | | config.add_route('home', '{foo}/{bar}/*traverse', |
| | | factory='mypackage.routes.root_factory') |
| | | config.add_view('mypackage.views.myview', route_name='home') |
| | | |
| | |
| | | .. code-block:: python |
| | | :linenos: |
| | | |
| | | config.add_route('home', '{foo}/{bar}/*traverse', |
| | | config.add_route('home', '{foo}/{bar}/*traverse', |
| | | factory='mypackage.routes.root_factory') |
| | | config.add_view('mypackage.views.myview', name='home') |
| | | config.add_view('mypackage.views.another_view', name='another', |
| | | route_name='home') |
| | | config.add_view('mypackage.views.myview', route_name='home') |
| | | config.add_view('mypackage.views.another_view', route_name='home', |
| | | name='another') |
| | | |
| | | The ``add_view`` call for ``mypackage.views.another_view`` above names a |
| | | different view and, more importantly, a different :term:`view name`. The |
| | |
| | | :linenos: |
| | | |
| | | config.add_route('abc', '/articles/{article}/edit', |
| | | traverse='/articles/{article}') |
| | | traverse='/{article}') |
| | | |
| | | The syntax of the ``traverse`` argument is the same as it is for |
| | | ``pattern``. |
| | | |
| | | If, as above, the ``pattern`` provided is ``articles/{article}/edit``, |
| | | If, as above, the ``pattern`` provided is ``/articles/{article}/edit``, |
| | | and the ``traverse`` argument provided is ``/{article}``, when a |
| | | request comes in that causes the route to match in such a way that the |
| | | ``article`` match value is ``1`` (when the request URI is |
| | |
| | | These scaffolds are rendered using the :term:`PasteDeploy` ``paster`` script. |
| | | |
| | | .. index:: |
| | | single: scaffolds |
| | | single: scaffolds |
| | | single: pyramid_starter scaffold |
| | | single: pyramid_zodb scaffold |
| | | single: pyramid_alchemy scaffold |
| | |
| | | ``pyramid_zodb`` |
| | | URL mapping via :term:`traversal` and persistence via :term:`ZODB`. |
| | | |
| | | ``pyramid_routesalchemy`` |
| | | ``pyramid_routesalchemy`` |
| | | URL mapping via :term:`URL dispatch` and persistence via |
| | | :term:`SQLAlchemy` |
| | | |
| | |
| | | .. code-block:: text |
| | | |
| | | [chrism@vitaminf shellenv]$ ../bin/paster pshell development.ini MyProject |
| | | Python 2.4.5 (#1, Aug 29 2008, 12:27:37) |
| | | Python 2.4.5 (#1, Aug 29 2008, 12:27:37) |
| | | [GCC 4.0.1 (Apple Inc. build 5465)] on darwin |
| | | Type "help" for more information. "root" is the Pyramid app root object, |
| | | "registry" is the Pyramid registry object. |
| | |
| | | default_locale_name = en |
| | | |
| | | [pipeline:main] |
| | | pipeline = |
| | | pipeline = |
| | | egg:WebError#evalerror |
| | | MyProject |
| | | |
| | |
| | | |
| | | .. note:: |
| | | |
| | | In general, :app:`Pyramid` applications generated from scaffolds |
| | | In general, :app:`Pyramid` applications generated from scaffolds |
| | | should be threading-aware. It is not required that a :app:`Pyramid` |
| | | application be nonblocking as all application code will run in its own |
| | | thread, provided by the server you're using. |
| | |
| | | Such a section should consists of global parameters that are shared by all |
| | | the applications, servers and :term:`middleware` defined within the |
| | | configuration file. The values in a ``[DEFAULT]`` section will be passed |
| | | to your application's ``main`` function as ``global_values`` (see |
| | | to your application's ``main`` function as ``global_config`` (see |
| | | the reference to the ``main`` function in :ref:`init_py`). |
| | | |
| | | ``production.ini`` |
| | |
| | | .. code-block:: python |
| | | :linenos: |
| | | |
| | | from pyramid.response import Response |
| | | from pyramid.view import view_config |
| | | |
| | | @view_config(renderer='json') |
| | |
| | | .. code-block:: python |
| | | :linenos: |
| | | |
| | | config.add_view('myproject.views.hello_world', |
| | | config.add_view('myproject.views.hello_world', |
| | | name='hello', |
| | | context='myproject.resources.Hello', |
| | | renderer='json') |
| | | |
| | | |
| | | |
| | | Views which use the JSON renderer can vary non-body response attributes by |
| | | using the api of the ``request.response`` attribute. See |
| | |
| | | If the ``renderer`` attribute of a view configuration is an absolute path or |
| | | a :term:`asset specification` which has a final path element with a filename |
| | | extension of ``.txt``, the :term:`Chameleon` text renderer is used. See |
| | | :ref:`chameleon_zpt_templates` for more information about Chameleon text |
| | | :ref:`chameleon_text_templates` for more information about Chameleon text |
| | | templates. |
| | | |
| | | The behavior of these renderers is the same, except for the engine |
| | |
| | | |
| | | Before passing keywords to the template, the keyword arguments derived from |
| | | the dictionary returned by the view are augmented. The callable object -- |
| | | whatever object was used to define the ``view`` -- will be automatically |
| | | whatever object was used to define the view -- will be automatically |
| | | inserted into the set of keyword arguments passed to the template as the |
| | | ``view`` keyword. If the view callable was a class, the ``view`` keyword |
| | | will be an instance of that class. Also inserted into the keywords passed to |
| | |
| | | The ``Mako`` template renderer renders views using a Mako template. When |
| | | used, the view must return a Response object or a Python *dictionary*. The |
| | | dictionary items will then be used in the global template space. If the view |
| | | callable returns anything but a Response object, or a dictionary, an error |
| | | callable returns anything but a Response object or a dictionary, an error |
| | | will be raised. |
| | | |
| | | When using a ``renderer`` argument to a :term:`view configuration` to specify |
| | |
| | | |
| | | class RendererFactory: |
| | | def __init__(self, info): |
| | | """ Constructor: info will be an object having the the |
| | | """ Constructor: info will be an object having the |
| | | following attributes: name (the renderer name), package |
| | | (the package that was 'current' at the time the |
| | | renderer was registered), type (the renderer type |
| | | name), registry (the current application registry) and |
| | | settings (the deployment settings dictionary). """ |
| | | settings (the deployment settings dictionary). """ |
| | | |
| | | def __call__(self, value, system): |
| | | """ Call a the renderer implementation with the value |
| | | """ Call the renderer implementation with the value |
| | | and the system value passed in as arguments and return |
| | | the result (a string or unicode object). The value is |
| | | the return value of a view. The system value is a |
| | |
| | | |
| | | There are essentially two different kinds of renderer factories: |
| | | |
| | | - A renderer factory which expects to accept a :term:`asset |
| | | - A renderer factory which expects to accept an :term:`asset |
| | | specification`, or an absolute path, as the ``name`` attribute of the |
| | | ``info`` object fed to its constructor. These renderer factories are |
| | | registered with a ``name`` value that begins with a dot (``.``). These |
| | |
| | | .. code-block:: python |
| | | :linenos: |
| | | |
| | | config.add_renderer(name='.jinja2', |
| | | config.add_renderer(name='.jinja2', |
| | | factory='my.package.MyJinja2Renderer') |
| | | |
| | | Adding the above code to your application startup will allow you to use the |
| | |
| | | set as ``renderer=`` in the view configuration. |
| | | |
| | | Changing an Existing Renderer |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | You can associate more than one filename extension with the same existing |
| | | renderer implementation as necessary if you need to use a different file |
| | |
| | | def set_xmlrpc_params(event): |
| | | request = event.request |
| | | if (request.content_type == 'text/xml' |
| | | and request.method == 'POST' |
| | | and not 'soapaction' in request.headers |
| | | and not 'x-pyramid-avoid-xmlrpc' in request.headers): |
| | | and request.method == 'POST' |
| | | and not 'soapaction' in request.headers |
| | | and not 'x-pyramid-avoid-xmlrpc' in request.headers): |
| | | params, method = parse_xmlrpc_request(request) |
| | | request.xmlrpc_params, request.xmlrpc_method = params, method |
| | | request.is_xmlrpc = True |
| | |
| | | class Resource(dict): |
| | | pass |
| | | |
| | | root = Resource({'a':Resource({'b':Resource({'c':Resource()})})}) |
| | | root = Resource({'a': Resource({'b': Resource({'c': Resource()})})}) |
| | | |
| | | The resource tree we've created above is represented by a dictionary-like |
| | | root object which has a single child named ``a``. ``a`` has a single child |
| | | named ``b``, and ``b`` has a single child named ``c``, which has no children. |
| | | It is therefore possible to access ``c`` like so: |
| | | root object which has a single child named ``'a'``. ``'a'`` has a single child |
| | | named ``'b'``, and ``'b'`` has a single child named ``'c'``, which has no |
| | | children. It is therefore possible to access the ``'c'`` leaf resource like so: |
| | | |
| | | .. code-block:: python |
| | | :linenos: |
| | |
| | | root['a']['b']['c'] |
| | | |
| | | If you returned the above ``root`` object from a :term:`root factory`, the |
| | | path ``/a/b/c`` would find the ``c`` object in the resource tree as the |
| | | path ``/a/b/c`` would find the ``'c'`` object in the resource tree as the |
| | | result of :term:`traversal`. |
| | | |
| | | In this example, each of the resources in the tree is of the same class. |
| | |
| | | |
| | | .. code-block:: python |
| | | :linenos: |
| | | |
| | | |
| | | list(lineage(thing2)) |
| | | [ <Thing object at thing2>, <Thing object at thing1> ] |
| | | |
| | |
| | | ``__parent__`` attribute, it returns the resource represented by |
| | | ``resource.__parent__``. If *that* resource has a ``__parent__`` attribute, |
| | | return that resource's parent, and so on, until the resource being inspected |
| | | either has no ``__parent__`` attribute or which has a ``__parent__`` |
| | | attribute of ``None``. |
| | | either has no ``__parent__`` attribute or has a ``__parent__`` attribute of |
| | | ``None``. |
| | | |
| | | See the documentation for :func:`pyramid.location.lineage` for more |
| | | information. |
| | |
| | | .. code-block:: python |
| | | :linenos: |
| | | |
| | | import datetime |
| | | from zope.interface import directlyProvides |
| | | from zope.interface import Interface |
| | | |
| | |
| | | .. code-block:: python |
| | | :linenos: |
| | | |
| | | import datetime |
| | | from zope.interface import alsoProvides |
| | | from zope.interface import directlyProvides |
| | | from zope.interface import Interface |
| | |
| | | resource, analogous to a file system "directory" or "file". The |
| | | resource found as the result of a traversal becomes the |
| | | :term:`context` of the :term:`request`. Then, the :term:`view lookup` |
| | | subsystem is used to find some view code willing "publish" this |
| | | subsystem is used to find some view code willing to "publish" this |
| | | resource by generating a :term:`response`. |
| | | |
| | | Using :term:`Traversal` to map a URL to code is optional. It is often |
| | |
| | | can be configured to return whatever object is appropriate as the |
| | | traversal root of your application. |
| | | |
| | | - Next, the first element (``a``) is popped from the path segment |
| | | - Next, the first element (``'a'``) is popped from the path segment |
| | | sequence and is used as a key to lookup the corresponding resource |
| | | in the root. This invokes the root resource's ``__getitem__`` method |
| | | using that value (``a``) as an argument. |
| | | using that value (``'a'``) as an argument. |
| | | |
| | | - If the root resource "contains" a resource with key ``a``, its |
| | | - If the root resource "contains" a resource with key ``'a'``, its |
| | | ``__getitem__`` method will return it. The :term:`context` temporarily |
| | | becomes the "A" resource. |
| | | |
| | | - The next segment (``b``) is popped from the path sequence, and the "A" |
| | | resource's ``__getitem__`` is called with that value (``b``) as an |
| | | - The next segment (``'b'``) is popped from the path sequence, and the "A" |
| | | resource's ``__getitem__`` is called with that value (``'b'``) as an |
| | | argument; we'll presume it succeeds. |
| | | |
| | | - The "A" resource's ``__getitem__`` returns another resource, which |
| | |
| | | traversal ends before the path segment sequence is exhausted, the |
| | | :term:`view name` is the *next* remaining path segment element. If the |
| | | :term:`traversal` expends all of the path segments, then the :term:`view |
| | | name` is the empty string (`''`). |
| | | name` is the empty string (``''``). |
| | | |
| | | The combination of the context resource and the :term:`view name` found |
| | | via traversal is used later in the same request by the :term:`view |
| | |
| | | UTF-8 encoding. If any URL-unquoted path segment in ``PATH_INFO`` is not |
| | | decodeable using the UTF-8 decoding, a :exc:`TypeError` is raised. A |
| | | segment will be fully URL-unquoted and UTF8-decoded before it is passed |
| | | it to the ``__getitem__`` of any resource during traversal. |
| | | in to the ``__getitem__`` of any resource during traversal. |
| | | |
| | | Thus, a request with a ``PATH_INFO`` variable of ``/a/b/c`` maps to the |
| | | traversal sequence ``[u'a', u'b', u'c']``. |
| | | |
| | | #. :term:`Traversal` begins at the root resource returned by the root |
| | | factory. For the traversal sequence ``[u'a', u'b', u'c']``, the root |
| | | resource's ``__getitem__`` is called with the name ``a``. Traversal |
| | | resource's ``__getitem__`` is called with the name ``'a'``. Traversal |
| | | continues through the sequence. In our example, if the root resource's |
| | | ``__getitem__`` called with the name ``a`` returns a resource (aka |
| | | "resource ``a``"), that resource's ``__getitem__`` is called with the |
| | | name ``b``. If resource A returns a resource when asked for ``b``, |
| | | "resource ``b``"'s ``__getitem__`` is then asked for the name ``c``, and |
| | | may return "resource ``c``". |
| | | resource "A"), that resource's ``__getitem__`` is called with the name |
| | | ``'b'``. If resource "A" returns a resource "B" when asked for ``'b'``, |
| | | resource B's ``__getitem__`` is then asked for the name ``'c'``, and may |
| | | return resource "C". |
| | | |
| | | #. Traversal ends when a) the entire path is exhausted or b) when any |
| | | resouce raises a :exc:`KeyError` from its ``__getitem__`` or c) when any |
| | | non-final path element traversal does not have a ``__getitem__`` method |
| | | (resulting in a :exc:`NameError`) or d) when any path element is prefixed |
| | | with the set of characters ``@@`` (indicating that the characters |
| | | (resulting in a :exc:`AttributeError`) or d) when any path element is |
| | | prefixed with the set of characters ``@@`` (indicating that the characters |
| | | following the ``@@`` token should be treated as a :term:`view name`). |
| | | |
| | | #. When traversal ends for any of the reasons in the previous step, the last |
| | |
| | | Many arguments supplied during view configuration are :term:`view predicate` |
| | | arguments. View predicate arguments used during view configuration are used |
| | | to narrow the set of circumstances in which :term:`view lookup` will find a |
| | | particular view callable. |
| | | particular view callable. |
| | | |
| | | In general, the fewer number of predicates which are supplied to a |
| | | particular view configuration, the more likely it is that the associated |
| | |
| | | The name of a :term:`permission` that the user must possess in order to |
| | | invoke the :term:`view callable`. See :ref:`view_security_section` for |
| | | more information about view security and permissions. |
| | | |
| | | |
| | | If ``permission`` is not supplied, no permission is registered for this |
| | | view (it's accessible by any caller). |
| | | |
| | |
| | | argument. The view callable it is passed will accept ``(context, |
| | | request)``. The decorator must return a replacement view callable which |
| | | also accepts ``(context, request)``. |
| | | |
| | | |
| | | ``mapper`` |
| | | A Python object or :term:`dotted Python name` which refers to a :term:`view |
| | | mapper`, or ``None``. By default it is ``None``, which indicates that the |
| | |
| | | ``pattern``, representing a part of the path that will be used by |
| | | :term:`traversal` against the result of the route's :term:`root factory`. |
| | | |
| | | If ``route_name`` is not supplied, the view callable will be have a chance |
| | | If ``route_name`` is not supplied, the view callable will only have a chance |
| | | of being invoked if no other route was matched. This is when the |
| | | request/context pair found via :term:`resource location` does not indicate |
| | | it matched any configured route. |
| | |
| | | .. code-block:: python |
| | | :linenos: |
| | | |
| | | config.add_view('mypackage.views.my_view', name='my_view', request_method='POST', |
| | | config.add_view('mypackage.views.my_view', name='my_view', request_method='POST', |
| | | context=MyResource, permission='read') |
| | | |
| | | All arguments to ``view_config`` may be omitted. For example: |
| | |
| | | |
| | | This registers the same view under two different names. |
| | | |
| | | The decorator can also be used against class methods: |
| | | The decorator can also be used against a method of a class: |
| | | |
| | | .. code-block:: python |
| | | :linenos: |
| | |
| | | def amethod(self): |
| | | return Response('hello') |
| | | |
| | | When the decorator is used against a class method, a view is registered for |
| | | the *class*, so the class constructor must accept an argument list in one of |
| | | two forms: either it must accept a single argument ``request`` or it must |
| | | When the decorator is used against a method of a class, a view is registered |
| | | for the *class*, so the class constructor must accept an argument list in one |
| | | of two forms: either it must accept a single argument ``request`` or it must |
| | | accept two arguments, ``context, request``. |
| | | |
| | | The method which is decorated must return a :term:`response`. |
| | |
| | | URL = /FrontPage |
| | | |
| | | context: <tutorial.models.Page object at 0xa12536c> |
| | | view name: |
| | | view name: |
| | | |
| | | View: |
| | | ----- |
| | |
| | | route name: about |
| | | route pattern: /about |
| | | route path: /about |
| | | subpath: |
| | | subpath: |
| | | route predicates (request method = GET) |
| | | |
| | | View: |
| | |
| | | route name: about_post |
| | | route pattern: /about |
| | | route path: /about |
| | | subpath: |
| | | subpath: |
| | | route predicates (request method = POST) |
| | | |
| | | View: |
| | |
| | | :func:`pyramid.router.make_app` API. |
| | | |
| | | .. warning:: This method is deprecated as of Pyramid 1.0. Use |
| | | ``pyramid.threadlocals.get_current_registry().settings`` instead or use |
| | | ``pyramid.threadlocal.get_current_registry().settings`` instead or use |
| | | the ``settings`` attribute of the registry available from the request |
| | | (``request.registry.settings``). |
| | | """ |