diff options
Diffstat (limited to 'docs/narr')
| -rw-r--r-- | docs/narr/MyProject/development.ini | 2 | ||||
| -rw-r--r-- | docs/narr/MyProject/myproject/templates/mytemplate.pt | 184 | ||||
| -rw-r--r-- | docs/narr/advconfig.rst | 18 | ||||
| -rw-r--r-- | docs/narr/assets.rst | 61 | ||||
| -rw-r--r-- | docs/narr/configuration.rst | 4 | ||||
| -rw-r--r-- | docs/narr/events.rst | 9 | ||||
| -rw-r--r-- | docs/narr/extending.rst | 19 | ||||
| -rw-r--r-- | docs/narr/firstapp.rst | 13 | ||||
| -rw-r--r-- | docs/narr/hooks.rst | 28 | ||||
| -rw-r--r-- | docs/narr/hybrid.rst | 18 | ||||
| -rw-r--r-- | docs/narr/i18n.rst | 56 | ||||
| -rw-r--r-- | docs/narr/muchadoabouttraversal.rst | 22 | ||||
| -rw-r--r-- | docs/narr/project.rst | 80 | ||||
| -rw-r--r-- | docs/narr/renderers.rst | 42 | ||||
| -rw-r--r-- | docs/narr/resources.rst | 32 | ||||
| -rw-r--r-- | docs/narr/router.rst | 24 | ||||
| -rw-r--r-- | docs/narr/security.rst | 31 | ||||
| -rw-r--r-- | docs/narr/sessions.rst | 2 | ||||
| -rw-r--r-- | docs/narr/startup.rst | 12 | ||||
| -rw-r--r-- | docs/narr/templates.rst | 29 | ||||
| -rw-r--r-- | docs/narr/testing.rst | 24 | ||||
| -rw-r--r-- | docs/narr/threadlocals.rst | 18 | ||||
| -rw-r--r-- | docs/narr/traversal.rst | 6 | ||||
| -rw-r--r-- | docs/narr/urldispatch.rst | 393 | ||||
| -rw-r--r-- | docs/narr/viewconfig.rst | 36 | ||||
| -rw-r--r-- | docs/narr/views.rst | 22 | ||||
| -rw-r--r-- | docs/narr/zca.rst | 4 |
27 files changed, 483 insertions, 706 deletions
diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index 154e2c418..29486ce56 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -44,6 +44,6 @@ level = NOTSET formatter = generic [formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s +format = %(asctime)s %(levelname)-5.5s [%(name)s] %(message)s # End logging configuration diff --git a/docs/narr/MyProject/myproject/templates/mytemplate.pt b/docs/narr/MyProject/myproject/templates/mytemplate.pt index 03e7d9091..632c34876 100644 --- a/docs/narr/MyProject/myproject/templates/mytemplate.pt +++ b/docs/narr/MyProject/myproject/templates/mytemplate.pt @@ -4,103 +4,103 @@ xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head> - <title>The Pyramid Web Application Development Framework</title> - <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> - <meta name="keywords" content="python web application" /> - <meta name="description" content="pyramid web application" /> - <link rel="shortcut icon" - href="${request.static_url('myproject:static/favicon.ico')}" /> - <link rel="stylesheet" - href="${request.static_url('myproject:static/pylons.css')}" - type="text/css" media="screen" charset="utf-8" /> - <link rel="stylesheet" - href="http://fonts.googleapis.com/css?family=Neuton|Nobile:regular,i,b,bi&subset=latin" - type="text/css" media="screen" charset="utf-8" /> - <!--[if lte IE 6]> - <link rel="stylesheet" - href="${request.static_url('myproject:static/ie6.css')}" - type="text/css" media="screen" charset="utf-8" /> - <![endif]--> + <title>The Pyramid Web Application Development Framework</title> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> + <meta name="keywords" content="python web application" /> + <meta name="description" content="pyramid web application" /> + <link rel="shortcut icon" + href="${request.static_url('myproject:static/favicon.ico')}" /> + <link rel="stylesheet" + href="${request.static_url('myproject:static/pylons.css')}" + type="text/css" media="screen" charset="utf-8" /> + <link rel="stylesheet" + href="http://fonts.googleapis.com/css?family=Neuton|Nobile:regular,i,b,bi&subset=latin" + type="text/css" media="screen" charset="utf-8" /> + <!--[if lte IE 6]> + <link rel="stylesheet" + href="${request.static_url('myproject:static/ie6.css')}" + type="text/css" media="screen" charset="utf-8" /> + <![endif]--> </head> <body> - <div id="wrap"> - <div id="top"> - <div class="top align-center"> - <div> - <img src="${request.static_url('myproject:static/pyramid.png')}" - width="750" height="169" alt="pyramid"/> - </div> - </div> + <div id="wrap"> + <div id="top"> + <div class="top align-center"> + <div> + <img src="${request.static_url('myproject:static/pyramid.png')}" + width="750" height="169" alt="pyramid"/> </div> - <div id="middle"> - <div class="middle align-center"> - <p class="app-welcome"> - Welcome to <span class="app-name">${project}</span>, - an application generated by<br/> - the Pyramid web application development framework. - </p> - </div> + </div> + </div> + <div id="middle"> + <div class="middle align-center"> + <p class="app-welcome"> + Welcome to <span class="app-name">${project}</span>, + an application generated by<br/> + the Pyramid web application development framework. + </p> + </div> + </div> + <div id="bottom"> + <div class="bottom"> + <div id="left" class="align-right"> + <h2>Search documentation</h2> + <form method="get" + action="http://docs.pylonsproject.org/pyramid/dev/search.html"> + <input type="text" id="q" name="q" value="" /> + <input type="submit" id="x" value="Go" /> + </form> </div> - <div id="bottom"> - <div class="bottom"> - <div id="left" class="align-right"> - <h2>Search documentation</h2> - <form method="get" - action="http://docs.pylonsproject.org/pyramid/dev/search.html"> - <input type="text" id="q" name="q" value="" /> - <input type="submit" id="x" value="Go" /> - </form> - </div> - <div id="right" class="align-left"> - <h2>Pyramid links</h2> - <ul class="links"> - <li> - <a href="http://pylonsproject.org"> - Pylons Website - </a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#narrative-documentation"> - Narrative Documentation - </a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#api-documentation"> - API Documentation - </a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#tutorials"> - Tutorials - </a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#change-history"> - Change History - </a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#sample-applications"> - Sample Applications - </a> - </li> - <li> - <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#support-and-development"> - Support and Development - </a> - </li> - <li> - <a href="irc://irc.freenode.net#pyramid"> - IRC Channel - </a> - </li> - </ul> - </div> - </div> + <div id="right" class="align-left"> + <h2>Pyramid links</h2> + <ul class="links"> + <li> + <a href="http://pylonsproject.org"> + Pylons Website + </a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#narrative-documentation"> + Narrative Documentation + </a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#api-documentation"> + API Documentation + </a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#tutorials"> + Tutorials + </a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#change-history"> + Change History + </a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#sample-applications"> + Sample Applications + </a> + </li> + <li> + <a href="http://docs.pylonsproject.org/projects/pyramid/dev/#support-and-development"> + Support and Development + </a> + </li> + <li> + <a href="irc://irc.freenode.net#pyramid"> + IRC Channel + </a> + </li> + </ul> </div> + </div> </div> - <div id="footer"> - <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> - </div> + </div> + <div id="footer"> + <div class="footer">© Copyright 2008-2010, Agendaless Consulting.</div> + </div> </body> </html> diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 20316dc77..099bce35f 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -163,7 +163,7 @@ Using ``config.commit()`` +++++++++++++++++++++++++ You can manually commit a configuration by using the -:meth:`pyramid.config.Configurator.commit` method between configuration +:meth:`~pyramid.config.Configurator.commit` method between configuration calls. For example, we prevent conflicts from occurring in the application we examined previously as the result of adding a ``commit``. Here's the application that generates conflicts: @@ -255,7 +255,7 @@ conflict detection (and :ref:`twophase_config`) is disabled. Configuration statements will be executed immediately, and succeeding statements will override preceding ones. -:meth:`pyramid.config.Configurator.commit` has no effect when ``autocommit`` +:meth:`~pyramid.config.Configurator.commit` has no effect when ``autocommit`` is ``True``. If you use a Configurator in code that performs unit testing, it's usually a @@ -267,7 +267,7 @@ unconcerned about conflict detection or two-phase configuration in test code. Automatic Conflict Resolution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If your code uses the :meth:`pyramid.config.Configurator.include` method to +If your code uses the :meth:`~pyramid.config.Configurator.include` method to include external configuration, some conflicts are automatically resolved. Configuration statements that are made as the result of an "include" will be overridden by configuration statements that happen within the caller of @@ -332,7 +332,7 @@ Instead, use :meth:`pyramid.config.Configuration.include`: Using ``include`` rather than calling the function directly will allow :ref:`automatic_conflict_resolution` to work. -:meth:`pyramid.config.Configuration.include` can also accept a :term:`module` +:meth:`~pyramid.config.Configuration.include` can also accept a :term:`module` as an argument: .. code-block:: python @@ -346,11 +346,11 @@ For this to work properly, the ``myapp`` module must contain a callable with the special name ``includeme``, which should perform configuration (like the ``add_routes`` callable we showed above as an example). -:meth:`pyramid.config.Configuration.include` can also accept a :term:`dotted +:meth:`~pyramid.config.Configuration.include` can also accept a :term:`dotted Python name` to a function or a module. .. note: See :ref:`the_include_tag` for a declarative alternative to - :meth:`pyramid.config.Configurator.include`. + the :meth:`~pyramid.config.Configurator.include` method. .. _twophase_config: @@ -368,8 +368,8 @@ to do conflict detection. Due to this, for configuration methods that have no internal ordering constraints, execution order of configuration method calls is not important. For example, the relative ordering of -:meth:`pyramid.config.Configurator.add_view` and -:meth:`pyramid.config.Configurator.add_renderer` is unimportant when a +:meth:`~pyramid.config.Configurator.add_view` and +:meth:`~pyramid.config.Configurator.add_renderer` is unimportant when a non-autocommitting configurator is used. This code snippet: .. code-block:: python @@ -398,7 +398,7 @@ used, two-phase configuration is disabled, and configuration statements must be ordered in dependency order. Some configuration methods, such as -:meth:`pyramid.config.Configurator.add_route` have internal ordering +:meth:`~pyramid.config.Configurator.add_route` have internal ordering constraints: the routes they imply require relative ordering. Such ordering constraints are not absolved by two-phase configuration. Routes are still added in configuration execution order. diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index ee2e0440e..74fa7723e 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -142,7 +142,7 @@ see :ref:`advanced_static`. Here's another example that uses an :term:`asset specification` instead of an absolute path as the ``path`` argument. To convince -:meth:`pyramid.config.Configurator.add_static_view` to serve files up under +:meth:`~pyramid.config.Configurator.add_static_view` to serve files up under the ``/static`` URL from the ``a/b/c/static`` directory of the Python package named ``some_package``, we can use a fully qualified :term:`asset specification` as the ``path``: @@ -153,17 +153,17 @@ specification` as the ``path``: # config is an instance of pyramid.config.Configurator config.add_static_view(name='static', path='some_package:a/b/c/static') -The ``path`` provided to :meth:`pyramid.config.Configurator.add_static_view` +The ``path`` provided to :meth:`~pyramid.config.Configurator.add_static_view` may be a fully qualified :term:`asset specification` or an *absolute path*. Instead of representing a URL prefix, the ``name`` argument of a call to -:meth:`pyramid.config.Configurator.add_static_view` can alternately be a +:meth:`~pyramid.config.Configurator.add_static_view` can alternately be a *URL*. Each of examples we've seen so far have shown usage of the ``name`` argument as a URL prefix. However, when ``name`` is a *URL*, static assets can be served from an external webserver. In this mode, the ``name`` is used as the URL prefix when generating a URL using :func:`pyramid.url.static_url`. -For example, :meth:`pyramid.config.Configurator.add_static_view` may +For example, :meth:`~pyramid.config.Configurator.add_static_view` may be fed a ``name`` argument which is ``http://example.com/images``: .. code-block:: python @@ -173,23 +173,16 @@ be fed a ``name`` argument which is ``http://example.com/images``: config.add_static_view(name='http://example.com/images', path='mypackage:images') -Because :meth:`pyramid.config.Configurator.add_static_view` is provided with +Because :meth:`~pyramid.config.Configurator.add_static_view` is provided with a ``name`` argument that is the URL ``http://example.com/images``, subsequent -calls to :func:`pyramid.url.static_url` with paths that start with the +calls to :func:`~pyramid.url.static_url` with paths that start with the ``path`` argument passed to -:meth:`pyramid.config.Configurator.add_static_view` will generate a URL +:meth:`~pyramid.config.Configurator.add_static_view` will generate a URL something like ``http://example.com/images/logo.png``. The external webserver listening on ``example.com`` must be itself configured to respond -properly to such a request. The :func:`pyramid.url.static_url` API is +properly to such a request. The :func:`~pyramid.url.static_url` API is discussed in more detail later in this chapter. -.. note:: - - The :ref:`static_directive` ZCML directive offers an declarative - equivalent to :meth:`pyramid.config.Configurator.add_static_view`. Use of - the :ref:`static_directive` ZCML directive is completely equivalent to - using imperative configuration for the same purpose. - .. index:: single: generating static asset urls single: static asset urls @@ -199,7 +192,7 @@ discussed in more detail later in this chapter. Generating Static Asset URLs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a :meth:`pyramid.config.Configurator.add_static_view` method is used to +When a :meth:`~pyramid.config.Configurator.add_static_view` method is used to register a static asset directory, a special helper API named :func:`pyramid.url.static_url` can be used to generate the appropriate URL for an asset that lives in one of the directories named by the static @@ -221,7 +214,7 @@ visits a URL which begins with ``/static1``, and the assets in the visits a URL which begins with ``/static2``. You needn't generate the URLs to static assets "by hand" in such a -configuration. Instead, use the :func:`pyramid.url.static_url` API to +configuration. Instead, use the :func:`~pyramid.url.static_url` API to generate them for you. For example: .. code-block:: python @@ -242,15 +235,15 @@ If the request "application URL" of the running system is ``http://example.com/static1/foo.css``. The ``js_url`` generated above would be ``http://example.com/static2/foo.js``. -One benefit of using the :func:`pyramid.url.static_url` function rather than +One benefit of using the :func:`~pyramid.url.static_url` function rather than constructing static URLs "by hand" is that if you need to change the ``name`` of a static URL declaration, the generated URLs will continue to resolve properly after the rename. -URLs may also be generated by :func:`pyramid.url.static_url` to static assets +URLs may also be generated by :func:`~pyramid.url.static_url` to static assets that live *outside* the :app:`Pyramid` application. This will happen when -the :meth:`pyramid.config.Configurator.add_static_view` API associated with -the path fed to :func:`pyramid.url.static_url` is a *URL* instead of a view +the :meth:`~pyramid.config.Configurator.add_static_view` API associated with +the path fed to :func:`~pyramid.url.static_url` is a *URL* instead of a view name. For example, the ``name`` argument may be ``http://example.com`` while the the ``path`` given may be ``mypackage:images``: @@ -270,13 +263,13 @@ assets which begin with ``mypackage:images`` will be prefixed with static_url('mypackage:images/logo.png', request) # -> http://example.com/images/logo.png -Using :func:`pyramid.url.static_url` in conjunction with a -:meth:`pyramid.configuration.Configurator.add_static_view` makes it possible +Using :func:`~pyramid.url.static_url` in conjunction with a +:meth:`~pyramid.configuration.Configurator.add_static_view` makes it possible to put static media on a separate webserver during production (if the -``name`` argument to :meth:`pyramid.config.Configurator.add_static_view` is a +``name`` argument to :meth:`~pyramid.config.Configurator.add_static_view` is a URL), while keeping static media package-internal and served by the development webserver during development (if the ``name`` argument to -:meth:`pyramid.config.Configurator.add_static_view` is a URL prefix). To +:meth:`~pyramid.config.Configurator.add_static_view` is a URL prefix). To create such a circumstance, we suggest using the :attr:`pyramid.registry.Registry.settings` API in conjunction with a setting in the application ``.ini`` file named ``media_location``. Then set the @@ -300,7 +293,7 @@ dispatch`, you may want static assets to only be available as a fallback if no previous route matches. Alternately, you might like to serve a particular static asset manually, because its download requires authentication. -Note that you cannot use the :func:`pyramid.url.static_url` API to generate +Note that you cannot use the :func:`~pyramid.url.static_url` API to generate URLs against assets made accessible by registering a custom static view. Root-Relative Custom Static View (URL Dispatch Only) @@ -309,7 +302,7 @@ Root-Relative Custom Static View (URL Dispatch Only) The :class:`pyramid.view.static` helper class generates a Pyramid view callable. This view callable can serve static assets from a directory. An instance of this class is actually used by the -:meth:`pyramid.config.Configurator.add_static_view` configuration method, so +:meth:`~pyramid.config.Configurator.add_static_view` configuration method, so its behavior is almost exactly the same once it's configured. .. warning:: The following example *will not work* for applications that use @@ -317,13 +310,13 @@ its behavior is almost exactly the same once it's configured. exclusively. The root-relative route we'll be registering will always be matched before traversal takes place, subverting any views registered via ``add_view`` (at least those without a ``route_name``). A - :class:`pyramid.view.static` static view cannot be made root-relative when + :class:`~pyramid.view.static` static view cannot be made root-relative when you use traversal. To serve files within a directory located on your filesystem at ``/path/to/static/dir`` as the result of a "catchall" route hanging from the root that exists at the end of your routing table, create an instance of the -:class:`pyramid.view.static` class inside a ``static.py`` file in your +:class:`~pyramid.view.static` class inside a ``static.py`` file in your application root as below. .. ignore-next-block @@ -334,7 +327,7 @@ application root as below. static_view = static('/path/to/static/dir') .. note:: For better cross-system flexibility, use an :term:`asset - specification` as the argument to :class:`pyramid.view.static` instead of + specification` as the argument to :class:`~pyramid.view.static` instead of a physical absolute filesystem path, e.g. ``mypackage:static`` instead of ``/path/to/mypackage/static``. @@ -351,7 +344,7 @@ application's startup code. config.add_route('catchall_static', '/*subpath', 'myapp.static.static_view') The special name ``*subpath`` above is used by the -:class:`pyramid.view.static` view callable to signify the path of the file +:class:`~pyramid.view.static` view callable to signify the path of the file relative to the directory you're serving. Registering A View Callable to Serve a "Static" Asset @@ -440,7 +433,7 @@ feature, a :term:`Configurator` API exists named setuptools :term:`pkg_resources` API. .. note:: The :term:`ZCML` directive named ``asset`` serves the same purpose - as the :meth:`pyramid.config.Configurator.override_asset` method. + as the :meth:`~pyramid.config.Configurator.override_asset` method. .. index:: single: override_asset @@ -450,7 +443,7 @@ feature, a :term:`Configurator` API exists named The ``override_asset`` API ~~~~~~~~~~~~~~~~~~~~~~~~~~ -An individual call to :meth:`pyramid.config.Configurator.override_asset` +An individual call to :meth:`~pyramid.config.Configurator.override_asset` can override a single asset. For example: .. ignore-next-block @@ -503,7 +496,7 @@ if you want to override assets for both ``some.package:templates``, and The package name in a specification may start with a dot, meaning that the package is relative to the package in which the configuration construction file resides (or the ``package`` argument to the -:class:`pyramid.config.Configurator` class construction). +:class:`~pyramid.config.Configurator` class construction). For example: .. ignore-next-block diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index 05bc4d6cc..6360dc574 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -127,7 +127,7 @@ The scanning machinery imports each module and subpackage in a package or module recursively, looking for special attributes attached to objects defined within a module. These special attributes are typically attached to code via the use of a :term:`decorator`. For example, the -:class:`pyramid.view.view_config` decorator can be attached to a function or +:class:`~pyramid.view.view_config` decorator can be attached to a function or instance method. Once scanning is invoked, and :term:`configuration decoration` is found by @@ -136,7 +136,7 @@ behalf: these calls replace the need to add imperative configuration statements that don't live near the code being configured. In the example above, the scanner translates the arguments to -:class:`pyramid.view.view_config` into a call to the +:class:`~pyramid.view.view_config` into a call to the :meth:`pyramid.config.Configurator.add_view` method, effectively: .. ignore-next-block diff --git a/docs/narr/events.rst b/docs/narr/events.rst index 224eeca16..929208083 100644 --- a/docs/narr/events.rst +++ b/docs/narr/events.rst @@ -43,7 +43,7 @@ Configuring an Event Listener Imperatively You can imperatively configure a subscriber function to be called for some event type via the -:meth:`pyramid.config.Configurator.add_subscriber` +:meth:`~pyramid.config.Configurator.add_subscriber` method (see also :term:`Configurator`): .. code-block:: python @@ -59,7 +59,7 @@ method (see also :term:`Configurator`): config.add_subscriber(mysubscriber, NewRequest) The first argument to -:meth:`pyramid.config.Configurator.add_subscriber` is the +:meth:`~pyramid.config.Configurator.add_subscriber` is the subscriber function (or a :term:`dotted Python name` which refers to a subscriber callable); the second argument is the event type. @@ -79,10 +79,9 @@ type via the :func:`pyramid.events.subscriber` function. def mysubscriber(event): event.request.foo = 1 -When the :func:`pyramid.subscriber` decorator is used a +When the :func:`~pyramid.events.subscriber` decorator is used a :term:`scan` must be performed against the package containing the -decorated function for the decorator to have any effect. See -:func:`pyramid.subscriber` for more information. +decorated function for the decorator to have any effect. Either of the above registration examples implies that every time the :app:`Pyramid` framework emits an event object that supplies an diff --git a/docs/narr/extending.rst b/docs/narr/extending.rst index c709e1f8f..416207584 100644 --- a/docs/narr/extending.rst +++ b/docs/narr/extending.rst @@ -115,15 +115,14 @@ Fundamental Plugpoints The fundamental "plug points" of an application developed using :app:`Pyramid` are *routes*, *views*, and *assets*. Routes are declarations -made using the :meth:`pyramid.config.Configurator.add_route` method (or the -ZCML ``<route>`` directive). Views are declarations made using the -:meth:`pyramid.config.Configurator.add_view` method (or the ZCML ``<view>`` -directive). Assets are files that are accessed by :app:`Pyramid` using the -:term:`pkg_resources` API such as static files and templates via a -:term:`asset specification`. Other directives and configurator methods also -deal in routes, views, and assets. For example, ``add_handler`` directive of -the ``pyramid_handlers`` package adds a single route, and some number of -views. +made using the :meth:`pyramid.config.Configurator.add_route` method. Views +are declarations made using the :meth:`pyramid.config.Configurator.add_view` +method. Assets are files that are +accessed by :app:`Pyramid` using the :term:`pkg_resources` API such as static +files and templates via a :term:`asset specification`. Other directives and +configurator methods also deal in routes, views, and assets. For example, +``add_handler`` directive of the ``pyramid_handlers`` package adds a single +route, and some number of views. .. index:: single: extending an existing application @@ -270,7 +269,7 @@ Overriding Routes ~~~~~~~~~~~~~~~~~ Route setup is currently typically performed in a sequence of ordered calls -to :meth:`pyramid.config.Configurator.add_route`. Because these calls are +to :meth:`~pyramid.config.Configurator.add_route`. Because these calls are ordered relative to each other, and because this ordering is typically important, you should retain their relative ordering when performing an override. Typically, this means *copying* all the ``add_route`` statements diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index a82119b73..f5adad905 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -7,13 +7,6 @@ In this chapter, we will walk through the creation of a tiny :app:`Pyramid` application. After we're finished creating the application, we'll explain in more detail how it works. -.. note:: - - If you're a "theory-first" kind of person, you might choose to read - :ref:`urldispatch_chapter` and :ref:`views_chapter` before diving into - the code that follows, but it's not necessary if -- like many programmers - -- you're willing to "go with the flow". - .. _helloworld_imperative: Hello World, Goodbye World @@ -122,7 +115,7 @@ A view callable is required to return a :term:`response` object because a response object has all the information necessary to formulate an actual HTTP response; this object is then converted to text by the upstream :term:`WSGI` server and sent back to the requesting browser. To return a response, each -view callable creates an instance of the :class:`pyramid.response.Response` +view callable creates an instance of the :class:`~pyramid.response.Response` class. In the ``hello_world`` function, the string ``'Hello world!'`` is passed to the ``Response`` constructor as the *body* of the response. In the ``goodbye_world`` function, the string ``'Goodbye world!'`` is passed. @@ -247,7 +240,7 @@ predicates) is always invoked. In this application, :app:`Pyramid` chooses the most specific view callable based only on view :term:`predicate` applicability. The ordering of calls to -:meth:`pyramid.config.Configurator.add_view` is never very important. We can +:meth:`~pyramid.config.Configurator.add_view` is never very important. We can register ``goodbye_world`` first and ``hello_world`` second; :app:`Pyramid` will still give us the most specific callable when a request is dispatched to it. @@ -322,7 +315,7 @@ References ---------- For more information about the API of a :term:`Configurator` object, -see :class:`pyramid.config.Configurator` . +see :class:`~pyramid.config.Configurator` . For more information about :term:`view configuration`, see :ref:`view_config_chapter`. diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index b3b41046f..d2eaf8215 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -42,7 +42,7 @@ Like any other view, the notfound view must accept at least a ``request`` parameter, or both ``context`` and ``request``. The ``request`` is the current :term:`request` representing the denied action. The ``context`` (if used in the call signature) will be the instance of the -:exc:`pyramid.exceptions.NotFound` exception that caused the view to be +:exc:`~pyramid.exceptions.NotFound` exception that caused the view to be called. Here's some sample code that implements a minimal NotFound view callable: @@ -57,7 +57,7 @@ Here's some sample code that implements a minimal NotFound view callable: .. note:: When a NotFound view callable is invoked, it is passed a :term:`request`. The ``exception`` attribute of the request will - be an instance of the :exc:`pyramid.exceptions.NotFound` + be an instance of the :exc:`~pyramid.exceptions.NotFound` exception that caused the not found view to be called. The value of ``request.exception.args[0]`` will be a value explaining why the not found error was raised. This message will be different when @@ -67,7 +67,7 @@ Here's some sample code that implements a minimal NotFound view callable: .. warning:: When a NotFound view callable accepts an argument list as described in :ref:`request_and_context_view_definitions`, the ``context`` passed as the first argument to the view callable will be the - :exc:`pyramid.exceptions.NotFound` exception instance. If available, the + :exc:`~pyramid.exceptions.NotFound` exception instance. If available, the resource context will still be available as ``request.context``. .. index:: @@ -122,7 +122,7 @@ Here's some sample code that implements a minimal forbidden view: .. note:: When a forbidden view callable is invoked, it is passed a :term:`request`. The ``exception`` attribute of the request will - be an instance of the :exc:`pyramid.exceptions.Forbidden` + be an instance of the :exc:`~pyramid.exceptions.Forbidden` exception that caused the forbidden view to be called. The value of ``request.exception.args[0]`` will be a value explaining why the forbidden was raised. This message will be different when the @@ -253,7 +253,7 @@ that can be used for this purpose. For example: An object of this type is sent as an event just before a :term:`renderer` is invoked (but *after* the application-level renderer globals factory added via -:class:`pyramid.config.Configurator.set_renderer_globals_factory`, if any, +:class:`~pyramid.config.Configurator.set_renderer_globals_factory`, if any, has injected its own keys into the renderer globals dictionary). If a subscriber attempts to add a key that already exist in the renderer @@ -263,7 +263,7 @@ keys added to the renderer globals dictionary by all :class:`pyramid.events.BeforeRender` subscribers and renderer globals factories must be unique. -See the API documentation for the :class:`pyramid.events.BeforeRender` event +See the API documentation for the :class:`~pyramid.events.BeforeRender` event interface at :class:`pyramid.interfaces.IBeforeRender`. Another mechanism which allows event subscribers more control when adding @@ -307,14 +307,14 @@ callback will be an exception object instead of its default value of Response callbacks are called in the order they're added (first-to-most-recently-added). All response callbacks are called *after* -the :class:`pyramid.events.NewResponse` event is sent. Errors raised by +the :class:`~pyramid.events.NewResponse` event is sent. Errors raised by response callbacks are not handled specially. They will be propagated to the caller of the :app:`Pyramid` router application. A response callback has a lifetime of a *single* request. If you want a response callback to happen as the result of *every* request, you must re-register the callback into every new request (perhaps within a subscriber -of a :class:`pyramid.events.NewRequest` event). +of a :class:`~pyramid.events.NewRequest` event). .. index:: single: finished callback @@ -377,7 +377,7 @@ application. A finished callback has a lifetime of a *single* request. If you want a finished callback to happen as the result of *every* request, you must re-register the callback into every new request (perhaps within a subscriber -of a :class:`pyramid.events.NewRequest` event). +of a :class:`~pyramid.events.NewRequest` event). .. index:: single: traverser @@ -472,7 +472,7 @@ However, since the way traversal is done will have been modified, the URLs it generates by default may be incorrect. If you've added a traverser, you can change how -:func:`pyramid.url.resource_url` generates a URL for a specific type of +:func:`~pyramid.url.resource_url` generates a URL for a specific type of resource by adding a registerAdapter call for :class:`pyramid.interfaces.IContextURL` to your application: @@ -488,7 +488,7 @@ resource by adding a registerAdapter call for IContextURL) In the above example, the ``myapp.traversal.URLGenerator`` class will be used -to provide services to :func:`pyramid.url.resource_url` any time the +to provide services to :func:`~pyramid.url.resource_url` any time the :term:`context` passed to ``resource_url`` is of class ``myapp.resources.MyRoot``. The second argument in the ``(MyRoot, Interface)`` tuple represents the type of interface that must be possessed by @@ -496,7 +496,7 @@ the :term:`request` (in this case, any interface, represented by ``zope.interface.Interface``). The API that must be implemented by a class that provides -:class:`pyramid.interfaces.IContextURL` is as follows: +:class:`~pyramid.interfaces.IContextURL` is as follows: .. code-block:: python :linenos: @@ -611,7 +611,7 @@ to set a *default* view mapper (overriding the superdefault view mapper used by Pyramid itself). A *single* view registration can use a view mapper by passing the mapper as -the ``mapper`` argument to :meth:`pyramid.config.Configuration.add_view`. +the ``mapper`` argument to :meth:`~pyramid.config.Configuration.add_view`. .. index:: single: configuration decorator @@ -621,7 +621,7 @@ the ``mapper`` argument to :meth:`pyramid.config.Configuration.add_view`. Registering Configuration Decorators ------------------------------------ -Decorators such as :class:`pyramid.view.view_config` don't change the +Decorators such as :class:`~pyramid.view.view_config` don't change the behavior of the functions or classes they're decorating. Instead, when a :term:`scan` is performed, a modified version of the function or class is registered with :app:`Pyramid`. diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst index 181ae1285..780cb0975 100644 --- a/docs/narr/hybrid.rst +++ b/docs/narr/hybrid.rst @@ -156,12 +156,12 @@ match is straightforward. When a route is matched: - If the route's configuration does not have a ``factory`` argument, the *global* :term:`root factory` will be called to generate a :term:`root` object. The global root factory is the - callable implied by the ``root_factory`` argument passed to - :class:`pyramid.config.Configurator` at application + callable implied by the ``root_factory`` argument passed to the + :class:`~pyramid.config.Configurator` at application startup time. - If a ``root_factory`` argument is not provided to the - :class:`pyramid.config.Configurator` at startup time, a + :class:`~pyramid.config.Configurator` at startup time, a *default* root factory is used. The default root factory is used to generate a root object. @@ -260,7 +260,7 @@ route statement is a reasonable thing to do. We could have also used our ``root_factory`` callable as the ``root_factory`` argument of the - :class:`pyramid.config.Configurator` constructor, instead + :class:`~pyramid.config.Configurator` constructor, instead of associating it with a particular route inside the route's configuration. Every hybrid route configuration that is matched but which does *not* name a ``factory`` attribute will use the use @@ -300,13 +300,13 @@ invoked after a route matches: config.add_view('mypackage.views.myview', route_name='home') Note that the above call to -:meth:`pyramid.config.Configurator.add_view` includes a ``route_name`` +:meth:`~pyramid.config.Configurator.add_view` includes a ``route_name`` argument. View configurations that include a ``route_name`` argument are meant to associate a particular view declaration with a route, using the route's name, in order to indicate that the view should *only be invoked when the route matches*. -Calls to :meth:`pyramid.config.Configurator.add_view` may pass a +Calls to :meth:`~pyramid.config.Configurator.add_view` may pass a ``route_name`` attribute, which refers to the value of an existing route's ``name`` argument. In the above example, the route name is ``home``, referring to the name of the route defined above it. @@ -357,7 +357,7 @@ Using the ``traverse`` Argument In a Route Definition Rather than using the ``*traverse`` remainder marker in a pattern, you can use the ``traverse`` argument to the -:meth:`pyramid.config.Configurator.add_route` method. +:meth:`~pyramid.config.Configurator.add_route` method. When you use the ``*traverse`` remainder marker, the traversal path is limited to being the remainder segments of a request URL when a route @@ -365,7 +365,7 @@ matches. However, when you use the ``traverse`` argument or attribute, you have more control over how to compose a traversal path. Here's a use of the ``traverse`` pattern in a call to -:meth:`pyramid.config.Configurator.add_route`: +:meth:`~pyramid.config.Configurator.add_route`: .. code-block:: python :linenos: @@ -472,7 +472,7 @@ startup time. config.add_view('myproject.views.another', route_name='home') This is because the ``view`` argument to the -:meth:`pyramid.config.Configurator.add_route` above is an *implicit* +:meth:`~pyramid.config.Configurator.add_route` above is an *implicit* default view when that route matches. ``add_route`` calls don't *need* to supply a view attribute. For example, this ``add_route`` call: diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 7bfd29631..e7a4f61c0 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -59,7 +59,7 @@ This creates a Unicode-like object that is a TranslationString. :term:`Django` i18n, using a TranslationString is a lot like using "lazy" versions of related gettext APIs. -The first argument to :class:`pyramid.i18n.TranslationString` is +The first argument to :class:`~pyramid.i18n.TranslationString` is the ``msgid``; it is required. It represents the key into the translation mappings provided by a particular localization. The ``msgid`` argument must be a Unicode object or an ASCII string. The @@ -139,7 +139,7 @@ Using the ``TranslationStringFactory`` Class ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Another way to generate a translation string is to use the -:attr:`pyramid.i18n.TranslationStringFactory` object. This object +:attr:`~pyramid.i18n.TranslationStringFactory` object. This object is a *translation string factory*. Basically a translation string factory presets the ``domain`` value of any :term:`translation string` generated by using it. For example: @@ -156,11 +156,11 @@ generated by using it. For example: file generation tools. After assigning ``_`` to the result of a -:func:`pyramid.i18n.TranslationStringFactory`, the subsequent result -of calling ``_`` will be a :class:`pyramid.i18n.TranslationString` +:func:`~pyramid.i18n.TranslationStringFactory`, the subsequent result +of calling ``_`` will be a :class:`~pyramid.i18n.TranslationString` instance. Even though a ``domain`` value was not passed to ``_`` (as would have been necessary if the -:class:`pyramid.i18n.TranslationString` constructor were used instead +:class:`~pyramid.i18n.TranslationString` constructor were used instead of a translation string factory), the ``domain`` attribute of the resulting translation string will be ``pyramid``. As a result, the previous code example is completely equivalent (except for spelling) @@ -175,7 +175,7 @@ to: You can set up your own translation string factory much like the one provided above by using the -:class:`pyramid.i18n.TranslationStringFactory` class. For example, +:class:`~pyramid.i18n.TranslationStringFactory` class. For example, if you'd like to create a translation string factory which presets the ``domain`` value of generated translation strings to ``form``, you'd do something like this: @@ -344,7 +344,8 @@ which reside in your :app:`Pyramid` application. You run a $ mkdir -p myapplication/locale $ python setup.py extract_messages -The message catalog ``.pot`` template will end up in +The message catalog ``.pot`` template will end up in: + ``myapplication/locale/myapplication.pot``. Translation Domains @@ -432,7 +433,8 @@ init_catalog`` command: $ cd /place/where/myapplication/setup.py/lives $ python setup.py init_catalog -l es -By default, the message catalog ``.po`` file will end up in +By default, the message catalog ``.po`` file will end up in: + ``myapplication/locale/es/LC_MESSAGES/myapplication.po``. Once the file is there, it can be worked on by a human translator. @@ -491,13 +493,12 @@ translations will be available to :app:`Pyramid`. Using a Localizer ----------------- -A :term:`localizer` is an object that allows you to perform -translation or pluralization "by hand" in an application. You may use -the :func:`pyramid.i18n.get_localizer` function to obtain a -:term:`localizer`. :func:`pyramid.i18n.get_localizer`. This -function will return either the localizer object implied by the active -:term:`locale negotiator` or a default localizer object if no explicit -locale negotiator is registered. +A :term:`localizer` is an object that allows you to perform translation or +pluralization "by hand" in an application. You may use the +:func:`pyramid.i18n.get_localizer` function to obtain a :term:`localizer`. +This function will return either the localizer object implied by the active +:term:`locale negotiator` or a default localizer object if no explicit locale +negotiator is registered. .. code-block:: python :linenos: @@ -534,7 +535,7 @@ translation in a view component of an application might look like so: translated = localizer.translate(ts) # translation string # ... use translated ... -The :func:`pyramid.i18n.get_localizer` function will return a +The :func:`~pyramid.i18n.get_localizer` function will return a :class:`pyramid.i18n.Localizer` object bound to the locale name represented by the request. The translation returned from its :meth:`pyramid.i18n.Localizer.translate` method will depend on the @@ -612,9 +613,9 @@ locale negotiator returns ``None``. You can change the default locale name by changing the ``default_locale_name`` setting; see :ref:`default_locale_name_setting`. -Once :func:`pyramid.i18n.get_locale_name` is first run, the locale +Once :func:`~pyramid.i18n.get_locale_name` is first run, the locale name is stored on the request object. Subsequent calls to -:func:`pyramid.i18n.get_locale_name` will return the stored locale +:func:`~pyramid.i18n.get_locale_name` will return the stored locale name without invoking the :term:`locale negotiator`. To avoid this caching, you can use the :func:`pyramid.i18n.negotiate_locale_name` function: @@ -641,7 +642,7 @@ You can also obtain the locale name related to a request using the Obtaining the locale name as an attribute of a localizer is equivalent to obtaining a locale name by calling the -:func:`pyramid.i18n.get_locale_name` function. +:func:`~pyramid.i18n.get_locale_name` function. .. index:: single: date and currency formatting (i18n) @@ -738,8 +739,9 @@ facility described in :ref:`performing_a_translation`. Mako Pyramid I18N Support ------------------------- -:ref:`mako_i18n` is a recipe within the :term:`Pyramid Cookbook` which -explains how to add idiomatic I18N support to :term:`Mako` templates. +There exists a recipe within the :term:`Pyramid Cookbook` named "Mako +Internationalization" which explains how to add idiomatic I18N support to +:term:`Mako` templates. .. index:: single: localization deployment settings @@ -753,7 +755,7 @@ Localization-Related Deployment Settings A :app:`Pyramid` application will have a ``default_locale_name`` setting. This value represents the :term:`default locale name` used when the :term:`locale negotiator` returns ``None``. Pass it to the -:mod:`pyramid.config.Configurator` constructor at startup +:mod:`~pyramid.config.Configurator` constructor at startup time: .. code-block:: python @@ -891,7 +893,7 @@ application startup. For example: 'another.application:locale/') A message catalog in a translation directory added via -:meth:`pyramid.config.Configurator.add_translation_dirs` +:meth:`~pyramid.config.Configurator.add_translation_dirs` will be merged into translations from a message catalog added earlier if both translation directories contain translations for the same locale and :term:`translation domain`. @@ -937,8 +939,8 @@ a particular request. A locale negotiator is a bit of code which accepts a request and which returns a :term:`locale name`. It is consulted when :meth:`pyramid.i18n.Localizer.translate` or :meth:`pyramid.i18n.Localizer.pluralize` is invoked. It is also -consulted when :func:`pyramid.i18n.get_locale_name` or -:func:`pyramid.i18n.negotiate_locale_name` is invoked. +consulted when :func:`~pyramid.i18n.get_locale_name` or +:func:`~pyramid.i18n.negotiate_locale_name` is invoked. .. _default_locale_negotiator: @@ -949,7 +951,7 @@ Most applications can make use of the default locale negotiator, which requires no additional coding or configuration. The default locale negotiator implementation named -:class:`pyramid.i18n.default_locale_negotiator` uses the following +:class:`~pyramid.i18n.default_locale_negotiator` uses the following set of steps to dermine the locale name. - First, the negotiator looks for the ``_LOCALE_`` attribute of the @@ -1000,7 +1002,7 @@ You may add your newly created locale negotiator to your application's configuration by passing an object which can act as the negotiator (or a :term:`dotted Python name` referring to the object) as the ``locale_negotiator`` argument of the -:class:`pyramid.config.Configurator` instance during application +:class:`~pyramid.config.Configurator` instance during application startup. For example: .. code-block:: python diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index 467a9e601..a4709ef18 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -6,8 +6,7 @@ Much Ado About Traversal .. note:: This chapter was adapted, with permission, from a blog post by `Rob Miller <http://blog.nonsequitarian.org/>`_, originally published at - `http://blog.nonsequitarian.org/2010/much-ado-about-traversal/ - <http://blog.nonsequitarian.org/2010/much-ado-about-traversal/>`_. + http://blog.nonsequitarian.org/2010/much-ado-about-traversal/ . Traversal is an alternative to :term:`URL dispatch` which allows :app:`Pyramid` applications to map URLs to code. @@ -269,14 +268,14 @@ It might be possible, but it certainly won't be easy. The matching patterns are going to become complex quickly as you try to handle all of the edge cases. -With traversal, however, it's straightforward. 20 layers of nesting would be -no problem. :app:`Pyramid` will happily call ``__getitem__`` as many times -as it needs to, until it runs out of path segments or until a resource raises -a :exc:`KeyError`. Each resource only needs to know how to fetch its -immediate children, the traversal algorithm takes care of the rest. Also, -since the structure of the resource tree can live in the database and not in -the code, it's simple to let users modify the tree at runtime to set up their -own personalized "directory" structures. +With traversal, however, it's straightforward. Twenty layers of nesting +would be no problem. :app:`Pyramid` will happily call ``__getitem__`` as +many times as it needs to, until it runs out of path segments or until a +resource raises a :exc:`KeyError`. Each resource only needs to know how to +fetch its immediate children, the traversal algorithm takes care of the rest. +Also, since the structure of the resource tree can live in the database and +not in the code, it's simple to let users modify the tree at runtime to set +up their own personalized "directory" structures. Another use case in which traversal shines is when there is a need to support a context-dependent security policy. One example might be a document @@ -305,7 +304,6 @@ don't require it, great: stick with :term:`URL dispatch`. But if you're using :app:`Pyramid` and you ever find that you *do* need to support one of these use cases, you'll be glad you have traversal in your toolkit. -.. note:: - It is even possible to mix and match :term:`traversal` with +.. note:: It is even possible to mix and match :term:`traversal` with :term:`URL dispatch` in the same :app:`Pyramid` application. See the :ref:`hybrid_chapter` chapter for details. diff --git a/docs/narr/project.rst b/docs/narr/project.rst index c076c67ac..7e2730e97 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -137,16 +137,11 @@ project we name ``MyProject``: name during ``paster create`` by adding the project name to the command line, e.g. ``paster create -t pyramid_starter MyProject``. -.. note:: You may encounter an error when using ``paster create`` - if a dependent Python package is not installed. This will - result in a traceback ending in: - - .. code-block:: text - - pkg_resources.DistributionNotFound: <package name> - - Simply run ``bin/easy_install``, with the missing package - name from the error message, to work around this issue. +.. note:: You may encounter an error when using ``paster create`` if a + dependent Python package is not installed. This will result in a traceback + ending in ``pkg_resources.DistributionNotFound: <package name>``. + Simply run ``bin/easy_install``, with the missing package name from the + error message to work around this issue. As a result of invoking the ``paster create`` command, a project is created in a directory named ``MyProject``. That directory is a :term:`project` @@ -325,37 +320,34 @@ unconditionally. [chrism@vitaminf shellenv]$ ../bin/paster pshell --disable-ipython \ development.ini MyProject -.. warning:: +You should always use a section name argument that refers to the actual +``app`` section within the Paste configuration file that points at your +:app:`Pyramid` application *without any middleware wrapping*. In particular, +a section name is inappropriate as the second argument to ``pshell`` if the +configuration section it names is a ``pipeline`` rather than an ``app``. For +example, if you have the following ``.ini`` file content: + +.. code-block:: ini + :linenos: + + [app:MyProject] + use = egg:MyProject + reload_templates = true + debug_authorization = false + debug_notfound = false + debug_templates = true + default_locale_name = en + + [pipeline:main] + pipeline = + egg:WebError#evalerror + MyProject - You should always use a section name argument that refers to the actual - ``app`` section within the Paste configuration file that points at your - :app:`Pyramid` application *without any middleware wrapping*. In - particular, a section name is inappropriate as the second argument to - ``pshell`` if the configuration section it names is a ``pipeline`` rather - than an ``app``. For example, if you have the following ``.ini`` file - content: - - .. code-block:: guess - :linenos: - - [app:MyProject] - use = egg:MyProject - reload_templates = true - debug_authorization = false - debug_notfound = false - debug_templates = true - default_locale_name = en - - [pipeline:main] - pipeline = - egg:WebError#evalerror - MyProject - - Use ``MyProject`` instead of ``main`` as the section name argument to - ``pshell`` against the above ``.ini`` file (e.g. ``paster pshell - development.ini MyProject``). If you use ``main`` instead, an error will - occur. Use the most specific reference to your application within the - ``.ini`` file possible as the section name argument. +Use ``MyProject`` instead of ``main`` as the section name argument to +``pshell`` against the above ``.ini`` file (e.g. ``paster pshell +development.ini MyProject``). If you use ``main`` instead, an error will +occur. Use the most specific reference to your application within the +``.ini`` file possible as the section name argument. Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). @@ -511,8 +503,8 @@ describe, run, and test your application. ``setup.py``. #. ``MANIFEST.in`` is a :term:`distutils` "manifest" file, naming which files - should be included in a source distribution of the package when ``python - setup.py sdist`` is run. + should be included in a source distribution of the package when ``python + setup.py sdist`` is run. #. ``setup.py`` is the file you'll use to test and distribute your application. It is a standard :term:`setuptools` ``setup.py`` file. @@ -532,8 +524,10 @@ serve``, as well as the deployment settings provided to that application. The generated ``development.ini`` file looks like so: +.. latexbroken? + .. literalinclude:: MyProject/development.ini - :language: guess + :language: ini :linenos: This file contains several "sections" including ``[app:MyProject]``, diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 91c00057b..0b7cdb834 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -23,7 +23,7 @@ dictionary does not implement the Pyramid response interface, so you might believe that this example would fail. However, since a ``renderer`` is associated with the view callable through its :term:`view configuration` (in this case, using a ``renderer`` argument passed to -:func:`pyramid.view.view_config`), if the view does *not* return a Response +:func:`~pyramid.view.view_config`), if the view does *not* return a Response object, the renderer will attempt to convert the result of the view to a response on the developer's behalf. @@ -60,7 +60,7 @@ object serialization techniques. View configuration can vary the renderer associated with a view callable via the ``renderer`` attribute. For example, this call to -:meth:`pyramid.config.Configurator.add_view` associates the ``json`` renderer +:meth:`~pyramid.config.Configurator.add_view` associates the ``json`` renderer with a view callable: .. code-block:: python @@ -187,7 +187,7 @@ values serializable by :func:`json.dumps`. You can configure a view to use the JSON renderer by naming ``json`` as the ``renderer`` argument of a view configuration, e.g. by using -:meth:`pyramid.config.Configurator.add_view`: +:meth:`~pyramid.config.Configurator.add_view`: .. code-block:: python :linenos: @@ -428,21 +428,20 @@ following interface: class RendererFactory: def __init__(self, info): - """ Constructor: ``info`` will be an object having the - 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). - """ + """ Constructor: info will be an object having the 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). """ def __call__(self, value, system): - """ Call a 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 dictionary - containing available system values (e.g. ``view``, - ``context``, and ``request``). """ + """ Call a 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 + dictionary containing available system values + (e.g. view, context, and request). """ The formal interface definition of the ``info`` object passed to a renderer factory constructor is available as :class:`pyramid.interfaces.IRendererInfo`. @@ -457,14 +456,14 @@ There are essentially two different kinds of renderer factories: such as a template. - A renderer factory which expects to accept a token that does not represent - a filesystem path or a asset specification in the ``name`` + a filesystem path or an asset specification in the ``name`` attribute of the ``info`` object fed to its constructor. These renderer factories are registered with a ``name`` value that does not begin with a dot. These renderer factories are typically object serializers. .. sidebar:: Asset Specifications - A asset specification is a colon-delimited identifier for an + An asset specification is a colon-delimited identifier for an :term:`asset`. The colon separates a Python :term:`package` name from a package subpath. For example, the asset specification ``my.package:static/baz.css`` identifies the file named @@ -472,7 +471,7 @@ There are essentially two different kinds of renderer factories: :term:`package`. Here's an example of the registration of a simple renderer factory via -:meth:`pyramid.config.Configurator.add_renderer`: +:meth:`~pyramid.config.Configurator.add_renderer`: .. code-block:: python :linenos: @@ -539,9 +538,6 @@ ending with ``.jinja2`` in its ``renderer`` value. The ``name`` passed to the ``MyJinja2Renderer`` constructor will be the full value that was set as ``renderer=`` in the view configuration. -See also :ref:`renderer_directive` and -:meth:`pyramid.config.Configurator.add_renderer`. - Changing an Existing Renderer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -595,7 +591,7 @@ user instructing the view to use a template renderer with one that uses an XML-RPC renderer. This renderer would produce an XML-RPC representation of the data returned by an arbitrary view callable. -To use this feature, create a :class:`pyramid.events.NewRequest` +To use this feature, create a :class:`~pyramid.events.NewRequest` :term:`subscriber` which sniffs at the request data and which conditionally sets an ``override_renderer`` attribute on the request itself, which is the *name* of a registered renderer. For example: diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst index 895d6c1c6..a11466a87 100644 --- a/docs/narr/resources.rst +++ b/docs/narr/resources.rst @@ -36,8 +36,8 @@ application. Also: - The ``context`` and ``containment`` predicate arguments to - :meth:`pyramid.config.Configurator.add_view` (or a - :func:`pyramid.view.view_config` decorator) reference a resource class + :meth:`~pyramid.config.Configurator.add_view` (or a + :func:`~pyramid.view.view_config` decorator) reference a resource class or resource :term:`interface`. - A :term:`root factory` returns a resource. @@ -46,7 +46,7 @@ Also: view. - Various helpful :app:`Pyramid` API methods expect a resource as an - argument (e.g. :func:`pyramid.url.resource_url` and others). + argument (e.g. :func:`~pyramid.url.resource_url` and others). .. index:: single: resource tree @@ -162,9 +162,9 @@ you will reach the filesystem root directory. .. warning:: If your root resource has a ``__name__`` argument that is not ``None`` or the empty string, URLs returned by the - :func:`pyramid.url.resource_url` function and paths generated by - the :func:`pyramid.traversal.resource_path` and - :func:`pyramid.traversal.resource_path_tuple` APIs will be + :func:`~pyramid.url.resource_url` function and paths generated by + the :func:`~pyramid.traversal.resource_path` and + :func:`~pyramid.traversal.resource_path_tuple` APIs will be generated improperly. The value of ``__name__`` will be prepended to every path and URL generated (as opposed to a single leading slash or empty tuple element). @@ -205,12 +205,12 @@ In general, since so much :app:`Pyramid` infrastructure depends on location-aware resources, it's a good idea to make each resource in your tree location-aware. -.. _generating_the_url_of_a_resource: - .. index:: single: resource_url pair: generating; resource url +.. _generating_the_url_of_a_resource: + Generating The URL Of A Resource -------------------------------- @@ -231,7 +231,7 @@ The simplest call to :func:`~pyramid.url.resource_url` looks like this: url = resource_url(resource, request) The ``request`` passed to ``resource_url`` in the above example is an -instance of an :app:`Pyramid` :term:`request` object. +instance of a :app:`Pyramid` :term:`request` object. If the resource referred to as ``resource`` in the above example was the root resource, and the host that was used to contact the server was @@ -281,7 +281,7 @@ about virtually rooting a resource. The shortcut method of the :term:`request` named :meth:`pyramid.request.Request.resource_url` can be used instead of -:func:`pyramid.url.resource_url` to generate a resource URL. +:func:`~pyramid.url.resource_url` to generate a resource URL. For more information about generating resource URLs, see the documentation for :func:`pyramid.url.resource_url`. @@ -292,13 +292,13 @@ Overriding Resource URL Generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If a resource object implements a ``__resource_url__`` method, this method -will be called when :func:`pyramid.url.resource_url` is called to generate a +will be called when :func:`~pyramid.url.resource_url` is called to generate a URL for the resource, overriding the default URL returned for the resource by :func:`~pyramid.url.resource_url`. The ``__resource_url__`` hook is passed two arguments: ``request`` and ``info``. ``request`` is the :term:`request` object passed to -:func:`pyramid.url.resource_url`. ``info`` is a dictionary with two +:func:`~pyramid.url.resource_url`. ``info`` is a dictionary with two keys: ``physical_path`` @@ -331,7 +331,7 @@ or port number of the generated URL. Note that the URL generated by ``__resource_url__`` should be fully qualified, should end in a slash, and should not contain any query string or anchor elements (only path elements) to work best with -:func:`pyramid.url.resource_url`. +:func:`~pyramid.url.resource_url`. Generating the Path To a Resource --------------------------------- @@ -350,7 +350,7 @@ character. If ``resource`` in the example above was accessible in the tree as ``root['a']['b']``, the above example would generate the string ``/a/b``. -Any positional arguments passed in to :func:`pyramid.traversal.resource_path` +Any positional arguments passed in to :func:`~pyramid.traversal.resource_path` will be appended as path segments to the end of the resource path. .. code-block:: python @@ -618,7 +618,7 @@ configuration, see :ref:`using_resource_interfaces`. Finding a Resource With a Class or Interface in Lineage ------------------------------------------------------- -Use the :func:`pyramid.traversal.find_interface` API to locate a parent that +Use the :func:`~pyramid.traversal.find_interface` API to locate a parent that is of a particular Python class, or which implements some :term:`interface`. For example, if your resource tree is composed as follows: @@ -669,7 +669,7 @@ These can be used to walk down a resource tree, or conveniently locate one resource "inside" another. Some APIs in :ref:`security_module` accept a resource object as a parameter. -For example, the :func:`pyramid.security.has_permission` API accepts a +For example, the :func:`~pyramid.security.has_permission` API accepts a resource object as one of its arguments; the ACL is obtained from this resource or one of its ancestors. Other APIs in the :mod:`pyramid.security` module also accept :term:`context` as an argument, and a context is always a diff --git a/docs/narr/router.rst b/docs/narr/router.rst index 782098bac..11f84d4ea 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -29,10 +29,10 @@ processing? #. The :term:`application registry` and the :term:`request` object created in the last step are pushed on to the :term:`thread local` stack that :app:`Pyramid` uses to allow the functions named - :func:`pyramid.threadlocal.get_current_request` and - :func:`pyramid.threadlocal.get_current_registry` to work. + :func:`~pyramid.threadlocal.get_current_request` and + :func:`~pyramid.threadlocal.get_current_registry` to work. -#. A :class:`pyramid.events.NewRequest` :term:`event` is sent to any +#. A :class:`~pyramid.events.NewRequest` :term:`event` is sent to any subscribers. #. If any :term:`route` has been defined within application @@ -46,7 +46,7 @@ processing? ``matched_route`` attributes are added to the request object; the former contains a dictionary representing the matched dynamic elements of the request's ``PATH_INFO`` value, the latter contains - the :class:`pyramid.interfaces.IRoute` object representing the + the :class:`~pyramid.interfaces.IRoute` object representing the route which matched. The root object associated with the route found is also generated: if the :term:`route configuration` which matched has an associated a ``factory`` argument, this factory is @@ -74,7 +74,7 @@ processing? they can be accessed via e.g. ``request.context`` within :term:`view` code. -#. A :class:`pyramid.events.ContextFound` :term:`event` is +#. A :class:`~pyramid.events.ContextFound` :term:`event` is sent to any subscribers. #. :app:`Pyramid` looks up a :term:`view` callable using the @@ -83,7 +83,7 @@ processing? the context, the type of the request, and the value of the view name, and any :term:`predicate` attributes applied to the view configuration), :app:`Pyramid` raises a - :class:`pyramid.exceptions.NotFound` exception, which is meant + :class:`~pyramid.exceptions.NotFound` exception, which is meant to be caught by a surrounding exception handler. #. If a view callable was found, :app:`Pyramid` attempts to call @@ -97,14 +97,14 @@ processing? security information attached to the context. If it returns ``True``, :app:`Pyramid` calls the view callable to obtain a response. If it returns ``False``, it raises a - :class:`pyramid.exceptions.Forbidden` exception, which is meant + :class:`~pyramid.exceptions.Forbidden` exception, which is meant to be called by a surrounding exception handler. #. If any exception was raised within a :term:`root factory`, by :term:`traversal`, by a :term:`view callable` or by :app:`Pyramid` itself (such as when it raises - :class:`pyramid.exceptions.NotFound` or - :class:`pyramid.exceptions.Forbidden`), the router catches the + :class:`~pyramid.exceptions.NotFound` or + :class:`~pyramid.exceptions.Forbidden`), the router catches the exception, and attaches it to the request as the ``exception`` attribute. It then attempts to find a :term:`exception view` for the exception that was caught. If it finds an exception view @@ -116,15 +116,15 @@ processing? successfully generated by a normal :term:`view callable` or an :term:`exception view` callable. :app:`Pyramid` will attempt to execute any :term:`response callback` functions attached via - :meth:`pyramid.request.Request.add_response_callback`. A - :class:`pyramid.events.NewResponse` :term:`event` is then sent to any + :meth:`~pyramid.request.Request.add_response_callback`. A + :class:`~pyramid.events.NewResponse` :term:`event` is then sent to any subscribers. The response object's ``app_iter``, ``status``, and ``headerlist`` attributes are then used to generate a WSGI response. The response is sent back to the upstream WSGI server. #. :app:`Pyramid` will attempt to execute any :term:`finished callback` functions attached via - :meth:`pyramid.request.Request.add_finished_callback`. + :meth:`~pyramid.request.Request.add_finished_callback`. #. The :term:`thread local` stack is popped. diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 10a6c3db3..6e07c9338 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -72,14 +72,14 @@ Enabling an Authorization Policy Imperatively ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Passing an ``authorization_policy`` argument to the constructor of the -:class:`pyramid.config.Configurator` class enables an +:class:`~pyramid.config.Configurator` class enables an authorization policy. You must also enable an :term:`authentication policy` in order to enable the authorization policy. This is because authorization, in general, depends upon authentication. Use the ``authentication_policy`` argument to the -:class:`pyramid.config.Configurator` class during +:class:`~pyramid.config.Configurator` class during application setup to specify an authentication policy. For example: @@ -97,7 +97,7 @@ For example: authorization_policy=authorization_policy) .. note:: the ``authentication_policy`` and ``authorization_policy`` - arguments may also be passed to the Configurator as :ref:`dotted + arguments may also be passed to the Configurator as :term:`dotted Python name` values, each representing the dotted name path to a suitable implementation global defined at Python module scope. @@ -187,11 +187,9 @@ These APIs are in support of configuring a default permission for an application: - The ``default_permission`` constructor argument to the - :mod:`pyramid.config.Configurator` constructor. + :mod:`~pyramid.config.Configurator` constructor. -- The - :meth:`pyramid.config.Configurator.set_default_permission` - method. +- The :meth:`pyramid.config.Configurator.set_default_permission` method. When a default permission is registered: @@ -204,6 +202,13 @@ When a default permission is registered: and the view is registered *without* a permission (making it available to all callers regardless of their credentials). +.. warning:: + + When you register a default permission, *all* views (even :term:`exception + view` views) are protected by a permission. For all views which are truly + meant to be anonymously accessible, you will need to associate the view's + configuration with the ``__no_permission_required__`` permission. + .. index:: single: ACL single: access control list @@ -306,9 +311,7 @@ authentication system provides group information and the effective :term:`authentication policy` policy is written to respect group information. For example, the :class:`pyramid.authentication.RepozeWho1AuthenicationPolicy` respects group -information if you configure it with a ``callback``. See -:ref:`authentication_policies_directives_section` for more information about -the ``callback`` attribute. +information if you configure it with a ``callback``. Each ACE in an ACL is processed by an authorization policy *in the order dictated by the ACL*. So if you have an ACL like this: @@ -539,7 +542,7 @@ one of :data:`pyramid.security.ACLAllowed`, ``msg`` attribute, which is a string indicating why the permission was denied or allowed. Introspecting this information in the debugger or via print statements when a call to -:func:`pyramid.security.has_permission` fails is often useful. +:func:`~pyramid.security.has_permission` fails is often useful. .. index:: single: authentication policy (creating) @@ -584,7 +587,7 @@ that implements the following interface: current user on subsequent requests. """ After you do so, you can pass an instance of such a class into the -:class:`pyramid.config.Configurator` class at configuration +:class:`~pyramid.config.Configurator` class at configuration time as ``authentication_policy`` to use it. .. index:: @@ -603,7 +606,7 @@ otherwise specified. In some cases, it's useful to be able to use a different authorization policy than the default -:class:`pyramid.authorization.ACLAuthorizationPolicy`. For +:class:`~pyramid.authorization.ACLAuthorizationPolicy`. For example, it might be desirable to construct an alternate authorization policy which allows the application to use an authorization mechanism that does not involve :term:`ACL` objects. @@ -634,5 +637,5 @@ following interface: used.""" After you do so, you can pass an instance of such a class into the -:class:`pyramid.config.Configurator` class at configuration +:class:`~pyramid.config.Configurator` class at configuration time as ``authorization_policy`` to use it. diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 0ed52b563..97e3ebc55 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -42,7 +42,7 @@ tampered with. You can configure this session factory in your :app:`Pyramid` application by using the ``session_factory`` argument to the -:class:`pyramid.config.Configurator` class: +:class:`~pyramid.config.Configurator` class: .. code-block:: python :linenos: diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 1b21cb516..e2c43b17e 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -82,7 +82,7 @@ Here's a high-level time-ordered overview of what happens when you press Our generated ``development.ini`` file looks like so: .. literalinclude:: MyProject/development.ini - :language: guess + :language: ini :linenos: In this case, the ``myproject.__init__:main`` function referred to by the @@ -94,7 +94,7 @@ Here's a high-level time-ordered overview of what happens when you press 'default_locale_name':'en'}``. #. The ``main`` function first constructs a - :class:`pyramid.config.Configurator` instance, passing a root resource + :class:`~pyramid.config.Configurator` instance, passing a root resource factory (constructor) to it as its ``root_factory`` argument, and ``settings`` dictionary captured via the ``**settings`` kwarg as its ``settings`` argument. @@ -109,18 +109,18 @@ Here's a high-level time-ordered overview of what happens when you press ``debug_authorization``, etc. #. The ``main`` function then calls various methods on the an instance of the - class :class:`pyramid.config.Configurator` method. The intent of + class :class:`~pyramid.config.Configurator` method. The intent of calling these methods is to populate an :term:`application registry`, which represents the :app:`Pyramid` configuration related to the application. -#. The :meth:`pyramid.config.Configurator.make_wsgi_app` method is called. +#. The :meth:`~pyramid.config.Configurator.make_wsgi_app` method is called. The result is a :term:`router` instance. The router is associated with the :term:`application registry` implied by the configurator previously populated by other methods run against the Configurator. The router is a WSGI application. -#. A :class:`pyramid.events.ApplicationCreated` event is emitted (see +#. A :class:`~pyramid.events.ApplicationCreated` event is emitted (see :ref:`events_chapter` for more information about events). #. Assuming there were no errors, the ``main`` function in ``myproject`` @@ -142,7 +142,7 @@ Deployment Settings ------------------- Note that an augmented version of the values passed as ``**settings`` to the -:class:`pyramid.config.Configurator` constructor will be available in +:class:`~pyramid.config.Configurator` constructor will be available in :app:`Pyramid` :term:`view callable` code as ``request.registry.settings``. You can create objects you wish to access later from view code, and put them into the dictionary you pass to the configurator as ``settings``. They will diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index f50f6c173..a9cdc13fb 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -203,7 +203,7 @@ may set attributes on the response that influence these values. Here's an example of changing the content-type and status of the response object returned by -:func:`pyramid.renderers.render_to_response`: +:func:`~pyramid.renderers.render_to_response`: .. code-block:: python :linenos: @@ -219,7 +219,7 @@ response object returned by return response Here's an example of manufacturing a response object using the result -of :func:`pyramid.renderers.render` (a string): +of :func:`~pyramid.renderers.render` (a string): .. code-block:: python :linenos: @@ -247,8 +247,8 @@ System Values Used During Rendering ----------------------------------- When a template is rendered using -:func:`pyramid.renderers.render_to_response` or -:func:`pyramid.renderers.render`, the renderer representing the +:func:`~pyramid.renderers.render_to_response` or +:func:`~pyramid.renderers.render`, the renderer representing the template will be provided with a number of *system* values. These values are provided in a dictionary to the renderer and include: @@ -282,7 +282,7 @@ variables. Templates Used as Renderers via Configuration --------------------------------------------- -An alternative to using :func:`pyramid.renderers.render_to_response` +An alternative to using :func:`~pyramid.renderers.render_to_response` to render templates manually in your view callable code, is to specify the template as a :term:`renderer` in your *view configuration*. This can be done with any of the @@ -299,7 +299,7 @@ The association of a template as a renderer for a :term:`view configuration` makes it possible to replace code within a :term:`view callable` that handles the rendering of a template. -Here's an example of using a :class:`pyramid.view.view_config` +Here's an example of using a :class:`~pyramid.view.view_config` decorator to specify a :term:`view configuration` that names a template renderer: @@ -448,7 +448,8 @@ Here's what a simple :term:`Chameleon` ZPT template used under <body> <h1 class="title">Welcome to <code>${project}</code>, an application generated by the <a - href="http://docs.pylonsproject.org/projects/pyramid/dev/">pyramid</a> web + href="http://docs.pylonsproject.org/projects/pyramid/dev/" + >pyramid</a> web application framework.</h1> </body> </html> @@ -456,8 +457,8 @@ Here's what a simple :term:`Chameleon` ZPT template used under Note the use of :term:`Genshi` -style ``${replacements}`` above. This is one of the ways that :term:`Chameleon` ZPT differs from standard ZPT. The above template expects to find a ``project`` key in the set -of keywords passed in to it via :func:`pyramid.renderers.render` or -:func:`pyramid.renderers.render_to_response`. Typical ZPT +of keywords passed in to it via :func:`~pyramid.renderers.render` or +:func:`~pyramid.renderers.render_to_response`. Typical ZPT attribute-based syntax (e.g. ``tal:content`` and ``tal:replace``) also works in these templates. @@ -480,7 +481,7 @@ passing the macro template, or even the macro itself, *into* the rendered template. To do this you can use the :func:`pyramid.renderers.get_renderer` API to retrieve the macro template, and pass it into the template being rendered via the dictionary returned by the view. For example, using a -:term:`view configuration` via a :class:`pyramid.view.view_config` decorator +:term:`view configuration` via a :class:`~pyramid.view.view_config` decorator that uses a :term:`renderer`: .. code-block:: python @@ -606,7 +607,7 @@ configure your application development environment so that exceptions generated by Chameleon during template compilation and execution will contain nicer debugging information. -.. warning:: template-debugging behavior is not recommended for +.. warning:: Template-debugging behavior is not recommended for production sites as it slows renderings; it's usually only desirable during development. @@ -740,8 +741,8 @@ look like: <body> <h1 class="title">Welcome to <code>${project}</code>, an application generated by the <a - href="http://docs.pylonsproject.org/projects/pyramid/dev/">pyramid</a> web - application framework.</h1> + href="http://docs.pylonsproject.org/projects/pyramid/dev/" + >pyramid</a> web application framework.</h1> </body> </html> @@ -765,7 +766,7 @@ appear immediately without needing to restart the application process. environment so that a change to a template will be automatically detected, and the template will be reloaded on the next rendering. -.. warning:: auto-template-reload behavior is not recommended for +.. warning:: Auto-template-reload behavior is not recommended for production sites as it slows rendering slightly; it's usually only desirable during development. diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index e166962f2..bd45388c2 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -118,7 +118,7 @@ of using this feature: testing.tearDown() The above will make sure that -:func:`pyramid.threadlocal.get_current_registry` called within a test +:func:`~pyramid.threadlocal.get_current_registry` called within a test case method of ``MyTest`` will return the :term:`application registry` associated with the ``config`` Configurator instance. Each test case method attached to ``MyTest`` will use an isolated registry. @@ -128,7 +128,7 @@ functions accepts various arguments that influence the environment of the test. See the :ref:`testing_module` chapter for information about the extra arguments supported by these functions. -If you also want to make :func:`pyramid.get_current_request` return something +If you also want to make :func:`~pyramid.get_current_request` return something other than ``None`` during the course of a single test, you can pass a :term:`request` object into the :func:`pyramid.testing.setUp` within the ``setUp`` method of your test: @@ -150,9 +150,9 @@ other than ``None`` during the course of a single test, you can pass a If you pass a :term:`request` object into :func:`pyramid.testing.setUp` within your test case's ``setUp``, any test method attached to the ``MyTest`` test case that directly or indirectly calls -:func:`pyramid.threadlocal.get_current_request` will receive the request +:func:`~pyramid.threadlocal.get_current_request` will receive the request object. Otherwise, during testing, -:func:`pyramid.threadlocal.get_current_request` will return ``None``. +:func:`~pyramid.threadlocal.get_current_request` will return ``None``. We use a "dummy" request implementation supplied by :class:`pyramid.testing.DummyRequest` because it's easier to construct than a "real" :app:`Pyramid` request object. @@ -163,8 +163,8 @@ What? Thread local data structures are always a bit confusing, especially when they're used by frameworks. Sorry. So here's a rule of thumb: if you don't *know* whether you're calling code that uses the -:func:`pyramid.threadlocal.get_current_registry` or -:func:`pyramid.threadlocal.get_current_request` functions, or you don't care +:func:`~pyramid.threadlocal.get_current_registry` or +:func:`~pyramid.threadlocal.get_current_request` functions, or you don't care about any of this, but you still want to write test code, just always call :func:`pyramid.testing.setUp` in your test's ``setUp`` method and :func:`pyramid.testing.tearDown` in your tests' ``tearDown`` method. This @@ -199,7 +199,7 @@ function. return {'greeting':'hello'} Without doing anything special during a unit test, the call to -:func:`pyramid.security.has_permission` in this view function will always +:func:`~pyramid.security.has_permission` in this view function will always return a ``True`` value. When a :app:`Pyramid` application starts normally, it will populate a :term:`application registry` using :term:`configuration declaration` calls made against a :term:`Configurator`. But if this @@ -255,7 +255,7 @@ be found when ``setup.py test`` is run. It has two test methods. The first test method, ``test_view_fn_forbidden`` tests the ``view_fn`` when the authentication policy forbids the current user the ``edit`` permission. Its third line registers a "dummy" "non-permissive" authorization policy -using the :meth:`pyramid.config.Configurator.testing_securitypolicy` method, +using the :meth:`~pyramid.config.Configurator.testing_securitypolicy` method, which is a special helper method for unit testing. We then create a :class:`pyramid.testing.DummyRequest` object which simulates @@ -264,13 +264,13 @@ request object that requires less setup than a "real" :app:`Pyramid` request. We call the function being tested with the manufactured request. When the function is called, :func:`pyramid.security.has_permission` will call the "dummy" authentication policy we've registered through -:meth:`pyramid.config.Configuration.testing_securitypolicy`, which denies +:meth:`~pyramid.config.Configuration.testing_securitypolicy`, which denies access. We check that the view function raises a :exc:`Forbidden` error. The second test method, named ``test_view_fn_allowed`` tests the alternate case, where the authentication policy allows access. Notice that we pass different values to -:meth:`pyramid.config.Configurator.testing_securitypolicy` to obtain this +:meth:`~pyramid.config.Configurator.testing_securitypolicy` to obtain this result. We assert at the end of this that the view function returns a value. Note that the test calls the :func:`pyramid.testing.setUp` function in its @@ -278,7 +278,7 @@ Note that the test calls the :func:`pyramid.testing.setUp` function in its ``tearDown`` method. We assign the result of :func:`pyramid.testing.setUp` as ``config`` on the unittest class. This is a :term:`Configurator` object and all methods of the configurator can be called as necessary within -tests. If you use any of the :class:`pyramid.config.Configurator` APIs during +tests. If you use any of the :class:`~pyramid.config.Configurator` APIs during testing, be sure to use this pattern in your test case's ``setUp`` and ``tearDown``; these methods make sure you're using a "fresh" :term:`application registry` per test run. @@ -357,7 +357,7 @@ after accessing some values that require a fully set up environment. str(len(body)))) Unless you cannot avoid it, you should prefer writing unit tests that use the -:class:`pyramid.config.Configurator` API to set up the right "mock" +:class:`~pyramid.config.Configurator` API to set up the right "mock" registrations rather than creating an integration test. Unit tests will run faster (because they do less for each test) and the result of a unit test is usually easier to make assertions about. diff --git a/docs/narr/threadlocals.rst b/docs/narr/threadlocals.rst index 13bfe41cb..909f643a0 100644 --- a/docs/narr/threadlocals.rst +++ b/docs/narr/threadlocals.rst @@ -32,7 +32,7 @@ bad idea, at least if code readability counts as an important concern. For historical reasons, however, thread local variables are indeed consulted by various :app:`Pyramid` API functions. For example, the implementation of the :mod:`pyramid.security` function named -:func:`pyramid.security.authenticated_userid` retrieves the thread +:func:`~pyramid.security.authenticated_userid` retrieves the thread local :term:`application registry` as a matter of course to find an :term:`authentication policy`. It uses the :func:`pyramid.threadlocal.get_current_registry` function to @@ -43,8 +43,8 @@ allows arbitrary authentication policies to be "plugged in". When they need to do so, :app:`Pyramid` internals use two API functions to retrieve the :term:`request` and :term:`application -registry`: :func:`pyramid.threadlocal.get_current_request` and -:func:`pyramid.threadlocal.get_current_registry`. The former +registry`: :func:`~pyramid.threadlocal.get_current_request` and +:func:`~pyramid.threadlocal.get_current_registry`. The former returns the "current" request; the latter returns the "current" registry. Both ``get_current_*`` functions retrieve an object from a thread-local data structure. These API functions are documented in @@ -88,17 +88,17 @@ the :mod:`pyramid.scripting` API will never cause any Router code to be executed. However, the :mod:`pyramid.scripting` APIs also push some values on to the thread locals stack as a matter of course. Such scripts should expect the -:func:`pyramid.threadlocal.get_current_request` function to always +:func:`~pyramid.threadlocal.get_current_request` function to always return ``None``, and should expect the -:func:`pyramid.threadlocal.get_current_registry` function to return +:func:`~pyramid.threadlocal.get_current_registry` function to return exactly the same :term:`application registry` for every request. Why You Shouldn't Abuse Thread Locals ------------------------------------- You probably should almost never use the -:func:`pyramid.threadlocal.get_current_request` or -:func:`pyramid.threadlocal.get_current_registry` functions, except +:func:`~pyramid.threadlocal.get_current_request` or +:func:`~pyramid.threadlocal.get_current_registry` functions, except perhaps in tests. In particular, it's almost always a mistake to use ``get_current_request`` or ``get_current_registry`` in application code because its usage makes it possible to write code that can be @@ -134,7 +134,7 @@ follows: application depend upon it) means you're forming a dependency in the wrong direction. -Use of the :func:`pyramid.threadlocal.get_current_request` function +Use of the :func:`~pyramid.threadlocal.get_current_request` function in application code *is* still useful in very limited circumstances. As a rule of thumb, usage of ``get_current_request`` is useful **within code which is meant to eventually be removed**. For @@ -151,7 +151,7 @@ time, the older implementation code is disused and the hack that uses ``get_current_request`` is removed. This would be an appropriate place to use the ``get_current_request``. -Use of the :func:`pyramid.threadlocal.get_current_registry` +Use of the :func:`~pyramid.threadlocal.get_current_registry` function should be limited to testing scenarios. The registry made current by use of the :meth:`pyramid.config.Configurator.begin` method during a diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst index a858644ca..b3747be61 100644 --- a/docs/narr/traversal.rst +++ b/docs/narr/traversal.rst @@ -127,7 +127,7 @@ passing it to an instance of a :term:`Configurator` named ``config``: config = Configurator(root_factory=Root) The ``root_factory`` argument to the -:class:`pyramid.config.Configurator` constructor registers this root +:class:`~pyramid.config.Configurator` constructor registers this root factory to be called to generate a root resource whenever a request enters the application. The root factory registered this way is also known as the global root factory. A root factory can alternately be @@ -236,8 +236,8 @@ because they are almost always used together. A Description of The Traversal Algorithm ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a user requests a page from your :mod:`traversal` -powered application, -the system uses this algorithm to find a :term:`context` resource and a +When a user requests a page from your traversal-powered application, the +system uses this algorithm to find a :term:`context` resource and a :term:`view name`. #. The request for the page is presented to the :app:`Pyramid` diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 44396e024..cab5f85fa 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -95,9 +95,8 @@ Route Configuration That Names a View Callable When a route configuration declaration names a ``view`` attribute, the value of the attribute will reference a :term:`view callable`. This view callable will be invoked when the route matches. A view callable, as described in -:ref:`view_chapter`, is developer-supplied code that "does stuff" as the -result of a request. For more information about how to create view -callables, see :ref:`views_chapter`. +:ref:`views_chapter`, is developer-supplied code that "does stuff" as the +result of a request. Here's an example route configuration that references a view callable: @@ -126,49 +125,6 @@ When a route configuration names a ``view`` attribute, the :term:`view callable` named as that ``view`` attribute will always be found and invoked when the associated route pattern matches during a request. -Route View Callable Registration and Lookup Details -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -The purpose of making it possible to specify a view callable within a route -configuration is to prevent developers from needing to deeply understand the -details of :term:`resource location` and :term:`view lookup`. When a route -names a view callable as a ``view`` argument, and a request enters the system -which matches the pattern of the route, the result is simple: the view -callable associated with the route is invoked with the request that caused -the invocation. - -For most usage, you needn't understand more than this; how it works is an -implementation detail. In the interest of completeness, however, we'll -explain how it *does* work in the this section. You can skip it if you're -uninterested. - -When a ``view`` attribute is attached to a route configuration, -:app:`Pyramid` ensures that a :term:`view configuration` is registered that -will always be found when the route pattern is matched during a request. To -do so: - -- A special route-specific :term:`interface` is created at startup time for - each route configuration declaration. - -- When a route configuration declaration mentions a ``view`` attribute, a - :term:`view configuration` is registered at startup time. This view - configuration uses the route-specific interface as a :term:`request` type. - -- At runtime, when a request causes any route to match, the :term:`request` - object is decorated with the route-specific interface. - -- The fact that the request is decorated with a route-specific interface - causes the view lookup machinery to always use the view callable registered - using that interface by the route configuration to service requests that - match the route pattern. - -In this way, we supply a shortcut to the developer. Under the hood, the -:term:`resource location` and :term:`view lookup` subsystems provided by -:app:`Pyramid` are still being utilized, but in a way which does not require -a developer to understand either of them in detail. It also means that we -can allow a developer to combine :term:`URL dispatch` and :term:`traversal` -in various exceptional cases as documented in :ref:`hybrid_chapter`. - .. index:: single: route path pattern syntax @@ -202,12 +158,12 @@ replacement marker (e.g. ``{foo}``) or a certain combination of both. A replacement marker does not need to be preceded by a ``/`` character. A replacement marker is in the format ``{name}``, where this means "accept -any characters up to the next non-alphanumeric character and use this as the -``name`` :term:`matchdict` value." A matchdict is the dictionary -representing the dynamic parts extracted from a URL based on the routing -pattern. It is available as ``request.matchdict``. For example, the -following pattern defines one literal segment (``foo``) and two replacement -markers (``baz``, and ``bar``): +any characters up to the next slash character and use this as the ``name`` +:term:`matchdict` value." A matchdict is the dictionary representing the +dynamic parts extracted from a URL based on the routing pattern. It is +available as ``request.matchdict``. For example, the following pattern +defines one literal segment (``foo``) and two replacement markers (``baz``, +and ``bar``): .. code-block:: text @@ -258,11 +214,12 @@ that a replacement marker should match only a specific set of characters as defined by a regular expression, you must use a slightly extended form of replacement marker syntax. Within braces, the replacement marker name must be followed by a colon, then directly thereafter, the regular expression. -For example, under the hood, the replacement marker ``{foo}`` can more -verbosely be spelled as ``{foo:[^/]+}``. The *default* regular expression -associated with a replacement marker ``[^/]+`` matches one or more characters -which are not a slash. You can use an arbitrary regular expression here to -match a sequence of characters. +The *default* regular expression associated with a replacement marker +``[^/]+`` matches one or more characters which are not a slash. For example, +under the hood, the replacement marker ``{foo}`` can more verbosely be +spelled as ``{foo:[^/]+}``. You can change this to be an arbitrary regular +expression to match an arbitrary sequence of characters, such as +``{foo:\d+}`` to match only digits. It is possible to use two replacement markers without any literal characters between them, for instance ``/{foo}{bar}``. However, this would be a @@ -371,7 +328,7 @@ are added to the application at startup time. This is unlike :term:`traversal`, which depends on emergent behavior which happens as a result of traversing a resource tree. -For routes added via the :mod:`pyramid.config.Configurator.add_route` method, +For routes added via the :mod:`~pyramid.config.Configurator.add_route` method, the order that routes are evaluated is the order in which they are added to the configuration imperatively. @@ -428,12 +385,14 @@ Route Configuration Arguments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Route configuration ``add_route`` statements may specify a large number of -arguments. +arguments. They are documented as part of the API documentation at +:meth:`pyramid.config.Configurator.add_route`. Many of these arguments are :term:`route predicate` arguments. A route predicate argument specifies that some aspect of the request must be true for the associated route to be considered a match during the route matching -process. +process. Examples of route predicate arguments are ``pattern``, ``xhr``, and +``request_method``. Other arguments are view configuration related arguments. These only have an effect when the route configuration names a ``view``. @@ -441,201 +400,13 @@ effect when the route configuration names a ``view``. Other arguments are ``name`` and ``factory``. These arguments represent neither predicates nor view configuration information. -**Non-Predicate Arguments** - -``name`` - The name of the route, e.g. ``myroute``. This attribute is required. It - must be unique among all defined routes in a given application. - -``factory`` - A Python object (often a function or a class) or a :term:`dotted Python - name` to such an object that will generate a :app:`Pyramid` resource object - as the :term:`root` when this route matches. For example, - ``mypackage.resources.MyFactoryClass``. If this argument is not specified, - the traversal root factory will be used. - -``traverse`` - If you would like to cause the :term:`context` resource to be something - other than the :term:`root` resource object when this route matches, you - can spell a traversal pattern as the ``traverse`` argument. This traversal - pattern will be used as the traversal path: traversal will begin at the - root object implied by this route (either the global root, or the object - returned by the ``factory`` associated with this route). - - The syntax of the ``traverse`` argument is the same as it is for - ``pattern``. For example, if 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 - ``/articles/1/edit``), the traversal path will be generated as ``/1``. - This means that the root object's ``__getitem__`` will be called with the - name ``1`` during the traversal phase. If the ``1`` object exists, it will - become the :term:`context` resource of the request. - :ref:`traversal_chapter` has more information about traversal. - - If the traversal path contains segment marker names which are not present - in the ``pattern`` argument, a runtime error will occur. The ``traverse`` - pattern should not contain segment markers that do not exist in the - ``pattern``. - - A similar combining of routing and traversal is available when a route is - matched which contains a ``*traverse`` remainder marker in its pattern (see - :ref:`using_traverse_in_a_route_pattern`). The ``traverse`` argument - allows you to associate route patterns with an arbitrary traversal path - without using a a ``*traverse`` remainder marker; instead you can use other - match information. - - Note that the ``traverse`` argument is ignored when attached to a route - that has a ``*traverse`` remainder marker in its pattern. - -**Predicate Arguments** - -``pattern`` - The path of the route e.g. ``ideas/{idea}``. This argument is required. - See :ref:`route_path_pattern_syntax` for information about the syntax of - route paths. If the path doesn't match the current URL, route matching - continues. - - .. note:: In earlier releases of this framework, this argument existed - as ``path``. ``path`` continues to work as an alias for - ``pattern``. - -``xhr`` - This value should be either ``True`` or ``False``. If this value is - specified and is ``True``, the :term:`request` must possess an - ``HTTP_X_REQUESTED_WITH`` (aka ``X-Requested-With``) header for this route - to match. This is useful for detecting AJAX requests issued from jQuery, - Prototype and other Javascript libraries. If this predicate returns - ``False``, route matching continues. - -``request_method`` - A string representing an HTTP method name, e.g. ``GET``, ``POST``, - ``HEAD``, ``DELETE``, ``PUT``. If this argument is not specified, this - route will match if the request has *any* request method. If this - predicate returns ``False``, route matching continues. - -``path_info`` - This value represents a regular expression pattern that will be tested - against the ``PATH_INFO`` WSGI environment variable. If the regex matches, - this predicate will return ``True``. If this predicate returns ``False``, - route matching continues. - -``request_param`` - This value can be any string. A view declaration with this argument - ensures that the associated route will only match when the request has a - key in the ``request.params`` dictionary (an HTTP ``GET`` or ``POST`` - variable) that has a name which matches the supplied value. If the value - supplied as the argument has a ``=`` sign in it, - e.g. ``request_params="foo=123"``, then the key (``foo``) must both exist - in the ``request.params`` dictionary, and the value must match the right - hand side of the expression (``123``) for the route to "match" the current - request. If this predicate returns ``False``, route matching continues. - -``header`` - This argument represents an HTTP header name or a header name/value pair. - If the argument contains a ``:`` (colon), it will be considered a - name/value pair (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``). If - the value contains a colon, the value portion should be a regular - expression. If the value does not contain a colon, the entire value will - be considered to be the header name (e.g. ``If-Modified-Since``). If the - value evaluates to a header name only without a value, the header specified - by the name must be present in the request for this predicate to be true. - If the value evaluates to a header name/value pair, the header specified by - the name must be present in the request *and* the regular expression - specified as the value must match the header value. Whether or not the - value represents a header name or a header name/value pair, the case of the - header name is not significant. If this predicate returns ``False``, route - matching continues. - -``accept`` - This value represents a match query for one or more mimetypes in the - ``Accept`` HTTP request header. If this value is specified, it must be in - one of the following forms: a mimetype match token in the form - ``text/plain``, a wildcard mimetype match token in the form ``text/*`` or a - match-all wildcard mimetype match token in the form ``*/*``. If any of the - forms matches the ``Accept`` header of the request, this predicate will be - true. If this predicate returns ``False``, route matching continues. - -``custom_predicates`` - This value should be a sequence of references to custom predicate - callables. Use custom predicates when no set of predefined predicates does - what you need. Custom predicates can be combined with predefined - predicates as necessary. Each custom predicate callable should accept two - arguments: ``info`` and ``request`` and should return either ``True`` or - ``False`` after doing arbitrary evaluation of the context resource and/or - the request. If all callables return ``True``, the associated route will - be considered viable for a given request. If any custom predicate returns - ``False``, route matching continues. See :ref:`custom_route_predicates` - for more information. - -**View-Related Arguments** - -``view`` - A Python object or a :term:`dotted Python name` to such an object that will - be used as a view callable when this route - matches. e.g. ``mypackage.views.my_view``. - -``view_context`` - A class or an :term:`interface` (or a :term:`dotted Python name` to such an - object) that the :term:`context` resource should possess for the view named - by the route to be used. If this attribute is not specified, the default - (``None``) will be used. - - If the ``view`` argument is not provided, this argument has no effect. - - This attribute can also be spelled as ``for_`` or ``view_for``. - -``view_permission`` - The permission name required to invoke the view associated with this route. - e.g. ``edit``. (see :ref:`using_security_with_urldispatch` for more - information about permissions). - - If the ``view`` attribute is not provided, this argument has no effect. - - This argument can also be spelled as ``permission``. - -``view_renderer`` - This is either a single string term (e.g. ``json``) or a string implying a - path or :term:`asset specification` (e.g. ``templates/views.pt``). If the - renderer value is a single term (does not contain a dot ``.``), the - specified term will be used to look up a renderer implementation, and that - renderer implementation will be used to construct a response from the view - return value. If the renderer term contains a dot (``.``), the specified - term will be treated as a path, and the filename extension of the last - element in the path will be used to look up the renderer implementation, - which will be passed the full path. The renderer implementation will be - used to construct a response from the view return value. See - :ref:`views_which_use_a_renderer` for more information. - - If the ``view`` argument is not provided, this argument has no effect. - - This argument can also be spelled as ``renderer``. - -``view_attr`` - The view machinery defaults to using the ``__call__`` method of the view - callable (or the function itself, if the view callable is a function) to - obtain a response dictionary. The ``attr`` value allows you to vary the - method attribute used to obtain the response. For example, if your view - was a class, and the class has a method named ``index`` and you wanted to - use this method instead of the class' ``__call__`` method to return the - response, you'd say ``attr="index"`` in the view configuration for the - view. This is most useful when the view definition is a class. - - If the ``view`` argument is not provided, this argument has no - effect. - -``use_global_views`` - When a request matches this route, and view lookup cannot find a view which - has a 'route_name' predicate argument that matches the route, try to fall - back to using a view that otherwise matches the context and request. - .. _custom_route_predicates: Custom Route Predicates ~~~~~~~~~~~~~~~~~~~~~~~ Each of the predicate callables fed to the ``custom_predicates`` argument of -:meth:`pyramid.config.Configurator.add_route` must be a callable accepting +:meth:`~pyramid.config.Configurator.add_route` must be a callable accepting two arguments. The first argument passed to a custom predicate is a dictionary conventionally named ``info``. The second argument is the current :term:`request` object. @@ -669,7 +440,7 @@ predicate function named ``num_one_two_or_three``, which ensures that the ``num`` segment is one of the values ``one``, ``two``, or ``three`` , and use the result as a custom predicate by feeding it inside a tuple to the ``custom_predicates`` argument to -:meth:`pyramid.config.Configurator.add_route`. +:meth:`~pyramid.config.Configurator.add_route`. A custom route predicate may also *modify* the ``match`` dictionary. For instance, a predicate might do some type conversion of values: @@ -823,7 +594,7 @@ The Matched Route When the URL pattern associated with a particular route configuration is matched by a request, an object named ``matched_route`` is added as an attribute of the :term:`request` object. Thus, ``request.matched_route`` -will be an object implementing the :class:`pyramid.interfaces.IRoute` +will be an object implementing the :class:`~pyramid.interfaces.IRoute` interface which matched the request. The most useful attribute of the route object is ``name``, which is the name of the route that matched. @@ -936,7 +707,7 @@ the :term:`root factory` configured at startup time (the ``root_factory`` argument to the :term:`Configurator` used to configure the application). You can override this behavior by passing in a ``factory`` argument to the -:meth:`pyramid.config.Configurator.add_route` method for a particular route. +:meth:`~pyramid.config.Configurator.add_route` method for a particular route. The ``factory`` should be a callable that accepts a :term:`request` and returns an instance of a class that will be the context resource used by the view. @@ -1001,7 +772,7 @@ Matching the Root URL It's not entirely obvious how to use a route pattern to match the root URL ("/"). To do so, give the empty string as a pattern in a call to -:meth:`pyramid.config.Configurator.add_route`: +:meth:`~pyramid.config.Configurator.add_route`: .. code-block:: python :linenos: @@ -1035,7 +806,8 @@ route patterns. For example, if you've configured a route with the ``name`` This would return something like the string ``http://example.com/1/2/3`` (at least if the current protocol and hostname implied ``http://example.com``). -See the :func:`pyramid.url.route_url` API documentation for more information. +See the :func:`~pyramid.url.route_url` API documentation for more +information. .. index:: single: redirecting to slash-appended routes @@ -1062,8 +834,10 @@ route configuration looks like so: .. code-block:: python :linenos: - config.add_route('noslash', 'no_slash', view='myproject.views.no_slash') - config.add_route('hasslash', 'has_slash/', view='myproject.views.has_slash') + config.add_route('noslash', 'no_slash', + view='myproject.views.no_slash') + config.add_route('hasslash', 'has_slash/', + view='myproject.views.has_slash') If a request enters the application with the ``PATH_INFO`` value of ``/has_slash/``, the second route will match. If a request enters the @@ -1138,16 +912,7 @@ Cleaning Up After a Request --------------------------- Sometimes it's required that some cleanup be performed at the end of a -request when a database connection is involved. When :term:`traversal` is -used, this cleanup is often done as a side effect of the traversal -:term:`root factory`. Often the root factory will insert an object into the -WSGI environment that performs some cleanup when its ``__del__`` method is -called. When URL dispatch is used, however, no special root factory is -required, so sometimes that option is not open to you. - -Instead of putting this cleanup logic in the root factory, however, you can -cause a subscriber to be fired when a new request is detected; the subscriber -can do this work. +request when a database connection is involved. For example, let's say you have a ``mypackage`` :app:`Pyramid` application package that uses SQLAlchemy, and you'd like the current SQLAlchemy database @@ -1158,37 +923,32 @@ session to be removed after each request. Put the following in the .. code-block:: python :linenos: - from mypackage.sql import DBSession - - class Cleanup: - def __init__(self, cleaner): - self.cleaner = cleaner - def __del__(self): - self.cleaner() - - def handle_teardown(event): - environ = event.request.environ - environ['mypackage.sqlcleaner'] = Cleanup(DBSession.remove) + from mypackage.models import DBSession -Then add an event subscriber in your startup configuration: + from pyramid.events import subscriber + from pyramid.events import NewRequest -.. code-block:: python - :linenos: + def cleanup_callback(request): + DBSession.remove() - config.add_subscriber('mypackage.handle_teardown', - 'pyramid.events.NewRequest') + @subscriber(NewRequest) + def add_cleanup_callback(event): + event.request.add_finished_callback(cleanup_callback) -Registering a handle_teardown subscriber will cause the DBSession to be -removed whenever the WSGI environment is destroyed (usually at the end of -every request). +Registering the ``cleanup_callback`` finished callback at the start of a +request (by causing the ``add_cleanup_callback`` to receive a +:class:`pyramid.events.NewRequest` event at the start of each request) will +cause the DBSession to be removed whenever request processing has ended. +Note that in the example above, for the :class:`pyramid.events.subscriber` +decorator to "work", the :meth:`pyramid.config.Configurator.scan` method must +be called against your ``mypackage`` package during application +initialization. -.. note:: This is only an example. In particular, it is not necessary - to cause ``DBSession.remove`` to be called as the result of an - event listener in an application generated from any - :app:`Pyramid` paster template, because these all use the - ``repoze.tm2`` middleware. The cleanup done by - ``DBSession.remove`` is unnecessary when ``repoze.tm2`` middleware - is in the WSGI pipeline. +.. note:: This is only an example. In particular, it is not necessary to + cause ``DBSession.remove`` to be called in an application generated from + any :app:`Pyramid` paster template, because these all use the + ``repoze.tm2`` middleware. The cleanup done by ``DBSession.remove`` is + unnecessary when ``repoze.tm2`` middleware is in the WSGI pipeline. .. index:: pair: URL dispatch; security @@ -1260,18 +1020,18 @@ which you started the application from. For example: See :ref:`environment_chapter` for more information about how, and where to set these values. -.. _displaying_application_routes: - .. index:: pair: routes; printing single: paster proutes +.. _displaying_application_routes: + Displaying All Application Routes --------------------------------- You can use the ``paster proutes`` command in a terminal window to print a summary of routes related to your application. Much like the ``paster -pshell`` command (see :ref:`interactive shell`), the ``paster proutes`` +pshell`` command (see :ref:`interactive_shell`), the ``paster proutes`` command accepts two arguments. The first argument to ``proutes`` is the path to your application's ``.ini`` file. The second is the ``app`` section name inside the ``.ini`` file which points to your application. @@ -1300,6 +1060,49 @@ callable could be found. If no routes are configured within your application, nothing will be printed to the console when ``paster proutes`` is executed. +Route View Callable Registration and Lookup Details +--------------------------------------------------- + +The purpose of making it possible to specify a view callable within a route +configuration is to prevent developers from needing to deeply understand the +details of :term:`resource location` and :term:`view lookup`. When a route +names a view callable as a ``view`` argument, and a request enters the system +which matches the pattern of the route, the result is simple: the view +callable associated with the route is invoked with the request that caused +the invocation. + +For most usage, you needn't understand more than this; how it works is an +implementation detail. In the interest of completeness, however, we'll +explain how it *does* work in the this section. You can skip it if you're +uninterested. + +When a ``view`` attribute is attached to a route configuration, +:app:`Pyramid` ensures that a :term:`view configuration` is registered that +will always be found when the route pattern is matched during a request. To +do so: + +- A special route-specific :term:`interface` is created at startup time for + each route configuration declaration. + +- When a route configuration declaration mentions a ``view`` attribute, a + :term:`view configuration` is registered at startup time. This view + configuration uses the route-specific interface as a :term:`request` type. + +- At runtime, when a request causes any route to match, the :term:`request` + object is decorated with the route-specific interface. + +- The fact that the request is decorated with a route-specific interface + causes the view lookup machinery to always use the view callable registered + using that interface by the route configuration to service requests that + match the route pattern. + +In this way, we supply a shortcut to the developer. Under the hood, the +:term:`resource location` and :term:`view lookup` subsystems provided by +:app:`Pyramid` are still being utilized, but in a way which does not require +a developer to understand either of them in detail. It also means that we +can allow a developer to combine :term:`URL dispatch` and :term:`traversal` +in various exceptional cases as documented in :ref:`hybrid_chapter`. + References ---------- diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index c45f053cf..0a6d9ee61 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -51,11 +51,9 @@ View configuration is performed in one of these ways: - by running a :term:`scan` against application source code which has a :class:`pyramid.view.view_config` decorator attached to a Python object as - per :class:`pyramid.view.view_config` and - :ref:`mapping_views_using_a_decorator_section`. + per :ref:`mapping_views_using_a_decorator_section`. - by using the :meth:`pyramid.config.Configurator.add_view` method as per - :meth:`pyramid.config.Configurator.add_view` and :ref:`mapping_views_using_imperative_config_section`. - By specifying a view within a :term:`route configuration`. View @@ -362,8 +360,7 @@ View Configuration Using the ``@view_config`` Decorator For better locality of reference, you may use the :class:`pyramid.view.view_config` decorator to associate your view functions -with URLs instead of using :term:`ZCML` or imperative configuration for the -same purpose. +with URLs instead of using imperative configuration for the same purpose. .. warning:: @@ -372,15 +369,14 @@ same purpose. declarations. Usage of the ``view_config`` decorator is a form of :term:`declarative -configuration`, like ZCML, but in decorator form. -:class:`pyramid.view.view_config` can be used to associate :term:`view -configuration` information -- as done via the equivalent imperative code or -ZCML -- with a function that acts as a :app:`Pyramid` view callable. All -arguments to the :meth:`pyramid.config.Configurator.add_view` method (save -for the ``view`` argument) are available in decorator form and mean precisely -the same thing. - -An example of the :class:`pyramid.view.view_config` decorator might reside in +configuration` in decorator form. :class:`~pyramid.view.view_config` can be +used to associate :term:`view configuration` information -- as done via the +equivalent imperative code -- with a function that acts as a :app:`Pyramid` +view callable. All arguments to the +:meth:`pyramid.config.Configurator.add_view` method (save for the ``view`` +argument) are available in decorator form and mean precisely the same thing. + +An example of the :class:`~pyramid.view.view_config` decorator might reside in a :app:`Pyramid` application module ``views.py``: .. ignore-next-block @@ -440,17 +436,17 @@ you *must* use the ``scan`` method of a Please see :ref:`decorations_and_code_scanning` for detailed information about what happens when code is scanned for configuration declarations -resulting from use of decorators like :class:`pyramid.view.view_config`. +resulting from use of decorators like :class:`~pyramid.view.view_config`. See :ref:`configuration_module` for additional API arguments to the -:meth:`pyramid.config.Configurator.scan` method. For example, the method +:meth:`~pyramid.config.Configurator.scan` method. For example, the method allows you to supply a ``package`` argument to better control exactly *which* code will be scanned. ``@view_config`` Placement ++++++++++++++++++++++++++ -A :class:`pyramid.view.view_config` decorator can be placed in various points +A :class:`~pyramid.view.view_config` decorator can be placed in various points in your application. If your view callable is a function, it may be used as a function decorator: @@ -484,7 +480,7 @@ against a class as when they are applied against a function. For example: def __call__(self): return Response('hello') -You can use the :class:`pyramid.view.view_config` decorator as a simple +You can use the :class:`~pyramid.view.view_config` decorator as a simple callable to manually decorate classes in Python 2.5 and below without the decorator syntactic sugar, if you wish: @@ -503,7 +499,7 @@ decorator syntactic sugar, if you wish: my_view = view_config()(MyView) -More than one :class:`pyramid.view.view_config` decorator can be stacked on +More than one :class:`~pyramid.view.view_config` decorator can be stacked on top of any number of others. Each decorator creates a separate view registration. For example: @@ -702,7 +698,7 @@ to a :term:`view configuration` found during view lookup will be verified. This will ensure that the currently authenticated user possesses that permission against the :term:`context` resource before the view function is actually called. Here's an example of specifying a permission in a view -configuration using :meth:`pyramid.config.Configurator.add_view`: +configuration using :meth:`~pyramid.config.Configurator.add_view`: .. code-block:: python :linenos: diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 392e5ea4a..efbf7924f 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -230,12 +230,12 @@ implements the :term:`Response` interface is to return a def view(request): return Response('OK') -You don't need to always use :class:`pyramid.response.Response` to represent a -response. :app:`Pyramid` provides a range of different "exception" classes +You don't need to always use :class:`~pyramid.response.Response` to represent +a response. :app:`Pyramid` provides a range of different "exception" classes which can act as response objects too. For example, an instance of the class -:class:`pyramid.httpexceptions.HTTPFound` is also a valid response object (see -:ref:`http_redirect`). A view can actually return any object that has the -following attributes. +:class:`pyramid.httpexceptions.HTTPFound` is also a valid response object +(see :ref:`http_redirect`). A view can actually return any object that has +the following attributes. status The HTTP status code (including the name) for the response as a string. @@ -290,7 +290,7 @@ Unauthorized``. It is possible, however, in Python 2.5 and above, to configure an *exception view* to catch these exceptions, and return an appropriate - :class:`pyramid.response.Response`. The simplest such view could just + :class:`~pyramid.response.Response`. The simplest such view could just catch and return the original exception. See :ref:`exception_views` for more details. @@ -312,11 +312,11 @@ handled by :app:`Pyramid` itself. These are Both are exception classes which accept a single positional constructor argument: a ``message``. -If :exc:`pyramid.exceptions.NotFound` is raised within view code, the result +If :exc:`~pyramid.exceptions.NotFound` is raised within view code, the result of the :term:`Not Found View` will be returned to the user agent which performed the request. -If :exc:`pyramid.exceptions.Forbidden` is raised within view code, the result +If :exc:`~pyramid.exceptions.Forbidden` is raised within view code, the result of the :term:`Forbidden View` will be returned to the user agent which performed the request. @@ -332,8 +332,8 @@ available to the view which :app:`Pyramid` invokes as Exception Views --------------- -The machinery which allows the special :exc:`pyramid.exceptions.NotFound` and -:exc:`pyramid.exceptions.Forbidden` exceptions to be caught by specialized +The machinery which allows the special :exc:`~pyramid.exceptions.NotFound` and +:exc:`~pyramid.exceptions.Forbidden` exceptions to be caught by specialized views as described in :ref:`special_exceptions_in_callables` can also be used by application developers to convert arbitrary exceptions to responses. @@ -515,7 +515,7 @@ an error when it can't decode some high-order character encoded in another character set within form data, e.g., when ``request.params['somename']`` is accessed. -If you are using the :class:`pyramid.response.Response` class to generate a +If you are using the :class:`~pyramid.response.Response` class to generate a response, or if you use the ``render_template_*`` templating APIs, the UTF-8 charset is set automatically as the default via the ``Content-Type`` header. If you return a ``Content-Type`` header without an explicit charset, a diff --git a/docs/narr/zca.rst b/docs/narr/zca.rst index 78a7b0b75..fcab0653e 100644 --- a/docs/narr/zca.rst +++ b/docs/narr/zca.rst @@ -171,7 +171,7 @@ when a :term:`Configurator` constructor is called, or when a During a request, the application registry created by the Configurator is "made current". This means calls to -:func:`pyramid.threadlocal.get_current_registry` in the thread +:func:`~pyramid.threadlocal.get_current_registry` in the thread handling the request will return the component registry associated with the application. @@ -184,7 +184,7 @@ always return the global ZCA registry (the one in To "fix" this and make the ZCA global APIs use the "current" BFG registry, you need to call -:meth:`pyramid.config.Configurator.hook_zca` within your +:meth:`~pyramid.config.Configurator.hook_zca` within your setup code. For example: .. code-block:: python |
