summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2013-09-20 14:10:05 -0400
committerChris McDonough <chrism@plope.com>2013-09-20 14:10:05 -0400
commitfaf334d94e8c7450962b6b0d18fe57cefd43f04a (patch)
treebac12a41585561e84b914ede37bcd83a62764fb9 /docs
parent53e00ae36d969e8f8794549d66f9b1c6b92e0c60 (diff)
parent4d2fc0bbc58bc1948c73b2fcb3e0e1bdeee7a5d6 (diff)
downloadpyramid-faf334d94e8c7450962b6b0d18fe57cefd43f04a.tar.gz
pyramid-faf334d94e8c7450962b6b0d18fe57cefd43f04a.tar.bz2
pyramid-faf334d94e8c7450962b6b0d18fe57cefd43f04a.zip
Merge branch 'master' into 1.5-branch
Diffstat (limited to 'docs')
-rw-r--r--docs/api/config.rst4
-rw-r--r--docs/api/request.rst24
-rw-r--r--docs/api/view.rst6
-rw-r--r--docs/designdefense.rst62
-rw-r--r--docs/glossary.rst7
-rw-r--r--docs/index.rst4
-rw-r--r--docs/latexindex.rst1
-rw-r--r--docs/narr/MyProject/myproject/__init__.py1
-rw-r--r--docs/narr/MyProject/setup.py1
-rw-r--r--docs/narr/advconfig.rst1
-rw-r--r--docs/narr/assets.rst20
-rw-r--r--docs/narr/hooks.rst76
-rw-r--r--docs/narr/introspector.rst12
-rw-r--r--docs/narr/project.rst17
-rw-r--r--docs/narr/renderers.rst270
-rw-r--r--docs/narr/subrequest.rst6
-rw-r--r--docs/narr/templates.rst436
-rw-r--r--docs/narr/urldispatch.rst7
-rw-r--r--docs/quick_tour.rst9
-rw-r--r--docs/tutorials/bfg/index.rst204
-rw-r--r--docs/tutorials/wiki/basiclayout.rst9
-rw-r--r--docs/tutorials/wiki/definingviews.rst4
-rw-r--r--docs/tutorials/wiki/src/authorization/setup.py1
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/__init__.py1
-rw-r--r--docs/tutorials/wiki/src/basiclayout/setup.py1
-rw-r--r--docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py1
-rw-r--r--docs/tutorials/wiki/src/models/setup.py1
-rw-r--r--docs/tutorials/wiki/src/models/tutorial/__init__.py1
-rw-r--r--docs/tutorials/wiki/src/tests/setup.py1
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/__init__.py1
-rw-r--r--docs/tutorials/wiki/src/views/setup.py1
-rw-r--r--docs/tutorials/wiki/src/views/tutorial/__init__.py1
-rw-r--r--docs/tutorials/wiki/tests.rst4
-rw-r--r--docs/tutorials/wiki2/authorization.rst8
-rw-r--r--docs/tutorials/wiki2/basiclayout.rst30
-rw-r--r--docs/tutorials/wiki2/definingmodels.rst2
-rw-r--r--docs/tutorials/wiki2/definingviews.rst8
-rw-r--r--docs/tutorials/wiki2/src/authorization/setup.py5
-rw-r--r--docs/tutorials/wiki2/src/authorization/tutorial/__init__.py1
-rw-r--r--docs/tutorials/wiki2/src/authorization/tutorial/models.py3
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/setup.py5
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py1
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/tutorial/models.py4
-rw-r--r--docs/tutorials/wiki2/src/models/setup.py5
-rw-r--r--docs/tutorials/wiki2/src/models/tutorial/__init__.py1
-rw-r--r--docs/tutorials/wiki2/src/models/tutorial/models.py4
-rw-r--r--docs/tutorials/wiki2/src/tests/setup.py5
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/__init__.py1
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/models.py3
-rw-r--r--docs/tutorials/wiki2/src/views/setup.py5
-rw-r--r--docs/tutorials/wiki2/src/views/tutorial/__init__.py1
-rw-r--r--docs/tutorials/wiki2/src/views/tutorial/models.py4
-rw-r--r--docs/tutorials/wiki2/tests.rst4
-rw-r--r--docs/whatsnew-1.0.rst6
-rw-r--r--docs/whatsnew-1.1.rst9
55 files changed, 260 insertions, 1050 deletions
diff --git a/docs/api/config.rst b/docs/api/config.rst
index 1f65be9f1..48dd2f0b9 100644
--- a/docs/api/config.rst
+++ b/docs/api/config.rst
@@ -52,10 +52,6 @@
.. automethod:: override_asset(to_override, override_with)
- :methodcategory:`Setting Renderer Globals`
-
- .. automethod:: set_renderer_globals_factory(factory)
-
:methodcategory:`Getting and Adding Settings`
.. automethod:: add_settings
diff --git a/docs/api/request.rst b/docs/api/request.rst
index 02290eaf3..72abddb68 100644
--- a/docs/api/request.rst
+++ b/docs/api/request.rst
@@ -199,13 +199,13 @@
- Ensures that the user implied by the request passed has the necessary
authorization to invoke view callable before calling it.
- - causes a :class:`~pyramid.events.NewResponse` event to be sent when
- the Pyramid application returns a response.
-
- Calls any :term:`response callback` functions defined within the
request's lifetime if a response is obtained from the Pyramid
application.
+ - causes a :class:`~pyramid.events.NewResponse` event to be sent if a
+ response is obtained.
+
- Calls any :term:`finished callback` functions defined within the
request's lifetime.
@@ -235,24 +235,6 @@
.. automethod:: resource_path
- .. attribute:: response_*
-
- In Pyramid 1.0, you could set attributes on a
- :class:`pyramid.request.Request` which influenced the behavior of
- *rendered* responses (views which use a :term:`renderer` and which
- don't directly return a response). These attributes began with
- ``response_``, such as ``response_headerlist``. If you needed to
- influence response values from a view that uses a renderer (such as the
- status code, a header, the content type, etc) you would set these
- attributes. See :ref:`response_prefixed_attrs` for further discussion.
- As of Pyramid 1.1, assignment to ``response_*`` attrs is deprecated.
- Assigning to one is still supported but will cause a deprecation
- warning to be emitted, and eventually the feature will be removed. For
- new code, instead of assigning ``response_*`` attributes to the
- request, use API of the :attr:`pyramid.request.Request.response`
- object (exposed to view code as ``request.response``) to influence
- rendered response behavior.
-
.. attribute:: json_body
This property will return the JSON-decoded variant of the request
diff --git a/docs/api/view.rst b/docs/api/view.rst
index 21d2bb90d..d8e429552 100644
--- a/docs/api/view.rst
+++ b/docs/api/view.rst
@@ -11,8 +11,6 @@
.. autofunction:: render_view
- .. autofunction:: is_response
-
.. autoclass:: view_config
:members:
@@ -25,8 +23,4 @@
.. autoclass:: forbidden_view_config
:members:
- .. autoclass:: static
- :members:
- :inherited-members:
-
diff --git a/docs/designdefense.rst b/docs/designdefense.rst
index cebcf6218..bbce3e29c 100644
--- a/docs/designdefense.rst
+++ b/docs/designdefense.rst
@@ -594,55 +594,45 @@ requires extensibility because it must be deployed in multiple locations.
Pyramid Is Too Big
------------------
-"The :app:`Pyramid` compressed tarball is almost 2MB. It must be
+"The :app:`Pyramid` compressed tarball is larger than 2MB. It must be
enormous!"
-No. We just ship it with test code and helper templates. Here's a
+No. We just ship it with docs, test code, and scaffolding. Here's a
breakdown of what's included in subdirectories of the package tree:
docs/
- 3.0MB
+ 4.9MB
pyramid/tests/
- 1.1MB
+ 2.0MB
-pyramid/paster_templates/
+pyramid/scaffolds/
- 804KB
+ 460KB
-pyramid/ (except for ``pyramd/tests and pyramid/paster_templates``)
+pyramid/ (except for ``pyramd/tests`` and ``pyramid/scaffolds``)
- 539K
+ 844KB
-The actual :app:`Pyramid` runtime code is about 10% of the total size of the
-tarball omitting docs, helper templates used for package generation, and test
-code. Of the approximately 19K lines of Python code in the package, the code
+Of the approximately 34K lines of Python code in the package, the code
that actually has a chance of executing during normal operation, excluding
-tests and paster template Python files, accounts for approximately 5K lines
-of Python code. This is comparable to Pylons 1.X, which ships with a little
-over 2K lines of Python code, excluding tests.
+tests and scaffolding Python files, accounts for approximately 10K lines.
+
Pyramid Has Too Many Dependencies
---------------------------------
-This is true. At the time of this writing (Pyramid 1.3), the total number of
-Python package distributions that :app:`Pyramid` depends upon transitively is
-if you use Python 3.2 or Python 2.7 is 10. If you use Python 2.6, Pyramid
-will pull in 12 package distributions. This is a lot more than zero package
-distribution dependencies: a metric which various Python microframeworks and
-Django boast.
-
-However, Pyramid 1.2 relied on 15 packages under Python 2.7 and 17 packages
-under Python 2.6, so we've made progress here. A port to Python 3 completed
-in Pyramid 1.3 helped us shed a good number of dependencies by forcing us to
-make better packaging decisions.
+Over time, we've made lots of progress on reducing the number of packaging
+dependencies Pyramid has had. Pyramid 1.2 had 15 of them. Pyramid 1.3 and 1.4
+had 12 of them. The current release as of this writing, Pyramid 1.5, has
+only 7. This number is unlikely to become any smaller.
-In the future, we may also move templating system dependencies out of the
-core and place them in add-on packages, to be included by developers instead
-of by the framework. This would reduce the number of core dependencies by
-about five, leaving us with only five remaining core dependencies.
+A port to Python 3 completed in Pyramid 1.3 helped us shed a good number of
+dependencies by forcing us to make better packaging decisions. Removing
+Chameleon and Mako templating system dependencies in the Pyramid core in 1.5
+let us shed most of the remainder of them.
Pyramid "Cheats" To Obtain Speed
--------------------------------
@@ -774,7 +764,7 @@ content management system (CMS) may have basic functionality that needs to be
extended for a particular deployment. That CMS system may be deployed for
many organizations at many places. Some number of deployments of this CMS
may be deployed centrally by a third party and managed as a group. It's
-useful to be able to extend such a system for each deployment via preordained
+easier to be able to extend such a system for each deployment via preordained
plugpoints than it is to continually keep each software branch of the system
in sync with some upstream source: the upstream developers may change code in
such a way that your changes to the same codebase conflict with theirs in
@@ -802,8 +792,8 @@ such a feature.
main template and the CSS in a separate Python package which defines
overrides.
-- If a deployment needs an application page to do something differently needs
- it to expose more or different information, the deployer may override the
+- If a deployment needs an application page to do something differently, or
+ to expose more or different information, the deployer may override the
view that renders the page within a separate Python package.
- If a deployment needs an additional feature, the deployer may add a view to
@@ -820,7 +810,7 @@ won't regularly need to deal wth meaningless textual merge conflicts that
trivial changes to upstream packages often entail when it comes time to
update the upstream package, because if you extend an application externally,
there just is no textual merge done. Your modifications will also, for
-whatever its worth, be contained in one, canonical, well-defined place.
+whatever it's worth, be contained in one, canonical, well-defined place.
Branching an application and continually merging in order to get new features
and bugfixes is clearly useful. You can do that with a :app:`Pyramid`
@@ -832,7 +822,7 @@ dismiss this feature in favor of branching and merging because applications
written in their framework of choice aren't extensible out of the box in a
comparably fundamental way.
-While :app:`Pyramid` application are fundamentally extensible even if you
+While :app:`Pyramid` applications are fundamentally extensible even if you
don't write them with specific extensibility in mind, if you're moderately
adventurous, you can also take it a step further. If you learn more about
the :term:`Zope Component Architecture`, you can optionally use it to expose
@@ -852,7 +842,7 @@ applications by :app:`Pyramid` are good or bad is mostly pointless. You
needn't take advantage of the extensibility features provided by a particular
:app:`Pyramid` application in order to affect a modification for a particular
set of its deployments. You can ignore the application's extensibility
-plugpoints entirely, and instead use version control branching and merging to
+plugpoints entirely, and use version control branching and merging to
manage application deployment modifications instead, as if you were deploying
an application written using any other web framework.
@@ -1659,7 +1649,7 @@ If you can understand this hello world program, you can use Pyramid:
server = make_server('0.0.0.0', 8080, app)
server.serve_forever()
-Pyramid has ~ 650 pages of documentation (printed), covering topics from the
+Pyramid has ~ 700 pages of documentation (printed), covering topics from the
very basic to the most advanced. *Nothing* is left undocumented, quite
literally. It also has an *awesome*, very helpful community. Visit the
#pyramid IRC channel on freenode.net (irc://freenode.net#pyramid) and see.
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 8ade889a3..7dc69c7c4 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -798,9 +798,8 @@ Glossary
:term:`Internationalization`.
renderer globals
- Values injected as names into a renderer based on application
- policy. See :ref:`adding_renderer_globals` for more
- information.
+ Values injected as names into a renderer by a
+ :class:`pyramid.event.BeforeRender` event.
response callback
A user-defined callback executed by the :term:`router` at a
@@ -1021,4 +1020,4 @@ Glossary
add-on
A Python :term:`distribution` that uses Pyramid's extensibility
to plug into a Pyramid application and provide extra,
- configurable services. \ No newline at end of file
+ configurable services.
diff --git a/docs/index.rst b/docs/index.rst
index d2a0008a8..2efe90cf7 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -20,7 +20,8 @@ After you install :app:`Pyramid` and run this application, when you visit
See :ref:`firstapp_chapter` for a full explanation of how this application
works. Read the :ref:`html_narrative_documentation` to understand how
:app:`Pyramid` is designed to scale from simple applications like this to
-very large web applications.
+very large web applications. To just dive in headfirst, read the
+:doc:`quick_tour`.
Front Matter
============
@@ -126,7 +127,6 @@ platforms.
tutorials/wiki2/index.rst
tutorials/wiki/index.rst
- tutorials/bfg/index.rst
tutorials/modwsgi/index.rst
.. _html_api_documentation:
diff --git a/docs/latexindex.rst b/docs/latexindex.rst
index eb14f5076..c4afff212 100644
--- a/docs/latexindex.rst
+++ b/docs/latexindex.rst
@@ -78,7 +78,6 @@ Tutorials
tutorials/wiki2/index.rst
tutorials/wiki/index.rst
- tutorials/bfg/index.rst
tutorials/modwsgi/index.rst
.. _api_documentation:
diff --git a/docs/narr/MyProject/myproject/__init__.py b/docs/narr/MyProject/myproject/__init__.py
index 6c512f52f..ad5ecbc6f 100644
--- a/docs/narr/MyProject/myproject/__init__.py
+++ b/docs/narr/MyProject/myproject/__init__.py
@@ -5,6 +5,7 @@ def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
config = Configurator(settings=settings)
+ config.include('pyramid_chameleon')
config.add_static_view('static', 'static', cache_max_age=3600)
config.add_route('home', '/')
config.scan()
diff --git a/docs/narr/MyProject/setup.py b/docs/narr/MyProject/setup.py
index 6969c73e7..a23f46c91 100644
--- a/docs/narr/MyProject/setup.py
+++ b/docs/narr/MyProject/setup.py
@@ -10,6 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
requires = [
'pyramid',
+ 'pyramid_chameleon',
'pyramid_debugtoolbar',
'waitress',
]
diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst
index 1b8e33de3..d3431e39e 100644
--- a/docs/narr/advconfig.rst
+++ b/docs/narr/advconfig.rst
@@ -302,7 +302,6 @@ These are the methods of the configurator which provide conflict detection:
:meth:`~pyramid.config.Configurator.set_view_mapper`,
:meth:`~pyramid.config.Configurator.set_authentication_policy`,
:meth:`~pyramid.config.Configurator.set_authorization_policy`,
-:meth:`~pyramid.config.Configurator.set_renderer_globals_factory`,
:meth:`~pyramid.config.Configurator.set_locale_negotiator`,
:meth:`~pyramid.config.Configurator.set_default_permission`,
:meth:`~pyramid.config.Configurator.add_traverser`,
diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst
index 26b3e3a92..b0a8d18b0 100644
--- a/docs/narr/assets.rst
+++ b/docs/narr/assets.rst
@@ -227,14 +227,14 @@ API to generate them for you. For example:
.. code-block:: python
:linenos:
- from pyramid.chameleon_zpt import render_template_to_response
+ from pyramid.renderers import render_to_response
def my_view(request):
css_url = request.static_url('mypackage:assets/1/foo.css')
js_url = request.static_url('mypackage:assets/2/foo.js')
- return render_template_to_response('templates/my_template.pt',
- css_url = css_url,
- js_url = js_url)
+ return render_to_response('templates/my_template.pt',
+ dict(css_url=css_url, js_url=js_url),
+ request=request)
If the request "application URL" of the running system is
``http://example.com``, the ``css_url`` generated above would be:
@@ -336,7 +336,9 @@ your application root as below.
from pyramid.static import static_view
static_view = static_view('/path/to/static/dir', use_subpath=True)
-.. note:: For better cross-system flexibility, use an :term:`asset
+.. note::
+
+ For better cross-system flexibility, use an :term:`asset
specification` as the argument to :class:`~pyramid.static.static_view`
instead of a physical absolute filesystem path, e.g. ``mypackage:static``
instead of ``/path/to/mypackage/static``.
@@ -432,9 +434,9 @@ feature, a :term:`Configurator` API exists named
:meth:`pyramid.config.Configurator.override_asset`. This API allows you to
*override* the following kinds of assets defined in any Python package:
-- Individual :term:`Chameleon` templates.
+- Individual template files.
-- A directory containing multiple Chameleon templates.
+- A directory containing multiple template files.
- Individual static files served up by an instance of the
``pyramid.static.static_view`` helper class.
@@ -460,8 +462,8 @@ can override a single asset. For example:
:linenos:
config.override_asset(
- to_override='some.package:templates/mytemplate.pt',
- override_with='another.package:othertemplates/anothertemplate.pt')
+ to_override='some.package:templates/mytemplate.pt',
+ override_with='another.package:othertemplates/anothertemplate.pt')
The string value passed to both ``to_override`` and ``override_with`` sent to
the ``override_asset`` API is called an :term:`asset specification`. The
diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst
index 3a2568775..0c450fad7 100644
--- a/docs/narr/hooks.rst
+++ b/docs/narr/hooks.rst
@@ -372,10 +372,8 @@ that can be used for this purpose. For example:
def add_global(event):
event['mykey'] = 'foo'
-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,
-has injected its own keys into the renderer globals dictionary).
+An object of this type is sent as an event just before a :term:`renderer`
+is invoked.
If a subscriber attempts to add a key that already exist in the renderer
globals dictionary, a :exc:`KeyError` is raised. This limitation is enforced
@@ -417,66 +415,6 @@ your view callable, like so:
See the API documentation for the :class:`~pyramid.events.BeforeRender` event
interface at :class:`pyramid.interfaces.IBeforeRender`.
-Another (deprecated) mechanism which allows event subscribers more control
-when adding renderer global values exists in :ref:`adding_renderer_globals`.
-
-.. index::
- single: adding renderer globals
-
-.. _adding_renderer_globals:
-
-Adding Renderer Globals (Deprecated)
-------------------------------------
-
-.. deprecated:: 1.1
- An alternative mechanism which allows event subscribers to add renderer
- global values is documented in :ref:`beforerender_event`.
-
-Whenever :app:`Pyramid` handles a request to perform a rendering (after a
-view with a ``renderer=`` configuration attribute is invoked, or when any of
-the methods beginning with ``render`` within the :mod:`pyramid.renderers`
-module are called), *renderer globals* can be injected into the *system*
-values sent to the renderer. By default, no renderer globals are injected,
-and the "bare" system values (such as ``request``, ``context``, ``view``, and
-``renderer_name``) are the only values present in the system dictionary
-passed to every renderer.
-
-A callback that :app:`Pyramid` will call every time a renderer is invoked can
-be added by passing a ``renderer_globals_factory`` argument to the
-constructor of the :term:`configurator`. This callback can either be a
-callable object or a :term:`dotted Python name` representing such a callable.
-
-.. code-block:: python
- :linenos:
-
- def renderer_globals_factory(system):
- return {'a': 1}
-
- config = Configurator(
- renderer_globals_factory=renderer_globals_factory)
-
-Such a callback must accept a single positional argument (notionally named
-``system``) which will contain the original system values. It must return a
-dictionary of values that will be merged into the system dictionary. See
-:ref:`renderer_system_values` for description of the values present in the
-system dictionary.
-
-If you're doing imperative configuration, and you'd rather do it after you've
-already constructed a :term:`configurator` it can also be registered via the
-:meth:`pyramid.config.Configurator.set_renderer_globals_factory` method:
-
-.. code-block:: python
- :linenos:
-
- from pyramid.config import Configurator
-
- def renderer_globals_factory(system):
- return {'a': 1}
-
- config = Configurator()
- config.set_renderer_globals_factory(renderer_globals_factory)
-
-
.. index::
single: response callback
@@ -514,7 +452,7 @@ callback will be an exception object instead of its default value of
``None``.
Response callbacks are called in the order they're added
-(first-to-most-recently-added). All response callbacks are called *after*
+(first-to-most-recently-added). All response callbacks are called *before*
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.
@@ -1384,9 +1322,11 @@ The first argument to :meth:`pyramid.config.Configurator.add_view_predicate`,
the name, is a string representing the name that is expected to be passed to
``view_config`` (or its imperative analogue ``add_view``).
-The second argument is a view or route predicate factory. A view or route
-predicate factory is most often a class with a constructor (``__init__``), a
-``text`` method, a ``phash`` method and a ``__call__`` method. For example:
+The second argument is a view or route predicate factory, or a :term:`dotted
+Python name` which refers to a view or route predicate factory. A view or
+route predicate factory is most often a class with a constructor
+(``__init__``), a ``text`` method, a ``phash`` method and a ``__call__``
+method. For example:
.. code-block:: python
:linenos:
diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst
index dec22c5b1..3c0a6744f 100644
--- a/docs/narr/introspector.rst
+++ b/docs/narr/introspector.rst
@@ -232,18 +232,6 @@ introspectables in categories not described here.
The factory object (the resolved ``factory`` argument to
``add_renderer``).
-``renderer globals factory``
-
- There will be one and only one introspectable in the ``renderer globals
- factory`` category. It represents a call to
- :meth:`pyramid.config.Configurator.set_renderer_globals_factory`; it will
- have the following data.
-
- ``factory``
-
- The factory object (the resolved ``factory`` argument to
- ``set_renderer_globals_factory``).
-
``routes``
Each introspectable in the ``routes`` category represents a call to
diff --git a/docs/narr/project.rst b/docs/narr/project.rst
index 52f13d5a8..f3050f805 100644
--- a/docs/narr/project.rst
+++ b/docs/narr/project.rst
@@ -570,8 +570,8 @@ adding more settings to this section.
The ``pyramid.reload_templates`` setting in the ``[app:main]`` section is a
:app:`Pyramid` -specific setting which is passed into the framework. If it
-exists, and its value is ``true``, :term:`Chameleon` and :term:`Mako`
-template changes will not require an application restart to be detected. See
+exists, and its value is ``true``, supported template changes will not
+require an application restart to be detected. See
:ref:`reload_templates_section` for more information.
.. warning:: The ``pyramid.reload_templates`` option should be turned off for
@@ -818,7 +818,7 @@ also informs Python that the directory which contains it is a *package*.
#. Line 1 imports the :term:`Configurator` class from :mod:`pyramid.config`
that we use later.
-#. Lines 4-11 define a function named ``main`` that returns a :app:`Pyramid`
+#. Lines 4-12 define a function named ``main`` that returns a :app:`Pyramid`
WSGI application. This function is meant to be called by the
:term:`PasteDeploy` framework as a result of running ``pserve``.
@@ -826,17 +826,20 @@ also informs Python that the directory which contains it is a *package*.
Line 7 creates an instance of a :term:`Configurator`.
- Line 8 registers a static view, which will serve up the files from the
+ Line 8 adds support for Chameleon templating bindings, allowing us to
+ specify renderers with the ``.pt`` extension.
+
+ Line 9 registers a static view, which will serve up the files from the
``myproject:static`` :term:`asset specification` (the ``static``
directory of the ``myproject`` package).
- Line 9 adds a :term:`route` to the configuration. This route is later
+ Line 10 adds a :term:`route` to the configuration. This route is later
used by a view in the ``views`` module.
- Line 10 calls ``config.scan()``, which picks up view registrations declared
+ Line 11 calls ``config.scan()``, which picks up view registrations declared
elsewhere in the package (in this case, in the ``views.py`` module).
- Line 11 returns a :term:`WSGI` application to the caller of the function
+ Line 12 returns a :term:`WSGI` application to the caller of the function
(Pyramid's pserve).
.. index::
diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst
index a2811dbae..3059aef35 100644
--- a/docs/narr/renderers.rst
+++ b/docs/narr/renderers.rst
@@ -67,9 +67,8 @@ When this configuration is added to an application, the
``myproject.views.my_view`` view callable will now use a ``json`` renderer,
which renders view return values to a :term:`JSON` response serialization.
-Other built-in renderers include renderers which use the :term:`Chameleon`
-templating language to render a dictionary to a response. Additional
-renderers can be added by developers to the system as necessary.
+Pyramid defines several :ref:`built_in_renderers`, and additional renderers
+can be added by developers to the system as necessary.
See :ref:`adding_and_overriding_renderers`.
Views which use a renderer and return a non-Response value can vary non-body
@@ -129,6 +128,11 @@ Built-In Renderers
Several built-in renderers exist in :app:`Pyramid`. These renderers can be
used in the ``renderer`` attribute of view configurations.
+.. note::
+
+ Bindings for officially supported templating languages can be found
+ at :ref:`available_template_system_bindings`.
+
.. index::
pair: renderer; string
@@ -203,13 +207,7 @@ representing the JSON serialization of the return value:
The return value needn't be a dictionary, but the return value must contain
values serializable by the configured serializer (by default ``json.dumps``).
-.. note::
-
- Extra arguments can be passed to the serializer by overriding the default
- ``json`` renderer. See :class:`pyramid.renderers.JSON` and
- :ref:`adding_and_overriding_renderers` for more information.
-
-You can configure a view to use the JSON renderer by naming ``json`` as the
+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`:
@@ -230,6 +228,18 @@ using the api of the ``request.response`` attribute. See
Serializing Custom Objects
++++++++++++++++++++++++++
+Some objects are not, by default, JSON-serializable (such as datetimes and
+other arbitrary Python objects). You can, however, register code that makes
+non-serializable objects serializable in two ways:
+
+- By defining a ``__json__`` method on objects in your application.
+
+- For objects you don't "own", you can register JSON renderer that knows about
+ an *adapter* for that kind of object.
+
+Using a Custom ``__json__`` Method
+**********************************
+
Custom objects can be made easily JSON-serializable in Pyramid by defining a
``__json__`` method on the object's class. This method should return values
natively JSON-serializable (such as ints, lists, dictionaries, strings, and
@@ -255,6 +265,9 @@ will be the active request object at render time.
# the JSON value returned by ``objects`` will be:
# [{"x": 1}, {"x": 2}]
+Using the ``add_adapter`` Method of a Custom JSON Renderer
+**********************************************************
+
If you aren't the author of the objects being serialized, it won't be
possible (or at least not reasonable) to add a custom ``__json__`` method
to their classes in order to influence serialization. If the object passed
@@ -269,19 +282,21 @@ objects using the registered adapters. A short example follows:
from pyramid.renderers import JSON
- json_renderer = JSON()
- def datetime_adapter(obj, request):
- return obj.isoformat()
- json_renderer.add_adapter(datetime.datetime, datetime_adapter)
+ if __name__ == '__main__':
+ config = Configurator()
+ json_renderer = JSON()
+ def datetime_adapter(obj, request):
+ return obj.isoformat()
+ json_renderer.add_adapter(datetime.datetime, datetime_adapter)
+ config.add_renderer('json', json_renderer)
- # then during configuration ....
- config = Configurator()
- config.add_renderer('json', json_renderer)
+The ``add_adapter`` method should accept two arguments: the *class* of the object that you want this adapter to run for (in the example above,
+``datetime.datetime``), and the adapter itself.
-The adapter should accept two arguments: the object needing to be serialized
-and ``request``, which will be the current request object at render time.
-The adapter should raise a :exc:`TypeError` if it can't determine what to do
-with the object.
+The adapter should be a callable. It should accept two arguments: the object
+needing to be serialized and ``request``, which will be the current request
+object at render time. The adapter should raise a :exc:`TypeError`
+if it can't determine what to do with the object.
See :class:`pyramid.renderers.JSON` and
:ref:`adding_and_overriding_renderers` for more information.
@@ -366,136 +381,6 @@ renderer in :ref:`json_serializing_custom_objects` can be used when passing
values to a JSONP renderer too.
.. index::
- pair: renderer; chameleon
-
-.. _chameleon_template_renderers:
-
-``*.pt`` or ``*.txt``: Chameleon Template Renderers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Two built-in renderers exist for :term:`Chameleon` templates.
-
-If the ``renderer`` attribute of a view configuration is an absolute path, a
-relative path or :term:`asset specification` which has a final path element
-with a filename extension of ``.pt``, the Chameleon ZPT renderer is used.
-See :ref:`chameleon_zpt_templates` for more information about ZPT templates.
-
-If the ``renderer`` attribute of a view configuration is an absolute path or
-a :term:`asset specification` which has a final path element with a filename
-extension of ``.txt``, the :term:`Chameleon` text renderer is used. See
-:ref:`chameleon_text_templates` for more information about Chameleon text
-templates.
-
-The behavior of these renderers is the same, except for the engine
-used to render the template.
-
-When a ``renderer`` attribute that names a template path or :term:`asset
-specification` (e.g. ``myproject:templates/foo.pt`` or
-``myproject:templates/foo.txt``) is used, the view must return a
-:term:`Response` object or a Python *dictionary*. If the view callable with
-an associated template returns a Python dictionary, the named template will
-be passed the dictionary as its keyword arguments, and the template renderer
-implementation will return the resulting rendered template in a response to
-the user. If the view callable returns anything but a Response object or a
-dictionary, an error will be raised.
-
-Before passing keywords to the template, the keyword arguments derived from
-the dictionary returned by the view are augmented. The callable object --
-whatever object was used to define the view -- will be automatically inserted
-into the set of keyword arguments passed to the template as the ``view``
-keyword. If the view callable was a class, the ``view`` keyword will be an
-instance of that class. Also inserted into the keywords passed to the
-template are ``renderer_name`` (the string used in the ``renderer`` attribute
-of the directive), ``renderer_info`` (an object containing renderer-related
-information), ``context`` (the context resource of the view used to render
-the template), and ``request`` (the request passed to the view used to render
-the template). ``request`` is also available as ``req`` in Pyramid 1.3+.
-
-Here's an example view configuration which uses a Chameleon ZPT renderer:
-
-.. code-block:: python
- :linenos:
-
- # config is an instance of pyramid.config.Configurator
-
- config.add_view('myproject.views.hello_world',
- name='hello',
- context='myproject.resources.Hello',
- renderer='myproject:templates/foo.pt')
-
-Here's an example view configuration which uses a Chameleon text renderer:
-
-.. code-block:: python
- :linenos:
-
- config.add_view('myproject.views.hello_world',
- name='hello',
- context='myproject.resources.Hello',
- renderer='myproject:templates/foo.txt')
-
-Views which use a Chameleon renderer can vary response attributes by using
-the API of the ``request.response`` attribute. See
-:ref:`request_response_attr`.
-
-.. index::
- pair: renderer; mako
-
-.. _mako_template_renderers:
-
-``*.mak`` or ``*.mako``: Mako Template Renderer
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``Mako`` template renderer renders views using a Mako template. When
-used, the view must return a Response object or a Python *dictionary*. The
-dictionary items will then be used in the global template space. If the view
-callable returns anything but a Response object or a dictionary, an error
-will be raised.
-
-When using a ``renderer`` argument to a :term:`view configuration` to specify
-a Mako template, the value of the ``renderer`` may be a path relative to the
-``mako.directories`` setting (e.g. ``some/template.mak``) or, alternately,
-it may be a :term:`asset specification`
-(e.g. ``apackage:templates/sometemplate.mak``). Mako templates may
-internally inherit other Mako templates using a relative filename or a
-:term:`asset specification` as desired.
-
-Here's an example view configuration which uses a relative path:
-
-.. code-block:: python
- :linenos:
-
- # config is an instance of pyramid.config.Configurator
-
- config.add_view('myproject.views.hello_world',
- name='hello',
- context='myproject.resources.Hello',
- renderer='foo.mak')
-
-It's important to note that in Mako's case, the 'relative' path name
-``foo.mak`` above is not relative to the package, but is relative to the
-directory (or directories) configured for Mako via the ``mako.directories``
-configuration file setting.
-
-The renderer can also be provided in :term:`asset specification`
-format. Here's an example view configuration which uses one:
-
-.. code-block:: python
- :linenos:
-
- config.add_view('myproject.views.hello_world',
- name='hello',
- context='myproject.resources.Hello',
- renderer='mypackage:templates/foo.mak')
-
-The above configuration will use the file named ``foo.mak`` in the
-``templates`` directory of the ``mypackage`` package.
-
-The ``Mako`` template renderer can take additional arguments beyond the
-standard ``pyramid.reload_templates`` setting, see the
-:ref:`environment_chapter` for additional
-:ref:`mako_template_renderer_settings`.
-
-.. index::
single: response headers (from a renderer)
single: renderer response headers
@@ -556,40 +441,6 @@ For more information on attributes of the request, see the API documentation
in :ref:`request_module`. For more information on the API of
``request.response``, see :attr:`pyramid.request.Request.response`.
-.. _response_prefixed_attrs:
-
-Deprecated Mechanism to Vary Attributes of Rendered Responses
--------------------------------------------------------------
-
-In previous releases of Pyramid (1.0 and before), the ``request.response``
-attribute did not exist. Instead, Pyramid required users to set special
-``response_`` -prefixed attributes of the request to influence response
-behavior. As of Pyramid 1.1, those request attributes are deprecated and
-their use will cause a deprecation warning to be issued when used. Until
-their existence is removed completely, we document them below, for benefit of
-people with older code bases.
-
-``response_content_type``
- Defines the content-type of the resulting response,
- e.g. ``text/xml``.
-
-``response_headerlist``
- A sequence of tuples describing header values that should be set in the
- response, e.g. ``[('Set-Cookie', 'abc=123'), ('X-My-Header', 'foo')]``.
-
-``response_status``
- A WSGI-style status code (e.g. ``200 OK``) describing the status of the
- response.
-
-``response_charset``
- The character set (e.g. ``UTF-8``) of the response.
-
-``response_cache_for``
- A value in seconds which will influence ``Cache-Control`` and ``Expires``
- headers in the returned response. The same can also be achieved by
- returning various values in the ``response_headerlist``, this is purely a
- convenience.
-
.. _adding_and_overriding_renderers:
Adding and Changing Renderers
@@ -739,44 +590,37 @@ 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.
-.. index::
- pair: renderer; changing
-
-Changing an Existing Renderer
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Adding a Default Renderer
+~~~~~~~~~~~~~~~~~~~~~~~~~
-You can associate more than one filename extension with the same existing
-renderer implementation as necessary if you need to use a different file
-extension for the same kinds of templates. For example, to associate the
-``.zpt`` extension with the Chameleon ZPT renderer factory, use the
-:meth:`pyramid.config.Configurator.add_renderer` method:
+To associate a *default* renderer with *all* view configurations (even
+ones which do not possess a ``renderer`` attribute), pass ``None`` as
+the ``name`` attribute to the renderer tag:
.. code-block:: python
- config.add_renderer('.zpt', 'pyramid.chameleon_zpt.renderer_factory')
-
-After you do this, :app:`Pyramid` will treat templates ending in both the
-``.pt`` and ``.zpt`` filename extensions as Chameleon ZPT templates.
-
-To change the default mapping in which files with a ``.pt`` extension are
-rendered via a Chameleon ZPT page template renderer, use a variation on the
-following in your application's startup code:
-
-.. code-block:: python
+ config.add_renderer(None, 'mypackage.json_renderer_factory')
- config.add_renderer('.pt', 'mypackage.pt_renderer')
+.. index::
+ pair: renderer; changing
-After you do this, the :term:`renderer factory` in
-``mypackage.pt_renderer`` will be used to render templates which end
-in ``.pt``, replacing the default Chameleon ZPT renderer.
+Changing an Existing Renderer
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-To associate a *default* renderer with *all* view configurations (even
-ones which do not possess a ``renderer`` attribute), pass ``None`` as
-the ``name`` attribute to the renderer tag:
+Pyramid supports overriding almost every aspect of its setup through its
+:ref:`Conflict Resolution <automatic_conflict_resolution>` mechanism. This
+means that in most cases overriding a renderer is as simple as using the
+:meth:`pyramid.config.Configurator.add_renderer` method to re-define the
+template extension. For example, if you would like to override the ``.txt``
+extension to specify a new renderer you could do the following:
.. code-block:: python
- config.add_renderer(None, 'mypackage.json_renderer_factory')
+ json_renderer = pyramid.renderers.JSON()
+ config.add_renderer('json', json_renderer)
+
+After doing this, any views registered with the ``json`` renderer will use
+the new renderer.
.. index::
pair: renderer; overriding at runtime
diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst
index 6437bd0fa..4b4e99d41 100644
--- a/docs/narr/subrequest.rst
+++ b/docs/narr/subrequest.rst
@@ -232,12 +232,12 @@ unconditionally:
- Ensures that the user implied by the request passed has the necessary
authorization to invoke view callable before calling it.
-- causes a :class:`~pyramid.events.NewResponse` event to be sent when the
- Pyramid application returns a response.
-
- Calls any :term:`response callback` functions defined within the subrequest's
lifetime if a response is obtained from the Pyramid application.
+- causes a :class:`~pyramid.events.NewResponse` event to be sent if a response
+ is obtained.
+
- Calls any :term:`finished callback` functions defined within the subrequest's
lifetime.
diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst
index 26bb6b6cd..3e19f7198 100644
--- a/docs/narr/templates.rst
+++ b/docs/narr/templates.rst
@@ -8,10 +8,6 @@ dynamic data provided by a :term:`view`. :app:`Pyramid` offers a
number of ways to perform templating tasks out of the box, and
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.
-
Before discussing how built-in templates are used in
detail, we'll discuss two ways to render templates within
:app:`Pyramid` in general: directly, and via renderer
@@ -32,7 +28,7 @@ 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 named
+: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:
@@ -60,19 +56,8 @@ 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
-prefix on Windows.
-
-.. warning::
-
- 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:`asset specification` in the form
+prefix on Windows. The path can alternately be a
+:term:`asset specification` in the form
``some.dotted.package_name:relative/path``. This makes it possible to
address template assets which live in another package. For example:
@@ -90,16 +75,9 @@ An asset specification points at a file within a Python *package*.
In this case, it points at a file named ``foo.pt`` within the
``templates`` directory of the ``mypackage`` package. Using a
asset specification instead of a relative template name is usually
-a good idea, because calls to ``render_to_response`` using asset
-specifications will continue to work properly if you move the code
-containing them around.
-
-.. note::
-
- Mako templating system bindings also respect absolute asset
- specifications as an argument to any of the ``render*`` commands. If a
- template name defines a ``:`` (colon) character and is not an absolute
- path, it is treated as an absolute asset specification.
+a good idea, because calls to :func:`~pyramid.renderers.render_to_response`
+using asset specifications will continue to work properly if you move the
+code containing them around.
In the examples above we pass in a keyword argument named ``request``
representing the current :app:`Pyramid` request. Passing a request
@@ -147,8 +125,8 @@ import its API functions into your views module, use those APIs to generate a
string, then return that string as the body of a :app:`Pyramid`
:term:`Response` object.
-For example, here's an example of using "raw" `Mako
-<http://www.makotemplates.org/>`_ from within a :app:`Pyramid` :term:`view`:
+For example, here's an example of using "raw" Mako_ from within a
+:app:`Pyramid` :term:`view`:
.. code-block:: python
:linenos:
@@ -163,10 +141,10 @@ For example, here's an example of using "raw" `Mako
return response
You probably wouldn't use this particular snippet in a project, because it's
-easier to use the Mako renderer bindings which already exist in
-:app:`Pyramid`. But if your favorite templating system is not supported as a
-renderer extension for :app:`Pyramid`, you can create your own simple
-combination as shown above.
+easier to use the supported
+:ref:`Mako bindings <available_template_system_bindings>`. But if your
+favorite templating system is not supported as a renderer extension for
+:app:`Pyramid`, you can create your own simple combination as shown above.
.. note::
@@ -281,8 +259,8 @@ 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 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.
+renderer itself, but most template renderers make these names available as
+top-level template variables.
.. index::
pair: renderer; templates
@@ -322,7 +300,9 @@ template renderer:
def my_view(request):
return {'foo':1, 'bar':2}
-.. note:: You do not need 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. :app:`Pyramid` automatically supplies this value for
you so that the "most correct" system values are provided to
@@ -350,11 +330,7 @@ it possible to address template assets which live in another package.
Not just any template from any arbitrary templating system may be used as a
renderer. Bindings must exist specifically for :app:`Pyramid` to use a
-templating language template as a renderer. Currently, :app:`Pyramid` has
-built-in support for two Chameleon templating languages: ZPT and text, and
-the Mako templating system. See :ref:`built_in_renderers` for a discussion
-of their details. :app:`Pyramid` also supports the use of :term:`Jinja2`
-templates as renderers. See :ref:`available_template_system_bindings`.
+templating language template as a renderer.
.. sidebar:: Why Use A Renderer via View Configuration
@@ -383,236 +359,6 @@ The same set of system values are provided to templates rendered via a
renderer view configuration as those provided to templates rendered
imperatively. See :ref:`renderer_system_values`.
-
-.. index::
- single: Chameleon ZPT templates
- single: ZPT templates (Chameleon)
-
-.. _chameleon_zpt_templates:
-
-:term:`Chameleon` ZPT Templates
--------------------------------
-
-Like :term:`Zope`, :app:`Pyramid` uses :term:`ZPT` (Zope Page
-Templates) as its default templating language. However,
-:app:`Pyramid` uses a different implementation of the :term:`ZPT`
-specification than Zope does: the :term:`Chameleon` templating
-engine. The Chameleon engine complies largely with the `Zope Page
-Template <http://wiki.zope.org/ZPT/FrontPage>`_ template
-specification. However, it is significantly faster.
-
-The language definition documentation for Chameleon ZPT-style
-templates is available from `the Chameleon website
-<http://chameleon.repoze.org/>`_.
-
-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:
-
- from pyramid.view import view_config
-
- @view_config(renderer='templates/foo.pt')
- def my_view(request):
- return {'foo':1, 'bar':2}
-
-See also :ref:`built_in_renderers` for more general information about
-renderers, including Chameleon ZPT renderers.
-
-.. index::
- single: ZPT template (sample)
-
-A Sample ZPT Template
-~~~~~~~~~~~~~~~~~~~~~
-
-Here's what a simple :term:`Chameleon` ZPT template used under
-:app:`Pyramid` might look like:
-
-.. code-block:: xml
- :linenos:
-
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:tal="http://xml.zope.org/namespaces/tal">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
- <title>${project} Application</title>
- </head>
- <body>
- <h1 class="title">Welcome to <code>${project}</code>, an
- application generated by the <a
- href="http://docs.pylonsproject.org/projects/pyramid/current/"
- >pyramid</a> web
- application framework.</h1>
- </body>
- </html>
-
-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
-attribute-based syntax (e.g. ``tal:content`` and ``tal:replace``) also
-works in these templates.
-
-.. index::
- single: ZPT macros
- single: Chameleon ZPT macros
-
-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 the
-context in :app:`Pyramid` is a :term:`resource` object, and templates cannot
-usually be retrieved from resources. 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:
-
- from pyramid.renderers import get_renderer
- from pyramid.view import view_config
-
- @view_config(renderer='templates/mytemplate.pt')
- def my_view(request):
- main = get_renderer('templates/master.pt').implementation()
- return {'main':main}
-
-Where ``templates/master.pt`` might look like so:
-
-.. code-block:: xml
- :linenos:
-
- <html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:tal="http://xml.zope.org/namespaces/tal"
- xmlns:metal="http://xml.zope.org/namespaces/metal">
- <span metal:define-macro="hello">
- <h1>
- Hello <span metal:define-slot="name">Fred</span>!
- </h1>
- </span>
- </html>
-
-And ``templates/mytemplate.pt`` might look like so:
-
-.. code-block:: xml
- :linenos:
-
- <html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:tal="http://xml.zope.org/namespaces/tal"
- xmlns:metal="http://xml.zope.org/namespaces/metal">
- <span metal:use-macro="main.macros['hello']">
- <span metal:fill-slot="name">Chris</span>
- </span>
- </html>
-
-
-Using A Chameleon Macro Name Within a Renderer Name
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-At times, you may want to render a macro inside of a Chameleon ZPT template
-instead of the full Chameleon ZPT template. To render the content of a
-``define-macro`` field inside a Chameleon ZPT template, given a Chameleon
-template file named ``foo.pt`` and a macro named ``bar`` defined within it
-(e.g. ``<div metal:define-macro="bar">...</div>``), you can configure the
-template as a :term:`renderer` like so:
-
-.. code-block:: python
- :linenos:
-
- from pyramid.view import view_config
-
- @view_config(renderer='foo#bar.pt')
- def my_view(request):
- return {'project':'my project'}
-
-The above will render only the ``bar`` macro defined within the ``foo.pt``
-template instead of the entire template.
-
-.. versionadded:: 1.4
-
-.. index::
- single: Chameleon text templates
-
-.. _chameleon_text_templates:
-
-Templating with :term:`Chameleon` Text Templates
-------------------------------------------------
-
-:app:`Pyramid` also allows for the use of templates which are
-composed entirely of non-XML text via :term:`Chameleon`. To do so,
-you can create templates that are entirely composed of text except for
-``${name}`` -style substitution points.
-
-Here's an example usage of a Chameleon text template. Create a file
-on disk named ``mytemplate.txt`` in your project's ``templates``
-directory with the following contents:
-
-.. code-block:: text
-
- Hello, ${name}!
-
-Then in your project's ``views.py`` module, you can create a view
-which renders this template:
-
-.. code-block:: python
- :linenos:
-
- from pyramid.view import view_config
-
- @view_config(renderer='templates/mytemplate.txt')
- def my_view(request):
- return {'name':'world'}
-
-When the template is rendered, it will show:
-
-.. code-block:: text
-
- Hello, world!
-
-See also :ref:`built_in_renderers` for more general information about
-renderers, including Chameleon text renderers.
-
-.. index::
- single: template renderer side effects
-
-Side Effects of Rendering a Chameleon Template
-----------------------------------------------
-
-When a Chameleon template is rendered from a file, the templating
-engine writes a file in the same directory as the template file itself
-as a kind of cache, in order to do less work the next time the
-template needs to be read from disk. If you see "strange" ``.py``
-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 configure it to ignore these files. Here's the contents of the
-author's ``svn propedit svn:ignore .`` in each of my ``templates``
-directories.
-
-.. code-block:: text
-
- *.pt.py
- *.txt.py
-
-Note that I always name my Chameleon ZPT template files with a ``.pt``
-extension and my Chameleon text template files with a ``.txt``
-extension so that these ``svn:ignore`` patterns work.
-
.. index::
pair: debugging; templates
@@ -644,107 +390,6 @@ The output tells you which template the error occurred in, as well as
displaying the arguments passed to the template itself.
.. index::
- single: template internationalization
- single: internationalization (of templates)
-
-:term:`Chameleon` Template Internationalization
------------------------------------------------
-
-See :ref:`chameleon_translation_strings` for information about
-supporting internationalized units of text within :term:`Chameleon`
-templates.
-
-.. index::
- single: Mako
-
-.. _mako_templates:
-
-Templating With Mako Templates
-------------------------------
-
-:term:`Mako` is a templating system written by Mike Bayer. :app:`Pyramid`
-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 a :term:`Mako` 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:
-
- from pyramid.view import view_config
-
- @view_config(renderer='foo.mak')
- def my_view(request):
- return {'project':'my project'}
-
-For the above view callable to work, the following setting needs to be
-present in the application stanza of your configuration's ``ini`` file:
-
-.. code-block:: ini
-
- mako.directories = mypackage:templates
-
-This lets the Mako templating system know that it should look for templates
-in the ``templates`` subdirectory of the ``mypackage`` Python package. See
-:ref:`mako_template_renderer_settings` for more information about the
-``mako.directories`` setting and other Mako-related settings that can be
-placed into the application's ``ini`` file.
-
-.. index::
- single: Mako template (sample)
-
-A Sample Mako Template
-~~~~~~~~~~~~~~~~~~~~~~
-
-Here's what a simple :term:`Mako` template used under :app:`Pyramid` might
-look like:
-
-.. code-block:: xml
- :linenos:
-
- <html>
- <head>
- <title>${project} Application</title>
- </head>
- <body>
- <h1 class="title">Welcome to <code>${project}</code>, an
- application generated by the <a
- href="http://docs.pylonsproject.org/projects/pyramid/current/"
- >pyramid</a> web framework.</h1>
- </body>
- </html>
-
-This template doesn't use any advanced features of Mako, only the
-``${}`` replacement syntax for names that are passed in as
-:term:`renderer globals`. See the `the Mako documentation
-<http://www.makotemplates.org/>`_ to use more advanced features.
-
-Using A Mako def name Within a Renderer Name
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Sometimes you'd like to render a ``def`` inside of a Mako template instead of
-the full Mako template. To render a def inside a Mako template, given a
-:term:`Mako` template file named ``foo.mak`` and a def named ``bar``, you can
-configure the template as a :term:`renderer` like so:
-
-.. code-block:: python
- :linenos:
-
- from pyramid.view import view_config
-
- @view_config(renderer='foo#bar.mak')
- def my_view(request):
- return {'project':'my project'}
-
-The above will render the ``bar`` def from within the ``foo.mak`` template
-instead of the entire template.
-
-.. versionadded:: 1.4
-
-.. index::
single: automatic reloading of templates
single: template automatic reload
@@ -759,9 +404,11 @@ 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
- production sites as it slows rendering slightly; it's
- usually only desirable during development.
+.. warning::
+
+ Auto-template-reload behavior is not recommended for
+ production sites as it slows rendering slightly; it's
+ usually only desirable during development.
In order to turn on automatic reloading of templates, you can use an
environment variable, or a configuration file setting.
@@ -772,31 +419,48 @@ variable set to ``1``, For example:
.. code-block:: text
- $ PYRAMID_RELOAD_TEMPLATES=1 $VENV/bin/pserve myproject.ini
+ $ PYRAMID_RELOAD_TEMPLATES=1 $VENV/bin/pserve myproject.ini
To use a setting in the application ``.ini`` file for the same
purpose, set the ``pyramid.reload_templates`` key to ``true`` within the
application's configuration section, e.g.:
.. code-block:: ini
- :linenos:
+ :linenos:
- [app:main]
- use = egg:MyProject
- pyramid.reload_templates = true
+ [app:main]
+ use = egg:MyProject
+ pyramid.reload_templates = true
.. index::
single: template system bindings
+ single: Chameleon
single: Jinja2
+ single: Mako
.. _available_template_system_bindings:
Available Add-On Template System Bindings
-----------------------------------------
-Jinja2 template bindings are available for :app:`Pyramid` in the
-``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).
+The Pylons Project maintains several packages providing bindings to different
+templating languages including the following:
+
++------------------------------+------------------------------+
+| Template Language | Pyramid Bindings |
++==============================+==============================+
+| Chameleon_ | pyramid_chameleon_ |
++------------------------------+------------------------------+
+| Jinja2_ | pyramid_jinja2_ |
++------------------------------+------------------------------+
+| Mako_ | pyramid_mako_ |
++------------------------------+------------------------------+
+
+.. _Chameleon: http://chameleon.readthedocs.org/en/latest/
+.. _pyramid_chameleon: https://pypi.python.org/pypi/pyramid_chameleon
+
+.. _Jinja2: http://jinja.pocoo.org/docs/
+.. _pyramid_jinja2: https://pypi.python.org/pypi/pyramid_jinja2
+.. _Mako: http://www.makotemplates.org/
+.. _pyramid_mako: https://pypi.python.org/pypi/pyramid_mako
diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst
index 62eb89348..61849c3c0 100644
--- a/docs/narr/urldispatch.rst
+++ b/docs/narr/urldispatch.rst
@@ -399,13 +399,6 @@ process. Examples of route predicate arguments are ``pattern``, ``xhr``, and
Other arguments are ``name`` and ``factory``. These arguments represent
neither predicates nor view configuration information.
-.. warning::
-
- Some arguments are view-configuration related arguments, such as
- ``view_renderer``. These only have an effect when the route configuration
- names a ``view`` and these arguments have been deprecated as of
- :app:`Pyramid` 1.1.
-
.. index::
single: route matching
diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst
index e55730a0d..4b23f7858 100644
--- a/docs/quick_tour.rst
+++ b/docs/quick_tour.rst
@@ -18,7 +18,7 @@ snippets of code to illustrate major concepts.
Python Setup
============
-First things first: we need our Python environment in ship-shape.
+First thing's first: we need our Python environment in ship-shape.
Pyramid encourages standard Python development practices (virtual
environments, packaging tools, logging, etc.) so let's get our working
area in place. For Python 3.3:
@@ -250,8 +250,9 @@ Python, but instead, will use a templating language.
Pyramid doesn't mandate a particular database system, form library,
etc. It encourages replaceability. This applies equally to templating,
which is fortunate: developers have strong views about template
-languages. That said, Pyramid bundles Chameleon and Mako,
-so in this step, let's use Chameleon as an example:
+languages. That said, the Pylons Project officially supports bindings for
+Chameleon, Jinja2 and Mako, so in this step, let's use Chameleon as an
+example:
.. literalinclude:: quick_tour/templating/views.py
:start-after: Start View 1
@@ -271,7 +272,7 @@ we can use ``name`` as a variable in our template via
.. seealso:: See Also: :doc:`../narr/templates`,
:ref:`debugging_templates`, and
- :ref:`mako_templates`
+ :ref:`available_template_system_bindings`
Templating With ``jinja2``
==========================
diff --git a/docs/tutorials/bfg/index.rst b/docs/tutorials/bfg/index.rst
deleted file mode 100644
index 1abb26466..000000000
--- a/docs/tutorials/bfg/index.rst
+++ /dev/null
@@ -1,204 +0,0 @@
-.. index::
- single: converting a BFG app
- single: bfg2pyramid
-
-.. _converting_a_bfg_app:
-
-Converting a :mod:`repoze.bfg` Application to :app:`Pyramid`
-============================================================
-
-Prior iterations of :app:`Pyramid` were released as a package named
-:mod:`repoze.bfg`. :mod:`repoze.bfg` users are encouraged to upgrade
-their deployments to :app:`Pyramid`, as, after the first final release
-of :app:`Pyramid`, further feature development on :mod:`repoze.bfg`
-will cease.
-
-Most existing :mod:`repoze.bfg` applications can be converted to a
-:app:`Pyramid` application in a completely automated fashion.
-However, if your application depends on packages which are not "core"
-parts of :mod:`repoze.bfg` but which nonetheless have ``repoze.bfg``
-in their names (e.g. ``repoze.bfg.skins``,
-``repoze.bfg.traversalwrapper``, ``repoze.bfg.jinja2``), you will need
-to find an analogue for each. For example, by the time you read this,
-there will be a ``pyramid_jinja2`` package, which can be used instead
-of ``repoze.bfg.jinja2``. If an analogue does not seem to exist for a
-``repoze.bfg`` add-on package that your application uses, please email
-the `Pylons-devel <http://groups.google.com/group/pylons-devel>`_
-maillist; we'll convert the package to a :app:`Pyramid` analogue for
-you.
-
-Here's how to convert a :mod:`repoze.bfg` application to a
-:app:`Pyramid` application:
-
-#. Ensure that your application works under :mod:`repoze.bfg` *version
- 1.3 or better*. See
- `http://docs.repoze.org/bfg/1.3/narr/install.html
- <http://docs.repoze.org/bfg/1.3/narr/install.html>`_ for
- :mod:`repoze.bfg` 1.3 installation instructions. If your
- application has an automated test suite, run it while your
- application is using :mod:`repoze.bfg` 1.3+. Otherwise, test it
- manually. It is only safe to proceed to the next step once your
- application works under :mod:`repoze.bfg` 1.3+.
-
- If your application has a proper set of dependencies, and a
- standard automated test suite, you might test your
- :mod:`repoze.bfg` application against :mod:`repoze.bfg` 1.3 like
- so:
-
- .. code-block:: bash
-
- $ $VENV/bin/python setup.py test
-
- ``bfgenv`` above will be the virtualenv into which you've installed
- :mod:`repoze.bfg` 1.3.
-
-#. Install :app:`Pyramid` into a *separate* virtualenv as per the
- instructions in :ref:`installing_chapter`. The :app:`Pyramid`
- virtualenv should be separate from the one you've used to install
- :mod:`repoze.bfg`. A quick way to do this:
-
- .. code-block:: bash
-
- $ cd ~
- $ virtualenv pyramidenv
- $ cd pyramidenv
- $ $VENV/bin/easy_install pyramid
-
-#. Put a *copy* of your :mod:`repoze.bfg` application into a temporary
- location (perhaps by checking a fresh copy of the application out
- of a version control repository). For example:
-
- .. code-block:: bash
-
- $ cd /tmp
- $ svn co http://my.server/my/bfg/application/trunk bfgapp
-
-#. Use the ``bfg2pyramid`` script present in the ``bin`` directory of
- the :app:`Pyramid` virtualenv to convert all :mod:`repoze.bfg`
- Python import statements into compatible :app:`Pyramid` import
- statements. ``bfg2pyramid`` will also fix ZCML directive usages of
- common :mod:`repoze.bfg` directives. You invoke ``bfg2pyramid`` by
- passing it the *path* of the copy of your application. The path
- passed should contain a "setup.py" file, representing your
- :mod:`repoze.bfg` application's setup script. ``bfg2pyramid`` will
- change the copy of the application *in place*.
-
- .. code-block:: bash
-
- $ ~/pyramidenv/bfg2pyramid /tmp/bfgapp
-
- ``bfg2pyramid`` will convert the following :mod:`repoze.bfg`
- application aspects to :app:`Pyramid` compatible analogues:
-
- - Python ``import`` statements naming :mod:`repoze.bfg` APIs will
- be converted to :app:`Pyramid` compatible ``import`` statements.
- Every Python file beneath the top-level path will be visited and
- converted recursively, except Python files which live in
- directories which start with a ``.`` (dot).
-
- - Each ZCML file found (recursively) within the path will have the
- default ``xmlns`` attribute attached to the ``configure`` tag
- changed from ``http://namespaces.repoze.org/bfg`` to
- ``http://pylonshq.com/pyramid``. Every ZCML file beneath the
- top-level path (files ending with ``.zcml``) will be visited and
- converted recursively, except ZCML files which live in
- directories which start with a ``.`` (dot).
-
- - ZCML files which contain directives that have attributes which
- name a ``repoze.bfg`` API module or attribute of an API module
- (e.g. ``context="repoze.bfg.exceptions.NotFound"``) will be
- converted to :app:`Pyramid` compatible ZCML attributes
- (e.g. ``context="pyramid.exceptions.NotFound``). Every ZCML file
- beneath the top-level path (files ending with ``.zcml``) will be
- visited and converted recursively, except ZCML files which live
- in directories which start with a ``.`` (dot).
-
-#. Edit the ``setup.py`` file of the application you've just converted
- (if you've been using the example paths, this will be
- ``/tmp/bfgapp/setup.py``) to depend on the ``pyramid`` distribution
- instead the of ``repoze.bfg`` distribution in its
- ``install_requires`` list. If you used a scaffold to
- create the :mod:`repoze.bfg` application, you can do so by changing
- the ``requires`` line near the top of the ``setup.py`` file. The
- original may look like this:
-
- .. code-block:: text
-
- requires = ['repoze.bfg', ... other dependencies ...]
-
- Edit the ``setup.py`` so it has:
-
- .. code-block:: text
-
- requires = ['pyramid', ... other dependencies ...]
-
- All other install-requires and tests-requires dependencies save for
- the one on ``repoze.bfg`` can remain the same.
-
-#. Convert any ``install_requires`` dependencies your application has
- on other add-on packages which have ``repoze.bfg`` in their names
- to :app:`Pyramid` compatible analogues (e.g. ``repoze.bfg.jinja2``
- should be replaced with ``pyramid_jinja2``). You may need to
- adjust configuration options and/or imports in your
- :mod:`repoze.bfg` application after replacing these add-ons. Read
- the documentation of the :app:`Pyramid` add-on package for
- information.
-
-#. *Only if you use ZCML and add-ons which use ZCML*: The default
- ``xmlns`` of the ``configure`` tag in ZCML has changed. The
- ``bfg2pyramid`` script effects the default namespace change (it
- changes the ``configure`` tag default ``xmlns`` from
- ``http://namespaces.repoze.org/bfg`` to
- ``http://pylonshq.com/pyramid``).
-
- This means that uses of add-ons which define ZCML directives in the
- ``http://namespaces.repoze.org/bfg`` namespace will begin to "fail"
- (they're actually not really failing, but your ZCML assumes that
- they will always be used within a ``configure`` tag which names the
- ``http://namespaces.repoze.org/bfg`` namespace as its default
- ``xmlns``). Symptom: when you attempt to start the application, an
- error such as ``ConfigurationError: ('Unknown directive',
- u'http://namespaces.repoze.org/bfg', u'workflow')`` is printed to
- the console and the application fails to start. In such a case,
- either add an ``xmlns="http://namespaces.repoze.org/bfg"``
- attribute to each tag which causes a failure, or define a namespace
- alias in the configure tag and prefix each failing tag. For
- example, change this "failing" tag instance::
-
- <configure xmlns="http://pylonshq.com/pyramid">
- <failingtag attr="foo"/>
- </configure>
-
- To this, which will begin to succeed::
-
- <configure xmlns="http://pylonshq.com/pyramid"
- xmlns:bfg="http://namespaces.repoze.org/bfg">
- <bfg:failingtag attr="foo"/>
- </configure>
-
- You will also need to add the ``pyramid_zcml`` package to your
- ``setup.py`` ``install_requires`` list. In Pyramid, ZCML configuration
- became an optional add-on supported by the ``pyramid_zcml`` package.
-
-#. Retest your application using :app:`Pyramid`. This might be as
- easy as:
-
- .. code-block:: bash
-
- $ cd /tmp/bfgapp
- $ $VENV/bin/python setup.py test
-
-#. Fix any test failures.
-
-#. Fix any code which generates deprecation warnings.
-
-#. Start using the converted version of your application. Celebrate.
-
-Two terminological changes have been made to Pyramid which make its
-documentation and newer APIs different than those of ``repoze.bfg``. The
-concept that BFG called ``model`` is called ``resource`` in Pyramid and the
-concept that BFG called ``resource`` is called ``asset`` in Pyramid. Various
-APIs have changed as a result (although all have backwards compatible shims).
-Additionally, the environment variables that influenced server behavior which
-used to be prefixed with ``BFG_`` (such as ``BFG_DEBUG_NOTFOUND``) must now
-be prefixed with ``PYRAMID_``.
diff --git a/docs/tutorials/wiki/basiclayout.rst b/docs/tutorials/wiki/basiclayout.rst
index 25ac9aabd..cdf52b73e 100644
--- a/docs/tutorials/wiki/basiclayout.rst
+++ b/docs/tutorials/wiki/basiclayout.rst
@@ -34,7 +34,10 @@ point happens to be the ``main`` function within the file named
factory` and the settings keywords parsed by :term:`PasteDeploy`. The root
factory is named ``root_factory``.
-#. *Line 15*. Register a "static view" which answers requests whose URL path
+#. *Line 15*. Include support for the :term:`Chameleon` template rendering
+ bindings, allowing us to use the ``.pt`` templates.
+
+#. *Line 16*. Register a "static view" which answers requests whose URL path
start with ``/static`` using the
:meth:`pyramid.config.Configurator.add_static_view` method. This
statement registers a view that will serve up static assets, such as CSS
@@ -47,7 +50,7 @@ point happens to be the ``main`` function within the file named
package. Alternatively the scaffold could have used an *absolute* asset
specification as the path (``tutorial:static``).
-#. *Line 16*. Perform a :term:`scan`. A scan will find :term:`configuration
+#. *Line 17*. Perform a :term:`scan`. A scan will find :term:`configuration
decoration`, such as view configuration decorators (e.g., ``@view_config``)
in the source code of the ``tutorial`` package and will take actions based
on these decorators. We don't pass any arguments to
@@ -56,7 +59,7 @@ point happens to be the ``main`` function within the file named
The scaffold could have equivalently said ``config.scan('tutorial')``, but
it chose to omit the package name argument.
-#. *Line 17*. Use the
+#. *Line 18*. Use the
:meth:`pyramid.config.Configurator.make_wsgi_app` method
to return a :term:`WSGI` application.
diff --git a/docs/tutorials/wiki/definingviews.rst b/docs/tutorials/wiki/definingviews.rst
index 23ee142af..e06468267 100644
--- a/docs/tutorials/wiki/definingviews.rst
+++ b/docs/tutorials/wiki/definingviews.rst
@@ -306,9 +306,9 @@ by the view (row 45). The view will use the ``body`` and
none of our tutorial views return in their dictionary.
``request`` is one of several
names that are available "by default" in a template when a template
- renderer is used. See :ref:`chameleon_template_renderers` for
+ renderer is used. See :ref:`renderer_system_values` for
information about other names that are available by default
- when a Chameleon template is used as a renderer.
+ when a template is used as a renderer.
Static Assets
-------------
diff --git a/docs/tutorials/wiki/src/authorization/setup.py b/docs/tutorials/wiki/src/authorization/setup.py
index 5d87fedbf..5ab4f73cd 100644
--- a/docs/tutorials/wiki/src/authorization/setup.py
+++ b/docs/tutorials/wiki/src/authorization/setup.py
@@ -10,6 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
requires = [
'pyramid',
+ 'pyramid_chameleon',
'pyramid_zodbconn',
'transaction',
'pyramid_tm',
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki/src/authorization/tutorial/__init__.py
index 8ea8f8fa3..39b94abd1 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/authorization/tutorial/__init__.py
@@ -21,6 +21,7 @@ def main(global_config, **settings):
config = Configurator(root_factory=root_factory, settings=settings)
config.set_authentication_policy(authn_policy)
config.set_authorization_policy(authz_policy)
+ config.include('pyramid_chameleon')
config.add_static_view('static', 'static', cache_max_age=3600)
config.scan()
return config.make_wsgi_app()
diff --git a/docs/tutorials/wiki/src/basiclayout/setup.py b/docs/tutorials/wiki/src/basiclayout/setup.py
index 75ba02611..da79881ab 100644
--- a/docs/tutorials/wiki/src/basiclayout/setup.py
+++ b/docs/tutorials/wiki/src/basiclayout/setup.py
@@ -10,6 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
requires = [
'pyramid',
+ 'pyramid_chameleon',
'pyramid_zodbconn',
'transaction',
'pyramid_tm',
diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py b/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py
index c3bb87a62..f2a86df47 100644
--- a/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py
@@ -12,6 +12,7 @@ def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
config = Configurator(root_factory=root_factory, settings=settings)
+ config.include('pyramid_chameleon')
config.add_static_view('static', 'static', cache_max_age=3600)
config.scan()
return config.make_wsgi_app()
diff --git a/docs/tutorials/wiki/src/models/setup.py b/docs/tutorials/wiki/src/models/setup.py
index 75ba02611..da79881ab 100644
--- a/docs/tutorials/wiki/src/models/setup.py
+++ b/docs/tutorials/wiki/src/models/setup.py
@@ -10,6 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
requires = [
'pyramid',
+ 'pyramid_chameleon',
'pyramid_zodbconn',
'transaction',
'pyramid_tm',
diff --git a/docs/tutorials/wiki/src/models/tutorial/__init__.py b/docs/tutorials/wiki/src/models/tutorial/__init__.py
index c3bb87a62..f2a86df47 100644
--- a/docs/tutorials/wiki/src/models/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/models/tutorial/__init__.py
@@ -12,6 +12,7 @@ def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
config = Configurator(root_factory=root_factory, settings=settings)
+ config.include('pyramid_chameleon')
config.add_static_view('static', 'static', cache_max_age=3600)
config.scan()
return config.make_wsgi_app()
diff --git a/docs/tutorials/wiki/src/tests/setup.py b/docs/tutorials/wiki/src/tests/setup.py
index 5ff7b545c..2e7ed2398 100644
--- a/docs/tutorials/wiki/src/tests/setup.py
+++ b/docs/tutorials/wiki/src/tests/setup.py
@@ -10,6 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
requires = [
'pyramid',
+ 'pyramid_chameleon',
'pyramid_zodbconn',
'transaction',
'pyramid_tm',
diff --git a/docs/tutorials/wiki/src/tests/tutorial/__init__.py b/docs/tutorials/wiki/src/tests/tutorial/__init__.py
index 8ea8f8fa3..bd3c5619f 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/tests/tutorial/__init__.py
@@ -19,6 +19,7 @@ def main(global_config, **settings):
'sosecret', callback=groupfinder, hashalg='sha512')
authz_policy = ACLAuthorizationPolicy()
config = Configurator(root_factory=root_factory, settings=settings)
+ config.include('pyramid_chameleon')
config.set_authentication_policy(authn_policy)
config.set_authorization_policy(authz_policy)
config.add_static_view('static', 'static', cache_max_age=3600)
diff --git a/docs/tutorials/wiki/src/views/setup.py b/docs/tutorials/wiki/src/views/setup.py
index 5d87fedbf..5ab4f73cd 100644
--- a/docs/tutorials/wiki/src/views/setup.py
+++ b/docs/tutorials/wiki/src/views/setup.py
@@ -10,6 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
requires = [
'pyramid',
+ 'pyramid_chameleon',
'pyramid_zodbconn',
'transaction',
'pyramid_tm',
diff --git a/docs/tutorials/wiki/src/views/tutorial/__init__.py b/docs/tutorials/wiki/src/views/tutorial/__init__.py
index c3bb87a62..f2a86df47 100644
--- a/docs/tutorials/wiki/src/views/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/views/tutorial/__init__.py
@@ -12,6 +12,7 @@ def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
config = Configurator(root_factory=root_factory, settings=settings)
+ config.include('pyramid_chameleon')
config.add_static_view('static', 'static', cache_max_age=3600)
config.scan()
return config.make_wsgi_app()
diff --git a/docs/tutorials/wiki/tests.rst b/docs/tutorials/wiki/tests.rst
index e40dc286b..e724f3e18 100644
--- a/docs/tutorials/wiki/tests.rst
+++ b/docs/tutorials/wiki/tests.rst
@@ -59,8 +59,8 @@ Change the ``requires`` list in ``setup.py`` to include ``WebTest``.
.. literalinclude:: src/tests/setup.py
:linenos:
:language: python
- :lines: 11-21
- :emphasize-lines: 10
+ :lines: 11-22
+ :emphasize-lines: 11
After we've added a dependency on WebTest in ``setup.py``, we need to rerun
``setup.py develop`` to get WebTest installed into our virtualenv. Assuming
diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst
index 01c301e74..cf20db6d7 100644
--- a/docs/tutorials/wiki2/authorization.rst
+++ b/docs/tutorials/wiki2/authorization.rst
@@ -83,7 +83,7 @@ statement at the head:
Add the following class definition:
.. literalinclude:: src/authorization/tutorial/models.py
- :lines: 36-40
+ :lines: 33-37
:linenos:
:language: python
@@ -203,7 +203,7 @@ Go back to ``tutorial/tutorial/__init__.py`` and add these two
routes:
.. literalinclude:: src/authorization/tutorial/__init__.py
- :lines: 30-31
+ :lines: 31-32
:linenos:
:language: python
@@ -329,7 +329,7 @@ when we're done:
.. literalinclude:: src/authorization/tutorial/__init__.py
:linenos:
- :emphasize-lines: 2-3,7,21-23,25-27,30-31
+ :emphasize-lines: 2-3,7,21-23,25-27,31-32
:language: python
(Only the highlighted lines need to be added.)
@@ -339,7 +339,7 @@ when we're done:
.. literalinclude:: src/authorization/tutorial/models.py
:linenos:
- :emphasize-lines: 1-4,36-40
+ :emphasize-lines: 1-4,33-37
:language: python
(Only the highlighted lines need to be added.)
diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst
index 0193afab4..05781c044 100644
--- a/docs/tutorials/wiki2/basiclayout.rst
+++ b/docs/tutorials/wiki2/basiclayout.rst
@@ -82,11 +82,18 @@ dictionary of settings parsed from the ``.ini`` file, which contains
deployment-related values such as ``pyramid.reload_templates``,
``db_string``, etc.
+Next, include :term:`Chameleon` templating bindings so that we can use
+renderers with the ``.pt`` extension within our project.
+
+ .. literalinclude:: src/basiclayout/tutorial/__init__.py
+ :lines: 17
+ :language: py
+
``main`` now calls :meth:`pyramid.config.Configurator.add_static_view` with
two arguments: ``static`` (the name), and ``static`` (the path):
.. literalinclude:: src/basiclayout/tutorial/__init__.py
- :lines: 17
+ :lines: 18
:language: py
This registers a static resource view which will match any URL that starts
@@ -104,7 +111,7 @@ via the :meth:`pyramid.config.Configurator.add_route` method that will be
used when the URL is ``/``:
.. literalinclude:: src/basiclayout/tutorial/__init__.py
- :lines: 18
+ :lines: 19
:language: py
Since this route has a ``pattern`` equalling ``/`` it is the route that will
@@ -118,7 +125,7 @@ view configuration will be registered, which will allow one of our
application URLs to be mapped to some code.
.. literalinclude:: src/basiclayout/tutorial/__init__.py
- :lines: 19
+ :lines: 20
:language: py
Finally, ``main`` is finished configuring things, so it uses the
@@ -126,7 +133,7 @@ Finally, ``main`` is finished configuring things, so it uses the
:term:`WSGI` application:
.. literalinclude:: src/basiclayout/tutorial/__init__.py
- :lines: 20
+ :lines: 21
:language: py
View Declarations via ``views.py``
@@ -225,10 +232,17 @@ To give a simple example of a model class, we define one named ``MyModel``:
:linenos:
:language: py
-Our example model has an ``__init__`` method that takes two arguments
-(``name``, and ``value``). It stores these values as ``self.name`` and
-``self.value`` on the instance created by the ``__init__`` function itself.
-The ``MyModel`` class also has a ``__tablename__`` attribute. This informs
+Our example model does not require an ``__init__`` method because SQLAlchemy
+supplies for us a default constructor if one is not already present,
+which accepts keyword arguments of the same name as that of the mapped attributes.
+
+.. note:: Example usage of MyModel:
+
+ .. code-block:: python
+
+ johnny = MyModel(name="John Doe", value=10)
+
+The ``MyModel`` class has a ``__tablename__`` attribute. This informs
SQLAlchemy which table to use to store the data representing instances of this
class.
diff --git a/docs/tutorials/wiki2/definingmodels.rst b/docs/tutorials/wiki2/definingmodels.rst
index 60427a911..e30af12b2 100644
--- a/docs/tutorials/wiki2/definingmodels.rst
+++ b/docs/tutorials/wiki2/definingmodels.rst
@@ -24,7 +24,7 @@ following:
.. literalinclude:: src/models/tutorial/models.py
:linenos:
:language: py
- :emphasize-lines: 20-22,25,27,29
+ :emphasize-lines: 20-22,25
(The highlighted lines are the ones that need to be changed.)
diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst
index a1e2313f3..49dbed50f 100644
--- a/docs/tutorials/wiki2/definingviews.rst
+++ b/docs/tutorials/wiki2/definingviews.rst
@@ -30,7 +30,7 @@ Open ``tutorial/setup.py`` and edit it to look like the following:
.. literalinclude:: src/views/setup.py
:linenos:
:language: python
- :emphasize-lines: 19
+ :emphasize-lines: 20
(Only the highlighted line needs to be added.)
@@ -272,9 +272,9 @@ by the view (row 45). The view will use the ``body`` and
none of our tutorial views return in their dictionary.
``request`` is one of several
names that are available "by default" in a template when a template
- renderer is used. See :ref:`chameleon_template_renderers` for
+ renderer is used. See :ref:`renderer_system_values` for
information about other names that are available by default
- when a Chameleon template is used as a renderer.
+ when a template is used as a renderer.
Static Assets
-------------
@@ -335,7 +335,7 @@ something like:
.. literalinclude:: src/views/tutorial/__init__.py
:linenos:
:language: python
- :emphasize-lines: 18-21
+ :emphasize-lines: 19-22
(The highlighted lines are the ones that need to be added or edited.)
diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py
index e8fa8f396..09bd63d33 100644
--- a/docs/tutorials/wiki2/src/authorization/setup.py
+++ b/docs/tutorials/wiki2/src/authorization/setup.py
@@ -10,10 +10,11 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
requires = [
'pyramid',
+ 'pyramid_chameleon',
+ 'pyramid_debugtoolbar',
+ 'pyramid_tm',
'SQLAlchemy',
'transaction',
- 'pyramid_tm',
- 'pyramid_debugtoolbar',
'zope.sqlalchemy',
'waitress',
'docutils',
diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py
index d08e55bf9..2ada42171 100644
--- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py
+++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py
@@ -25,6 +25,7 @@ def main(global_config, **settings):
root_factory='tutorial.models.RootFactory')
config.set_authentication_policy(authn_policy)
config.set_authorization_policy(authz_policy)
+ config.include('pyramid_chameleon')
config.add_static_view('static', 'static', cache_max_age=3600)
config.add_route('view_wiki', '/')
config.add_route('login', '/login')
diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models.py b/docs/tutorials/wiki2/src/authorization/tutorial/models.py
index 91e5a0019..4f7e1e024 100644
--- a/docs/tutorials/wiki2/src/authorization/tutorial/models.py
+++ b/docs/tutorials/wiki2/src/authorization/tutorial/models.py
@@ -29,9 +29,6 @@ class Page(Base):
name = Column(Text, unique=True)
data = Column(Text)
- def __init__(self, name, data):
- self.name = name
- self.data = data
class RootFactory(object):
__acl__ = [ (Allow, Everyone, 'view'),
diff --git a/docs/tutorials/wiki2/src/basiclayout/setup.py b/docs/tutorials/wiki2/src/basiclayout/setup.py
index e7d318128..15e7e5923 100644
--- a/docs/tutorials/wiki2/src/basiclayout/setup.py
+++ b/docs/tutorials/wiki2/src/basiclayout/setup.py
@@ -10,10 +10,11 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
requires = [
'pyramid',
+ 'pyramid_chameleon',
+ 'pyramid_debugtoolbar',
+ 'pyramid_tm',
'SQLAlchemy',
'transaction',
- 'pyramid_tm',
- 'pyramid_debugtoolbar',
'zope.sqlalchemy',
'waitress',
]
diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py
index aac7c5e69..867049e4f 100644
--- a/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py
+++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py
@@ -14,6 +14,7 @@ def main(global_config, **settings):
DBSession.configure(bind=engine)
Base.metadata.bind = engine
config = Configurator(settings=settings)
+ config.include('pyramid_chameleon')
config.add_static_view('static', 'static', cache_max_age=3600)
config.add_route('home', '/')
config.scan()
diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py
index aeeb9df64..0cdd4bbc3 100644
--- a/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py
+++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py
@@ -22,7 +22,3 @@ class MyModel(Base):
id = Column(Integer, primary_key=True)
name = Column(Text, unique=True)
value = Column(Integer)
-
- def __init__(self, name, value):
- self.name = name
- self.value = value
diff --git a/docs/tutorials/wiki2/src/models/setup.py b/docs/tutorials/wiki2/src/models/setup.py
index e7d318128..15e7e5923 100644
--- a/docs/tutorials/wiki2/src/models/setup.py
+++ b/docs/tutorials/wiki2/src/models/setup.py
@@ -10,10 +10,11 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
requires = [
'pyramid',
+ 'pyramid_chameleon',
+ 'pyramid_debugtoolbar',
+ 'pyramid_tm',
'SQLAlchemy',
'transaction',
- 'pyramid_tm',
- 'pyramid_debugtoolbar',
'zope.sqlalchemy',
'waitress',
]
diff --git a/docs/tutorials/wiki2/src/models/tutorial/__init__.py b/docs/tutorials/wiki2/src/models/tutorial/__init__.py
index aac7c5e69..867049e4f 100644
--- a/docs/tutorials/wiki2/src/models/tutorial/__init__.py
+++ b/docs/tutorials/wiki2/src/models/tutorial/__init__.py
@@ -14,6 +14,7 @@ def main(global_config, **settings):
DBSession.configure(bind=engine)
Base.metadata.bind = engine
config = Configurator(settings=settings)
+ config.include('pyramid_chameleon')
config.add_static_view('static', 'static', cache_max_age=3600)
config.add_route('home', '/')
config.scan()
diff --git a/docs/tutorials/wiki2/src/models/tutorial/models.py b/docs/tutorials/wiki2/src/models/tutorial/models.py
index 9a078d757..f028c917a 100644
--- a/docs/tutorials/wiki2/src/models/tutorial/models.py
+++ b/docs/tutorials/wiki2/src/models/tutorial/models.py
@@ -23,7 +23,3 @@ class Page(Base):
id = Column(Integer, primary_key=True)
name = Column(Text, unique=True)
data = Column(Text)
-
- def __init__(self, name, data):
- self.name = name
- self.data = data
diff --git a/docs/tutorials/wiki2/src/tests/setup.py b/docs/tutorials/wiki2/src/tests/setup.py
index c3da36b39..d8486e462 100644
--- a/docs/tutorials/wiki2/src/tests/setup.py
+++ b/docs/tutorials/wiki2/src/tests/setup.py
@@ -10,10 +10,11 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
requires = [
'pyramid',
+ 'pyramid_chameleon',
+ 'pyramid_debugtoolbar',
+ 'pyramid_tm',
'SQLAlchemy',
'transaction',
- 'pyramid_tm',
- 'pyramid_debugtoolbar',
'zope.sqlalchemy',
'waitress',
'docutils',
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/__init__.py b/docs/tutorials/wiki2/src/tests/tutorial/__init__.py
index d08e55bf9..cee89184b 100644
--- a/docs/tutorials/wiki2/src/tests/tutorial/__init__.py
+++ b/docs/tutorials/wiki2/src/tests/tutorial/__init__.py
@@ -23,6 +23,7 @@ def main(global_config, **settings):
authz_policy = ACLAuthorizationPolicy()
config = Configurator(settings=settings,
root_factory='tutorial.models.RootFactory')
+ config.include('pyramid_chameleon')
config.set_authentication_policy(authn_policy)
config.set_authorization_policy(authz_policy)
config.add_static_view('static', 'static', cache_max_age=3600)
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/models.py b/docs/tutorials/wiki2/src/tests/tutorial/models.py
index 91e5a0019..4f7e1e024 100644
--- a/docs/tutorials/wiki2/src/tests/tutorial/models.py
+++ b/docs/tutorials/wiki2/src/tests/tutorial/models.py
@@ -29,9 +29,6 @@ class Page(Base):
name = Column(Text, unique=True)
data = Column(Text)
- def __init__(self, name, data):
- self.name = name
- self.data = data
class RootFactory(object):
__acl__ = [ (Allow, Everyone, 'view'),
diff --git a/docs/tutorials/wiki2/src/views/setup.py b/docs/tutorials/wiki2/src/views/setup.py
index e8fa8f396..09bd63d33 100644
--- a/docs/tutorials/wiki2/src/views/setup.py
+++ b/docs/tutorials/wiki2/src/views/setup.py
@@ -10,10 +10,11 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
requires = [
'pyramid',
+ 'pyramid_chameleon',
+ 'pyramid_debugtoolbar',
+ 'pyramid_tm',
'SQLAlchemy',
'transaction',
- 'pyramid_tm',
- 'pyramid_debugtoolbar',
'zope.sqlalchemy',
'waitress',
'docutils',
diff --git a/docs/tutorials/wiki2/src/views/tutorial/__init__.py b/docs/tutorials/wiki2/src/views/tutorial/__init__.py
index c95bfdbf8..37cae1997 100644
--- a/docs/tutorials/wiki2/src/views/tutorial/__init__.py
+++ b/docs/tutorials/wiki2/src/views/tutorial/__init__.py
@@ -14,6 +14,7 @@ def main(global_config, **settings):
DBSession.configure(bind=engine)
Base.metadata.bind = engine
config = Configurator(settings=settings)
+ config.include('pyramid_chameleon')
config.add_static_view('static', 'static', cache_max_age=3600)
config.add_route('view_wiki', '/')
config.add_route('view_page', '/{pagename}')
diff --git a/docs/tutorials/wiki2/src/views/tutorial/models.py b/docs/tutorials/wiki2/src/views/tutorial/models.py
index 9a078d757..f028c917a 100644
--- a/docs/tutorials/wiki2/src/views/tutorial/models.py
+++ b/docs/tutorials/wiki2/src/views/tutorial/models.py
@@ -23,7 +23,3 @@ class Page(Base):
id = Column(Integer, primary_key=True)
name = Column(Text, unique=True)
data = Column(Text)
-
- def __init__(self, name, data):
- self.name = name
- self.data = data
diff --git a/docs/tutorials/wiki2/tests.rst b/docs/tutorials/wiki2/tests.rst
index 33b5d35c1..9aca0c5b7 100644
--- a/docs/tutorials/wiki2/tests.rst
+++ b/docs/tutorials/wiki2/tests.rst
@@ -54,8 +54,8 @@ Change the ``requires`` list in ``setup.py`` to include ``WebTest``.
.. literalinclude:: src/tests/setup.py
:linenos:
:language: python
- :lines: 11-21
- :emphasize-lines: 10
+ :lines: 11-22
+ :emphasize-lines: 11
After we've added a dependency on WebTest in ``setup.py``, we need to rerun
``setup.py develop`` to get WebTest installed into our virtualenv. Assuming
diff --git a/docs/whatsnew-1.0.rst b/docs/whatsnew-1.0.rst
index d1f3046ca..8750863e7 100644
--- a/docs/whatsnew-1.0.rst
+++ b/docs/whatsnew-1.0.rst
@@ -92,7 +92,7 @@ BFG Conversion Script
The ``bfg2pyramid`` conversion script performs a mostly automated conversion
of an existing :mod:`repoze.bfg` application to Pyramid. The process is
-described in :ref:`converting_a_bfg_app`.
+described in "Converting a BFG Application to Pyramid".
Scaffold Improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -203,8 +203,8 @@ Mako
~~~~
In addition to Chameleon templating, Pyramid now also provides built-in
-support for :term:`Mako` templating. See :ref:`mako_templates` for more
-information.
+support for :term:`Mako` templating. See
+:ref:`available_template_system_bindings` for more information.
URL Dispatch
~~~~~~~~~~~~
diff --git a/docs/whatsnew-1.1.rst b/docs/whatsnew-1.1.rst
index cc63017df..086c12ca2 100644
--- a/docs/whatsnew-1.1.rst
+++ b/docs/whatsnew-1.1.rst
@@ -540,11 +540,10 @@ Deprecations and Behavior Differences
within a static view returns the index.html properly. See also
https://github.com/Pylons/pyramid/issues/67.
-- Deprecated the
- :meth:`pyramid.config.Configurator.set_renderer_globals_factory` method and
- the ``renderer_globals`` Configurator constructor parameter. Users should
- convert code using this feature to use a BeforeRender event. See the section
- :ref:`beforerender_event` in the Hooks chapter.
+- Deprecated the ``pyramid.config.Configurator.set_renderer_globals_factory``
+ method and the ``renderer_globals`` Configurator constructor parameter.
+ Users should convert code using this feature to use a BeforeRender event. See
+ the section :ref:`beforerender_event` in the Hooks chapter.
- In Pyramid 1.0, the :class:`pyramid.events.subscriber` directive behaved
contrary to the documentation when passed more than one interface object to