diff options
Diffstat (limited to 'docs/narr/templates.rst')
| -rw-r--r-- | docs/narr/templates.rst | 210 |
1 files changed, 102 insertions, 108 deletions
diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index c1c2fe31e..09b9bfc51 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -10,7 +10,7 @@ provides add-on templating support through a set of bindings packages. Out of the box, :app:`Pyramid` provides templating via the :term:`Chameleon` and :term:`Mako` templating libraries. :term:`Chameleon` provides support for -two different types of templates: :term:`ZPT` templates and text templates. +two different types of templates: :term:`ZPT` templates, and text templates. Before discussing how built-in templates are used in detail, we'll discuss two ways to render templates within @@ -22,18 +22,18 @@ configuration. .. _templates_used_directly: -Templates Used Directly ------------------------ +Using Templates Directly +------------------------ The most straightforward way to use a template within :app:`Pyramid` is to cause it to be rendered directly within a :term:`view callable`. You may use whatever API is supplied by a given templating engine to do so. -:app:`Pyramid` provides various APIs that allow you to render -templates directly from within a view callable. For example, if there -is a :term:`Chameleon` ZPT template named ``foo.pt`` in a directory in -your application named ``templates``, you can render the template from +:app:`Pyramid` provides various APIs that allow you to render templates +directly from within a view callable. For example, if there is a +:term:`Chameleon` ZPT template named ``foo.pt`` in a directory named +``templates`` in your application, you can render the template from within the body of a view callable like so: .. code-block:: python @@ -58,7 +58,7 @@ within the body of a view callable like so: rendering tasks. This set of functions works to render templates for all renderer extensions registered with :app:`Pyramid`. -The ``sample_view`` :term:`view callable` above returns a +The ``sample_view`` :term:`view callable` function above returns a :term:`response` object which contains the body of the ``templates/foo.pt`` template. In this case, the ``templates`` directory should live in the same directory as the module containing @@ -67,8 +67,8 @@ the ``sample_view`` function. The template author will have the names comparison purposes. In the example above, the path ``templates/foo.pt`` is relative to the -directory in which the file which defines the view configuration -lives. In this case, this is the directory containing the file that +directory containing the file which defines the view configuration. +In this case, this is the directory containing the file that defines the ``sample_view`` function. Although a renderer path is usually just a simple relative pathname, a path named as a renderer can be absolute, starting with a slash on UNIX or a drive letter @@ -76,18 +76,17 @@ prefix on Windows. .. warning:: - The ability for a template to be named as a renderer relative to the - location of the module in which the view callable is defined is limited to - :term:`Chameleon` templates. Mako templates and other templating system - bindings work differently. In particular, Mako templates use a "lookup - path" as defined by the ``mako.directories`` configuration file instead of - treating relative paths as relative to the current view module. See - :ref:`mako_templates`. + Only :term:`Chameleon` templates support defining a renderer for a + template relative to the location of the module where the view + callable is defined. Mako templates, and other templating system + bindings work differently. In particular, Mako templates use a + "lookup path" as defined by the ``mako.directories`` configuration + file instead of treating relative paths as relative to the current + view module. See :ref:`mako_templates`. -The path can alternately be a :term:`resource specification` in the -form ``some.dotted.package_name:relative/path``, making it possible to -address template resources which live in another package. For -example: +The path can alternately be a :term:`resource specification` in the form +``some.dotted.package_name:relative/path``. This makes it possible to +address template resources which live in another package. For example: .. code-block:: python :linenos: @@ -118,29 +117,26 @@ In the examples above we pass in a keyword argument named ``request`` representing the current :app:`Pyramid` request. Passing a request keyword argument will cause the ``render_to_response`` function to supply the renderer with more correct system values (see -:ref:`renderer_system_values`), because most of the information -required to compose proper system values is present in the request. -If you care about the correct system values being provided to the -renderer being called (in particular, if your template relies on the -name ``request`` or ``context``, or if you've configured special -:term:`renderer globals` make sure to pass ``request`` as a keyword -argument in every call to to a ``pyramid.renderers.render_*`` -function. - -Every view must return a :term:`response` object (except for views -which use a :term:`renderer` named via view configuration, which we'll +:ref:`renderer_system_values`), because most of the information required +to compose proper system values is present in the request. If your +template relies on the name ``request`` or ``context``, or if you've +configured special :term:`renderer globals`, make sure to pass +``request`` as a keyword argument in every call to to a +``pyramid.renderers.render_*`` function. + +Every view must return a :term:`response` object, except for views +which use a :term:`renderer` named via view configuration (which we'll see shortly). The :func:`pyramid.renderers.render_to_response` function is a shortcut function that actually returns a response -object. +object. This allows the example view above to simply return the result +of its call to ``render_to_response()`` directly. -Obviously not all APIs you might call to get respnonse data will -return a response object. If you call a "response-ignorant" API that -returns information you'd like to use as a response (such as when you -render a template to a string), you must construct your own response -object as necessary with the string as the body. For example, the -:func:`pyramid.renderers.render` API returns a string. We can -manufacture a :term:`response` object directly, and use that string as -the body of the response: +Obviously not all APIs you might call to get response data will return a +response object. For example, you might render one or more templates to +a string that you want to use as response data. The +:func:`pyramid.renderers.render` API renders a template to a string. We +can manufacture a :term:`response` object directly, and use that string +as the body of the response: .. code-block:: python :linenos: @@ -258,7 +254,7 @@ values are provided in a dictionary to the renderer and include: ``context`` The current :app:`Pyramid` context if ``request`` was provided as - a keyword argument or ``None``. + a keyword argument, or ``None``. ``request`` The request provided as a keyword argument. @@ -267,31 +263,33 @@ values are provided in a dictionary to the renderer and include: The renderer name used to perform the rendering, e.g. ``mypackage:templates/foo.pt``. -``renderer_info`` An object implementing the - :class:`pyramid.interfaces.IRendererInfo` interface. Basically, an object - with the following attributes: ``name``, ``package`` and ``type``. +``renderer_info`` + An object implementing the :class:`pyramid.interfaces.IRendererInfo` + interface. Basically, an object with the following attributes: + ``name``, ``package`` and ``type``. You can define more values which will be passed to every template executed as a result of rendering by defining :term:`renderer globals`. -What any particular renderer does with them is up to the renderer itself, but -most template renderers, including Chameleon and Mako renderers, make these -names available as top-level template variables. +What any particular renderer does with these system values is up to the +renderer itself, but most template renderers, including Chameleon and +Mako renderers, make these names available as top-level template +variables. .. _templates_used_as_renderers: Templates Used as Renderers via Configuration --------------------------------------------- -Instead of using the :func:`pyramid.renderers.render_to_response` -API within the body of a view function directly to render a specific -template to a response, you may associate a template written in a -supported templating language with a view indirectly by specifying it -as a :term:`renderer` in *view configuration*. +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 +templating languages supported by :app:`Pyramid`. To use a renderer via view configuration, specify a template -:term:`resource specification` as the ``renderer`` argument or +:term:`resource specification` as the ``renderer`` argument, or attribute to the :term:`view configuration` of a :term:`view callable`. Then return a *dictionary* from that view callable. The dictionary items returned by the view callable will be made available @@ -314,13 +312,11 @@ template renderer: def my_view(request): return {'foo':1, 'bar':2} -.. note:: It is not necessary to supply the ``request`` value as a key +.. note:: You do not need to supply the ``request`` value as a key in the dictionary result returned from a renderer-configured view - callable in order to ensure that the "most correct" system values - are supplied to the renderer as it is when you use - :func:`pyramid.renderers.render` or - :func:`pyramid.renderers.render_to_response`. This is handled - automatically. + callable. :app:`Pyramid` automatically supplies this value for + you so that the "most correct" system values are provided to + the renderer. .. warning:: @@ -354,25 +350,25 @@ templates as renderers. See :ref:`available_template_system_bindings`. .. sidebar:: Why Use A Renderer via View Configuration Using a renderer in view configuration is usually a better way to - render templates than using any rendering API directly from within - a :term:`view callable` because it makes the view callable more - unit-testable. Views which use templating or rendering APIs - directly must return a :term:`Response` object. Making testing - assertions about response objects is typically an indirect process, - because it means that your test code often needs to somehow parse - information out of the response body (often HTML). View callables - which are configured with renderers externally via view - configuration typically return a dictionary, and making assertions - about the information is almost always more direct than needing to - parse HTML. Specifying a renderer from within :term:`ZCML` (as - opposed to imperatively or via a ``view_config`` decorator, or using a - template directly from within a view callable) also makes it - possible for someone to modify the template used to render a view - without needing to fork your code to do so. See + render templates than using any rendering API directly from within a + :term:`view callable` because it makes the view callable more + unit-testable. Views which use templating or rendering APIs directly + must return a :term:`Response` object. Making testing assertions + about response objects is typically an indirect process, because it + means that your test code often needs to somehow parse information + out of the response body (often HTML). View callables configured + with renderers externally via view configuration typically return a + dictionary, as above. Making assertions about results returned in a + dictionary is almost always more direct and straightforward than + needing to parse HTML. Specifying a renderer from within + :term:`ZCML` (as opposed to imperatively or via a ``view_config`` + decorator, or using a template directly from within a view callable) + also makes it possible for someone to modify the template used to + render a view without needing to fork your code to do so. See :ref:`extending_chapter` for more information. By default, views rendered via a template renderer return a -:term:`Response` object which has a *status code* of ``200 OK`` and a +:term:`Response` object which has a *status code* of ``200 OK``, and a *content-type* of ``text/html``. To vary attributes of the response of a view that uses a renderer, such as the content-type, headers, or status attributes, you must set attributes on the *request* object @@ -409,13 +405,13 @@ templates is available from `the Chameleon website :term:`Chameleon` only works on :term:`CPython` platforms and :term:`Google App Engine`. On :term:`Jython` and other non-CPython - platforms, you should use Mako (:ref:`mako_templates`) or + platforms, you should use Mako (see :ref:`mako_templates`) or ``pyramid_jinja2`` instead. See :ref:`available_template_system_bindings`. -Given that there is a :term:`Chameleon` ZPT template named ``foo.pt`` -in a directory in your application named ``templates``, you can render -the template as a :term:`renderer` like so: +Given a :term:`Chameleon` ZPT template named ``foo.pt`` in a directory +in your application named ``templates``, you can render the template as +a :term:`renderer` like so: .. code-block:: python :linenos: @@ -472,22 +468,21 @@ works in these templates. Using ZPT Macros in :app:`Pyramid` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a :term:`renderer` is used to render a template, -:app:`Pyramid` makes at least two top-level names available to the -template by default: ``context`` and ``request``. One of the common -needs in ZPT-based templates is to use one template's "macros" from within -a different template. In Zope, this is typically handled by -retrieving the template from the ``context``. But having a hold of -the context in :app:`Pyramid` is not helpful: templates cannot -usually be retrieved from models. To use macros in :app:`Pyramid`, -you need to make the macro template itself available to the rendered -template by passing the template in which the macro is defined (or even -the macro itself) *into* the rendered template. To make a macro -available to the rendered template, you can retrieve a different -template using the :func:`pyramid.renderers.get_renderer` API, -and pass it in to the template being rendered. For example, using a -:term:`view configuration` via a :class:`pyramid.view.view_config` -decorator that uses a :term:`renderer`: +When a :term:`renderer` is used to render a template, :app:`Pyramid` +makes at least two top-level names available to the template by default: +``context`` and ``request``. One of the common needs in ZPT-based +templates is to use one template's "macros" from within a different +template. In Zope, this is typically handled by retrieving the template +from the ``context``. But the context in :app:`Pyramid` is typically a +model object, and templates cannot usually be retrieved from models. To +use macros in :app:`Pyramid`, you need to make the macro template itself +available to the rendered template by 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 that uses a +:term:`renderer`: .. code-block:: python :linenos: @@ -588,7 +583,7 @@ files showing up in your ``templates`` directory (or otherwise directly "next" to your templates), it is due to this feature. If you're using a version control system such as Subversion, you -should cause it to ignore these files. Here's the contents of the +should configure it to ignore these files. Here's the contents of the author's ``svn propedit svn:ignore .`` in each of my ``templates`` directories. @@ -703,10 +698,10 @@ has built-in bindings for the Mako templating system. The language definition documentation for Mako templates is available from `the Mako website <http://www.makotemplates.org/>`_. -To use a Mako template, given that there is a :term:`Mako` ZPT template named -``foo.mak`` in the ``templates`` subdirectory in your application package -named ``mypackage``, you can render the template as a :term:`renderer` like -so: +To use a Mako template, given a :term:`Mako` ZPT template file named +``foo.mak`` in the ``templates`` subdirectory in your application +package named ``mypackage``, you can configure the template as a +:term:`renderer` like so: .. code-block:: python :linenos: @@ -757,7 +752,7 @@ look like: This template doesn't use any advanced features of Mako, only the ``${squiggly}`` replacement syntax for names that are passed in as -:term:`renderer globals` values. See the `the Mako documentation +:term:`renderer globals`. See the `the Mako documentation <http://www.makotemplates.org/>`_ to use more advanced features. .. index:: @@ -780,7 +775,7 @@ detected, and the template will be reloaded on the next rendering. usually only desirable during development. In order to turn on automatic reloading of templates, you can use an -environment variable setting or a configuration file setting. +environment variable, or a configuration file setting. To use an environment variable, start your application under a shell using the ``BFG_RELOAD_TEMPLATES`` operating system environment @@ -811,9 +806,8 @@ Available Add-On Template System Bindings ----------------------------------------- Jinja2 template bindings are available for :app:`Pyramid` in the -``pyramid_jinja2`` package. It lives in the Pylons version control -repository at `http://github.com/Pylons/pyramid_jinja2 -<http://github.com/Pylons/pyramid_jinja2>`_. At the time of this writing, it -has not had a release, but by the time you read this it also might be -available from :term:`PyPI`. +``pyramid_jinja2`` package. You can get the latest release of +this package from the +`Python package index <http://pypi.python.org/pypi/pyramid_jinja2>`_ +(pypi). |
