summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-04-22 10:21:30 -0400
committerChris McDonough <chrism@plope.com>2011-04-22 10:21:30 -0400
commitc150d77248653172b487326a1059b8c0bc5056e4 (patch)
tree48b508a5e7047bc8d9ff77defaf82af87bdb2ec8
parentfeef5257261f3c37f11571a475dbd68f603b144e (diff)
parent1612fe799b5d36d3c7c39468be55b15777730f62 (diff)
downloadpyramid-c150d77248653172b487326a1059b8c0bc5056e4.tar.gz
pyramid-c150d77248653172b487326a1059b8c0bc5056e4.tar.bz2
pyramid-c150d77248653172b487326a1059b8c0bc5056e4.zip
Merge branch 'disambiguate_add_route' of https://github.com/mmerickel/pyramid into mmerickel-disambiguate_add_route
-rw-r--r--docs/narr/advconfig.rst2
-rw-r--r--docs/narr/assets.rst7
-rw-r--r--docs/narr/hybrid.rst30
-rw-r--r--docs/narr/urldispatch.rst77
-rw-r--r--docs/narr/viewconfig.rst3
-rw-r--r--docs/tutorials/wiki2/authorization.rst12
-rw-r--r--docs/tutorials/wiki2/basiclayout.rst37
-rw-r--r--docs/tutorials/wiki2/definingviews.rst38
-rw-r--r--docs/tutorials/wiki2/src/authorization/tutorial/__init__.py39
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py5
-rw-r--r--docs/tutorials/wiki2/src/models/tutorial/__init__.py5
-rw-r--r--docs/tutorials/wiki2/src/views/tutorial/__init__.py21
-rw-r--r--pyramid/config.py109
-rw-r--r--pyramid/paster_templates/routesalchemy/+package+/__init__.py_tmpl7
-rw-r--r--pyramid/static.py17
-rw-r--r--pyramid/tests/test_static.py84
16 files changed, 313 insertions, 180 deletions
diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst
index 099bce35f..7ae80155b 100644
--- a/docs/narr/advconfig.rst
+++ b/docs/narr/advconfig.rst
@@ -300,7 +300,7 @@ detection, because they're implemented in terms of conflict-aware methods:
- :meth:`~pyramid.config.Configurator.add_route` does a second type of
conflict detection when a ``view`` parameter is passed (it calls
- ``add_view``).
+ ``add_view``). This behavior has been deprecated in :app:`Pyramid` 1.1.
- :meth:`~pyramid.config.Configurator.static_view`, a frontend for
``add_route`` and ``add_view``.
diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst
index bbb673ecc..8d0e7058c 100644
--- a/docs/narr/assets.rst
+++ b/docs/narr/assets.rst
@@ -341,7 +341,8 @@ application's startup code.
# .. every other add_route declaration should come
# before this one, as it will, by default, catch all requests
- config.add_route('catchall_static', '/*subpath', 'myapp.static.static_view')
+ config.add_route('catchall_static', '/*subpath')
+ config.add_view('myapp.static.static_view', route_name='catchall_static')
The special name ``*subpath`` above is used by the
:class:`~pyramid.view.static` view callable to signify the path of the file
@@ -384,8 +385,8 @@ Or you might register it to be the view callable for a particular route:
.. code-block:: python
:linenos:
- config.add_route('favicon', '/favicon.ico',
- view='myapp.views.favicon_view')
+ config.add_route('favicon', '/favicon.ico')
+ config.add_view('myapp.views.favicon_view', route_name='favicon')
Because this is a simple view callable, it can be protected with a
:term:`permission` or can be configured to respond under different
diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst
index 780cb0975..d66ad59df 100644
--- a/docs/narr/hybrid.rst
+++ b/docs/narr/hybrid.rst
@@ -41,15 +41,15 @@ configuration:
# config is an instance of pyramid.config.Configurator
- config.add_route('foobar', '{foo}/{bar}', view='myproject.views.foobar')
- config.add_route('bazbuz', '{baz}/{buz}', view='myproject.views.bazbuz')
+ config.add_route('foobar', '{foo}/{bar}')
+ config.add_route('bazbuz', '{baz}/{buz}')
-Each :term:`route` typically corresponds to a single view callable,
-and when that route is matched during a request, the view callable
-named by the ``view`` attribute is invoked.
+ config.add_view('myproject.views.foobar', route_name='foobar')
+ config.add_view('myproject.views.bazbuz', route_name='bazbuz')
-Typically, an application that uses only URL dispatch won't perform any calls
-to :meth:`pyramid.config.Configurator.add_view` in its startup code.
+Each :term:`route` corresponds to one or more view callables,
+and when that route is matched during a request, :term:`view lookup` is used
+to match the request to one of the view callables.
Traversal Only
~~~~~~~~~~~~~~
@@ -196,12 +196,9 @@ remainder becomes the path used to perform traversal.
The ``*remainder`` route pattern syntax is explained in more
detail within :ref:`route_pattern_syntax`.
-Note that unlike the examples provided within :ref:`urldispatch_chapter`, the
-``add_route`` configuration statement named previously does not pass a
-``view`` argument. This is because a hybrid mode application relies on
-:term:`traversal` to do :term:`resource location` and :term:`view lookup`
-instead of invariably invoking a specific view callable named directly within
-the matched route's configuration.
+A hybrid mode application relies more heavily on :term:`traversal` to do
+:term:`resource location` and :term:`view lookup` than most examples indicate
+within :ref:`urldispatch_chapter`.
Because the pattern of the above route ends with ``*traverse``, when this
route configuration is matched during a request, :app:`Pyramid` will attempt
@@ -442,8 +439,8 @@ commonly in route declarations that look like this:
.. code-block:: python
:linenos:
- config.add_route('static', '/static/*subpath',
- view='mypackage.views.static_view')
+ config.add_route('static', '/static/*subpath')
+ config.add_view('mypackage.views.static_view', route_name='static')
Where ``mypackage.views.static_view`` is an instance of
:class:`pyramid.view.static`. This effectively tells the static helper to
@@ -458,6 +455,9 @@ application. We'll detail them here.
Registering a Default View for a Route That Has a ``view`` Attribute
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. note:: As of :app:`Pyramid` 1.1 this issue is deprecated along with
+ the ability to add views directly to the :term:`route configuration`.
+
It is an error to provide *both* a ``view`` argument to a :term:`route
configuration` *and* a :term:`view configuration` which names a
``route_name`` that has no ``name`` value or the empty ``name`` value. For
diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst
index 219753882..2a8052861 100644
--- a/docs/narr/urldispatch.rst
+++ b/docs/narr/urldispatch.rst
@@ -60,11 +60,13 @@ and port, e.g. ``/foo/bar`` in the URL ``http://localhost:8080/foo/bar``),
and a *route name*, which is used by developers within a :app:`Pyramid`
application to uniquely identify a particular route when generating a URL.
It also optionally has a ``factory``, a set of :term:`route predicate`
-parameters, and a set of :term:`view` parameters.
+parameters, and a set of view callables.
.. index::
single: add_route
+.. _config-add-route:
+
Configuring a Route via The ``add_route`` Configurator Method
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -79,19 +81,31 @@ example:
# pyramid.config.Configurator class; "myview" is assumed
# to be a "view callable" function
from views import myview
- config.add_route('myroute', '/prefix/{one}/{two}', view=myview)
+ config.add_route('myroute', '/prefix/{one}/{two}')
+ config.add_view(myview, route_name='myroute')
.. versionchanged:: 1.0a4
Prior to 1.0a4, routes allow for a marker starting with a ``:``, for
example ``/prefix/:one/:two``. This style is now deprecated
in favor of ``{}`` usage which allows for additional functionality.
+.. versionchanged:: 1.1
+ Prior to 1.1, views were typically connected to routes using a set of
+ view parameters on :meth:`pyramid.config.Configurator.add_route`. That
+ behavior is now deprecated in favor of connecting views to routes using
+ :meth:`pyramid.config.Configurator.add_view` with the ``route_name``
+ parameter.
+
.. index::
single: route configuration; view callable
Route Configuration That Names a View Callable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. warning:: This section describes a feature which has been deprecated in
+ Pyramid 1.1. The recommended way to connect view callables to routes
+ is via :ref:`config-add-route`.
+
When a route configuration declaration names a ``view`` attribute, the value
of the attribute will reference a :term:`view callable`. This view callable
will be invoked when the route matches. A view callable, as described in
@@ -363,8 +377,8 @@ resource of the view callable ultimately found via :term:`view lookup`.
.. code-block:: python
:linenos:
- config.add_route('abc', '/abc', view='myproject.views.theview',
- factory='myproject.resources.root_factory')
+ config.add_route('abc', '/abc', factory='myproject.resources.root_factory')
+ config.add_view('myproject.views.theview', route_name='abc')
The factory can either be a Python object or a :term:`dotted Python name` (a
string) which points to such a Python object, as it is above.
@@ -395,7 +409,8 @@ process. Examples of route predicate arguments are ``pattern``, ``xhr``, and
``request_method``.
Other arguments are view configuration related arguments. These only have an
-effect when the route configuration names a ``view``.
+effect when the route configuration names a ``view``. These arguments have
+been deprecated as of :app:`Pyramid` 1.1.
Other arguments are ``name`` and ``factory``. These arguments represent
neither predicates nor view configuration information.
@@ -547,8 +562,8 @@ If any route matches, the route matching process stops. The :term:`request`
is decorated with a special :term:`interface` which describes it as a "route
request", the :term:`context` resource is generated, and the context and the
resulting request are handed off to :term:`view lookup`. During view lookup,
-if any ``view`` argument was provided within the matched route configuration,
-the :term:`view callable` it points to is called.
+if any ``view`` was provided within the matched route configuration, the
+:term:`view callable` it points to is called.
When a route configuration is declared, it may contain :term:`route
predicate` arguments. All route predicates associated with a route
@@ -621,7 +636,8 @@ result in a particular view callable being invoked:
.. code-block:: python
:linenos:
- config.add_route('idea', 'site/{id}', view='mypackage.views.site_view')
+ config.add_route('idea', 'site/{id}')
+ config.add_view('mypackage.views.site_view', route_name='idea')
When a route configuration with a ``view`` attribute is added to the system,
and an incoming request matches the *pattern* of the route configuration, the
@@ -665,9 +681,13 @@ add to your application:
.. code-block:: python
:linenos:
- config.add_route('idea', 'ideas/{idea}', view='mypackage.views.idea_view')
- config.add_route('user', 'users/{user}', view='mypackage.views.user_view')
- config.add_route('tag', 'tags/{tags}', view='mypackage.views.tag_view')
+ config.add_route('idea', 'ideas/{idea}')
+ config.add_route('user', 'users/{user}')
+ config.add_route('tag', 'tags/{tags}')
+
+ config.add_view('mypackage.views.idea_view', route_name='idea')
+ config.add_view('mypackage.views.user_view', route_name='user')
+ config.add_view('mypackage.views.tag_view', route_name='tag')
The above configuration will allow :app:`Pyramid` to service URLs in these
forms:
@@ -717,9 +737,8 @@ An example of using a route with a factory:
.. code-block:: python
:linenos:
- config.add_route('idea', 'ideas/{idea}',
- view='myproject.views.idea_view',
- factory='myproject.resources.Idea')
+ config.add_route('idea', 'ideas/{idea}', factory='myproject.resources.Idea')
+ config.add_view('myproject.views.idea_view', route_name='idea')
The above route will manufacture an ``Idea`` resource as a :term:`context`,
assuming that ``mypackage.resources.Idea`` resolves to a class that accepts a
@@ -777,14 +796,14 @@ It's not entirely obvious how to use a route pattern to match the root URL
.. code-block:: python
:linenos:
- config.add_route('root', '', view='mypackage.views.root_view')
+ config.add_route('root', '')
Or provide the literal string ``/`` as the pattern:
.. code-block:: python
:linenos:
- config.add_route('root', '/', view='mypackage.views.root_view')
+ config.add_route('root', '/')
.. index::
single: generating route URLs
@@ -834,10 +853,11 @@ route configuration looks like so:
.. code-block:: python
:linenos:
- config.add_route('noslash', 'no_slash',
- view='myproject.views.no_slash')
- config.add_route('hasslash', 'has_slash/',
- view='myproject.views.has_slash')
+ config.add_route('noslash', 'no_slash')
+ config.add_route('hasslash', 'has_slash/')
+
+ config.add_view('myproject.views.no_slash', route_name='noslash')
+ config.add_view('myproject.views.has_slash', route_name='hasslash')
If a request enters the application with the ``PATH_INFO`` value of
``/has_slash/``, the second route will match. If a request enters the
@@ -1063,23 +1083,18 @@ is executed.
Route View Callable Registration and Lookup Details
---------------------------------------------------
-The purpose of making it possible to specify a view callable within a route
-configuration is to prevent developers from needing to deeply understand the
-details of :term:`resource location` and :term:`view lookup`. When a route
-names a view callable as a ``view`` argument, and a request enters the system
-which matches the pattern of the route, the result is simple: the view
-callable associated with the route is invoked with the request that caused
-the invocation.
+When a request enters the system which matches the pattern of the route,
+the result is simple: the view callable associated with the route is invoked
+with the request that caused the invocation.
For most usage, you needn't understand more than this; how it works is an
implementation detail. In the interest of completeness, however, we'll
explain how it *does* work in the this section. You can skip it if you're
uninterested.
-When a ``view`` attribute is attached to a route configuration,
-:app:`Pyramid` ensures that a :term:`view configuration` is registered that
-will always be found when the route pattern is matched during a request. To
-do so:
+When a ``view`` is attached to a route configuration, :app:`Pyramid` ensures
+that a :term:`view configuration` is registered that will always be found when
+the route pattern is matched during a request. To do so:
- A special route-specific :term:`interface` is created at startup time for
each route configuration declaration.
diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst
index 9b2500a2b..7ee8e3fe5 100644
--- a/docs/narr/viewconfig.rst
+++ b/docs/narr/viewconfig.rst
@@ -59,7 +59,8 @@ View configuration is performed in one of these ways:
- By specifying a view within a :term:`route configuration`. View
configuration via a route configuration is performed by using the
:meth:`pyramid.config.Configurator.add_route` method, passing a ``view``
- argument specifying a view callable.
+ argument specifying a view callable. This method is deprecated as of
+ :app:`Pyramid` 1.1.
.. note:: A package named ``pyramid_handlers`` (available from PyPI) provides
an analogue of :term:`Pylons` -style "controllers", which are a special
diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst
index 64cab30db..d0354af99 100644
--- a/docs/tutorials/wiki2/authorization.rst
+++ b/docs/tutorials/wiki2/authorization.rst
@@ -97,25 +97,25 @@ We'll also change ``__init__.py``, adding a call to
:term:`view callable`. This is also known as a :term:`forbidden view`:
.. literalinclude:: src/authorization/tutorial/__init__.py
- :lines: 24-26
+ :lines: 41-43
:linenos:
:language: python
A forbidden view configures our newly created login view to show up when
:app:`Pyramid` detects that a view invocation can not be authorized.
-We'll also add ``view_permission`` arguments with the value ``edit`` to the
-``edit_page`` and ``add_page`` routes. This indicates that the view
-callables which these routes reference cannot be invoked without the
+We'll also add ``permission`` arguments with the value ``edit`` to the
+``edit_page`` and ``add_page`` views. This indicates that the view
+callables which these views reference cannot be invoked without the
authenticated user possessing the ``edit`` permission with respect to the
current context.
.. literalinclude:: src/authorization/tutorial/__init__.py
- :lines: 32-39
+ :lines: 37-40
:linenos:
:language: python
-Adding these ``view_permission`` arguments causes Pyramid to make the
+Adding these ``permission`` arguments causes Pyramid to make the
assertion that only users who possess the effective ``edit`` permission at
the time of the request may invoke those two views. We've granted the
``group:editors`` principal the ``edit`` permission at the root model via its
diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst
index 0dbcf6684..bb39a686d 100644
--- a/docs/tutorials/wiki2/basiclayout.rst
+++ b/docs/tutorials/wiki2/basiclayout.rst
@@ -81,28 +81,33 @@ via the :meth:`pyramid.config.Configurator.add_route` method that will be
used when the URL is ``/``:
.. literalinclude:: src/basiclayout/tutorial/__init__.py
- :lines: 13-14
+ :lines: 13
:language: py
Since this route has a ``pattern`` equalling ``/`` it is the route that will
-be called when the URL ``/`` is visted, e.g. ``http://localhost:6543/``. The
-argument named ``view`` with the value ``tutorial.views.my_view`` is the
-dotted name to a *function* we write (generated by the
-``pyramid_routesalchemy`` scaffold) that is given a ``request`` object and
-which returns a response or a dictionary.
-
-You will use :meth:`pyramid.config.Configurator.add_route` statements in a
-:term:`URL dispatch` based application to map URLs to code. This route also
-names a ``view_renderer``, which is a template which lives in the
-``templates`` subdirectory of the package. When the
-``tutorial.views.my_view`` view returns a dictionary, a :term:`renderer` will
-use this template to create a response.
-
-Fimnally, we use the :meth:`pyramid.config.Configurator.make_wsgi_app`
+be called when the URL ``/`` is visted, e.g. ``http://localhost:6543/``.
+
+Mapping the ``home`` route to code is done by registering a ``view``. You will
+use :meth:`pyramid.config.Configurator.add_view` in :term:`URL dispatch` to
+register views for the routes, mapping your patterns to code:
+
+ .. literalinclude:: src/basiclayout/tutorial/__init__.py
+ :lines: 14
+ :language: py
+
+The ``view`` argument of ``tutorial.views.my_view`` is the dotted name to a
+*function* we write (generated by the ``pyramid_routesalchemy`` scaffold) that
+is given a ``request`` object and which returns a response or a dictionary.
+This view also names a ``renderer``, which is a template which lives in the
+``templates`` subdirectory of the package. When the ``tutorial.views.my_view``
+view returns a dictionary, a :term:`renderer` will use this template to create
+a response.
+
+Finally, we use the :meth:`pyramid.config.Configurator.make_wsgi_app`
method to return a :term:`WSGI` application:
.. literalinclude:: src/basiclayout/tutorial/__init__.py
- :lines: 15
+ :lines: 16
:language: py
Our final ``__init__.py`` file will look like this:
diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst
index c5a452d11..f59f75702 100644
--- a/docs/tutorials/wiki2/definingviews.rst
+++ b/docs/tutorials/wiki2/definingviews.rst
@@ -272,8 +272,8 @@ Mapping Views to URLs in ``__init__.py``
========================================
The ``__init__.py`` file contains
-:meth:`pyramid.config.Configurator.add_route` calls which serve to map
-URLs via :term:`url dispatch` to view functions. First, we’ll get rid of the
+:meth:`pyramid.config.Configurator.add_view` calls which serve to map
+routes via :term:`url dispatch` to views. First, we’ll get rid of the
existing route created by the template using the name ``home``. It’s only an
example and isn’t relevant to our application.
@@ -282,21 +282,33 @@ these declarations is very important. ``route`` declarations are matched in
the order they're found in the ``__init__.py`` file.
#. Add a declaration which maps the pattern ``/`` (signifying the root URL)
- to the view named ``view_wiki`` in our ``views.py`` file with the name
- ``view_wiki``. This is the :term:`default view` for the wiki.
+ to the route named ``view_wiki``. This is the :term:`default view` for the
+ wiki.
-#. Add a declaration which maps the pattern ``/{pagename}`` to the view named
- ``view_page`` in our ``views.py`` file with the view name ``view_page``.
- This is the regular view for a page.
+#. Add a declaration which maps the pattern ``/{pagename}`` to the route named
+ ``view_page``. This is the regular view for a page.
-#. Add a declaration which maps the pattern
- ``/add_page/{pagename}`` to the view named ``add_page`` in our
- ``views.py`` file with the name ``add_page``. This is the add view
- for a new page.
+#. Add a declaration which maps the pattern ``/add_page/{pagename}`` to the
+ route named ``add_page``. This is the add view for a new page.
#. Add a declaration which maps the pattern ``/{pagename}/edit_page`` to the
- view named ``edit_page`` in our ``views.py`` file with the name
- ``edit_page``. This is the edit view for a page.
+ route named ``edit_page``. This is the edit view for a page.
+
+After we've defined the routes for our application, we can register views
+to handle the processing and rendering that needs to happen when each route is
+requested.
+
+#. Add a declaration which maps the ``view_wiki`` route to the view named
+ ``view_wiki`` in our ``views.py`` file.
+
+#. Add a declaration which maps the ``view_page`` route to the view named
+ ``view_page`` in our ``views.py`` file.
+
+#. Add a declaration which maps the ``add_page`` route to the view named
+ ``add_page`` in our ``views.py`` file.
+
+#. Add a declaration which maps the ``edit_page`` route to the view named
+ ``edit_page`` in our ``views.py`` file.
As a result of our edits, the ``__init__.py`` file should look
something like so:
diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py
index 025b94927..7da99775c 100644
--- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py
+++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py
@@ -20,25 +20,26 @@ def main(global_config, **settings):
authentication_policy=authn_policy,
authorization_policy=authz_policy)
config.add_static_view('static', 'tutorial:static')
- config.add_route('view_wiki', '/', view='tutorial.views.view_wiki')
- config.add_route('login', '/login',
- view='tutorial.login.login',
- view_renderer='tutorial:templates/login.pt')
- config.add_route('logout', '/logout',
- view='tutorial.login.logout')
- config.add_route('view_page', '/{pagename}',
- view='tutorial.views.view_page',
- view_renderer='tutorial:templates/view.pt')
- config.add_route('add_page', '/add_page/{pagename}',
- view='tutorial.views.add_page',
- view_renderer='tutorial:templates/edit.pt',
- view_permission='edit')
- config.add_route('edit_page', '/{pagename}/edit_page',
- view='tutorial.views.edit_page',
- view_renderer='tutorial:templates/edit.pt',
- view_permission='edit')
+
+ config.add_route('view_wiki', '/')
+ config.add_route('login', '/login')
+ config.add_route('logout', '/logout')
+ config.add_route('view_page', '/{pagename}')
+ config.add_route('add_page', '/add_page/{pagename}')
+ config.add_route('edit_page', '/{pagename}/edit_page')
+ config.add_route('view_wiki', '/')
+
+ config.add_view(route_name='login', view='tutorial.login.login',
+ renderer='tutorial:templates/login.pt')
+ config.add_view(route_name='logout', view='tutorial.login.logout')
+ config.add_view(route_name='view_page', view='tutorial.views.view_page',
+ renderer='tutorial:templates/view.pt')
+ config.add_view(route_name='add_page', view='tutorial.views.add_page',
+ renderer='tutorial:templates/edit.pt', permission='edit')
+ config.add_view(route_name='edit_page', view='tutorial.views.edit_page',
+ renderer='tutorial:templates/edit.pt', permission='edit')
config.add_view('tutorial.login.login',
- renderer='tutorial:templates/login.pt',
- context='pyramid.exceptions.Forbidden')
+ context='pyramid.exceptions.Forbidden',
+ renderer='tutorial:templates/login.pt')
return config.make_wsgi_app()
diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py
index d27b891c0..43fd7f0fe 100644
--- a/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py
+++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py
@@ -10,8 +10,9 @@ def main(global_config, **settings):
initialize_sql(engine)
config = Configurator(settings=settings)
config.add_static_view('static', 'tutorial:static')
- config.add_route('home', '/', view='tutorial.views.my_view',
- view_renderer='templates/mytemplate.pt')
+ config.add_route('home', '/')
+ config.add_view(route_name='home', view='tutorial.views.my_view',
+ renderer='templates/mytemplate.pt')
return config.make_wsgi_app()
diff --git a/docs/tutorials/wiki2/src/models/tutorial/__init__.py b/docs/tutorials/wiki2/src/models/tutorial/__init__.py
index c912a015b..ff46bbf8f 100644
--- a/docs/tutorials/wiki2/src/models/tutorial/__init__.py
+++ b/docs/tutorials/wiki2/src/models/tutorial/__init__.py
@@ -10,6 +10,7 @@ def main(global_config, **settings):
initialize_sql(engine)
config = Configurator(settings=settings)
config.add_static_view('static', 'tutorial:static')
- config.add_route('home', '/', view='tutorial.views.my_view',
- view_renderer='templates/mytemplate.pt')
+ config.add_route('home', '/')
+ config.add_view(route_name='home', view='tutorial.views.my_view',
+ renderer='templates/mytemplate.pt')
return config.make_wsgi_app()
diff --git a/docs/tutorials/wiki2/src/views/tutorial/__init__.py b/docs/tutorials/wiki2/src/views/tutorial/__init__.py
index 1a8d24499..93abf83e7 100644
--- a/docs/tutorials/wiki2/src/views/tutorial/__init__.py
+++ b/docs/tutorials/wiki2/src/views/tutorial/__init__.py
@@ -10,15 +10,16 @@ def main(global_config, **settings):
initialize_sql(engine)
config = Configurator(settings=settings)
config.add_static_view('static', 'tutorial:static')
- config.add_route('view_wiki', '/', view='tutorial.views.view_wiki')
- config.add_route('view_page', '/{pagename}',
- view='tutorial.views.view_page',
- view_renderer='tutorial:templates/view.pt')
- config.add_route('add_page', '/add_page/{pagename}',
- view='tutorial.views.add_page',
- view_renderer='tutorial:templates/edit.pt')
- config.add_route('edit_page', '/{pagename}/edit_page',
- view='tutorial.views.edit_page',
- view_renderer='tutorial:templates/edit.pt')
+ config.add_route('view_wiki', '/')
+ config.add_route('view_page', '/{pagename}')
+ config.add_route('add_page', '/add_page/{pagename}')
+ config.add_route('edit_page', '/{pagename}/edit_page')
+ config.add_view(route_name='view_wiki', view='tutorial.views.view_wiki')
+ config.add_view(route_name='view_page', view='tutorial.views.view_page',
+ renderer='tutorial:templates/view.pt')
+ config.add_view(route_name='add_page', view='tutorial.views.add_page',
+ renderer='tutorial:templates/edit.pt')
+ config.add_view(route_name='edit_page', view='tutorial.views.edit_page',
+ renderer='tutorial:templates/edit.pt')
return config.make_wsgi_app()
diff --git a/pyramid/config.py b/pyramid/config.py
index 9fda75daa..334e00201 100644
--- a/pyramid/config.py
+++ b/pyramid/config.py
@@ -13,6 +13,8 @@ from zope.configuration.config import GroupingContextDecorator
from zope.configuration.config import ConfigurationMachine
from zope.configuration.xmlconfig import registerCommonDirectives
+from zope.deprecation import deprecated
+
from zope.interface import Interface
from zope.interface import implementedBy
from zope.interface.interfaces import IInterface
@@ -1379,6 +1381,48 @@ class Configurator(object):
self.action(discriminator, register)
@action_method
+ def _add_view_from_route(self,
+ route_name,
+ view,
+ context,
+ permission,
+ renderer,
+ attr,
+ ):
+ if view:
+ self.add_view(
+ permission=permission,
+ context=context,
+ view=view,
+ name='',
+ route_name=route_name,
+ renderer=renderer,
+ attr=attr,
+ )
+ else:
+ # prevent mistakes due to misunderstanding of how hybrid calls to
+ # add_route and add_view interact
+ if attr:
+ raise ConfigurationError(
+ 'view_attr argument not permitted without view '
+ 'argument')
+ if context:
+ raise ConfigurationError(
+ 'view_context argument not permitted without view '
+ 'argument')
+ if permission:
+ raise ConfigurationError(
+ 'view_permission argument not permitted without view '
+ 'argument')
+ if renderer:
+ raise ConfigurationError(
+ 'view_renderer argument not permitted without '
+ 'view argument')
+ _add_view_from_route = deprecated(
+ _add_view_from_route, 'Use add_view() to add views for a route. No '
+ 'longer supported directly from add_route() in pyramid 1.1')
+
+ @action_method
def add_route(self,
name,
pattern=None,
@@ -1413,6 +1457,13 @@ class Configurator(object):
narrow the circumstances in which a route will be match a
request; non-predicate arguments are informational.
+ .. warning:: View-related arguments have been deprecated in
+ :app:`Pyramid` 1.1. *Do not use it for new development;
+ it should only be used to support older code bases which
+ depend upon it.* Use
+ :meth:`pyramid.config.Configurator.add_view` to add views
+ to a route.
+
Non-Predicate Arguments
name
@@ -1594,12 +1645,18 @@ class Configurator(object):
view
+ .. warning:: Deprecated in favor of
+ :meth:`pyramid.config.Configurator.add_view`.
+
A Python object or :term:`dotted Python name` to the same
object that will be used as a view callable when this route
matches. e.g. ``mypackage.views.my_view``.
view_context
+ .. warning:: Deprecated in favor of
+ :meth:`pyramid.config.Configurator.add_view`.
+
A class or an :term:`interface` or :term:`dotted Python
name` to the same object which the :term:`context` of the
view should match for the view named by the route to be
@@ -1614,6 +1671,9 @@ class Configurator(object):
view_permission
+ .. warning:: Deprecated in favor of
+ :meth:`pyramid.config.Configurator.add_view`.
+
The permission name required to invoke the view associated
with this route. e.g. ``edit``. (see
:ref:`using_security_with_urldispatch` for more information
@@ -1626,6 +1686,9 @@ class Configurator(object):
view_renderer
+ .. warning:: Deprecated in favor of
+ :meth:`pyramid.config.Configurator.add_view`.
+
This is either a single string term (e.g. ``json``) or a
string implying a path or :term:`asset specification`
(e.g. ``templates/views.pt``). If the renderer value is a
@@ -1648,6 +1711,9 @@ class Configurator(object):
view_attr
+ .. warning:: Deprecated in favor of
+ :meth:`pyramid.config.Configurator.add_view`.
+
The view machinery defaults to using the ``__call__`` method
of the view callable (or the function itself, if the view
callable is a function) to obtain a response dictionary.
@@ -1698,42 +1764,17 @@ class Configurator(object):
for info in view_info:
self.add_view(**info)
- if view_context is None:
- view_context = view_for
- if view_context is None:
- view_context = for_
- view_permission = view_permission or permission
- view_renderer = view_renderer or renderer
-
- if view:
- self.add_view(
- permission=view_permission,
- context=view_context,
- view=view,
- name='',
+ # deprecated adding views from add_route
+ if view or view_context or view_permission or view_renderer or \
+ view_for or for_ or permission or renderer or view_attr:
+ self._add_view_from_route(
route_name=name,
- renderer=view_renderer,
+ view=view,
+ permission=view_permission or permission,
+ context=view_context or view_for or for_,
+ renderer=view_renderer or renderer,
attr=view_attr,
- )
- else:
- # prevent mistakes due to misunderstanding of how hybrid calls to
- # add_route and add_view interact
- if view_attr:
- raise ConfigurationError(
- 'view_attr argument not permitted without view '
- 'argument')
- if view_context:
- raise ConfigurationError(
- 'view_context argument not permitted without view '
- 'argument')
- if view_permission:
- raise ConfigurationError(
- 'view_permission argument not permitted without view '
- 'argument')
- if view_renderer:
- raise ConfigurationError(
- 'view_renderer argument not permitted without '
- 'view argument')
+ )
mapper = self.get_routes_mapper()
diff --git a/pyramid/paster_templates/routesalchemy/+package+/__init__.py_tmpl b/pyramid/paster_templates/routesalchemy/+package+/__init__.py_tmpl
index 479740297..aea2393d6 100644
--- a/pyramid/paster_templates/routesalchemy/+package+/__init__.py_tmpl
+++ b/pyramid/paster_templates/routesalchemy/+package+/__init__.py_tmpl
@@ -10,8 +10,9 @@ def main(global_config, **settings):
initialize_sql(engine)
config = Configurator(settings=settings)
config.add_static_view('static', '{{package}}:static')
- config.add_route('home', '/', view='{{package}}.views.my_view',
- view_renderer='templates/mytemplate.pt')
+ config.add_route('home', '/')
+ config.add_view(route_name='home',
+ view='{{package}}.views.my_view',
+ renderer='templates/mytemplate.pt')
return config.make_wsgi_app()
-
diff --git a/pyramid/static.py b/pyramid/static.py
index 170b027f1..ec7b4cb00 100644
--- a/pyramid/static.py
+++ b/pyramid/static.py
@@ -149,13 +149,26 @@ class StaticURLInfo(object):
permission = extra.pop('permission', None)
if permission is None:
permission = '__no_permission_required__'
- extra['view_permission'] = permission
- extra['view'] = view
+
+ context = extra.pop('view_context', None)
+ if context is None:
+ context = extra.pop('view_for', None)
+ if context is None:
+ context = extra.pop('for_', None)
+
+ renderer = extra.pop('view_renderer', None)
+ if renderer is None:
+ renderer = extra.pop('renderer', None)
+
+ attr = extra.pop('view_attr', None)
# register a route using the computed view, permission, and
# pattern, plus any extras passed to us via add_static_view
pattern = "%s*subpath" % name # name already ends with slash
self.config.add_route(name, pattern, **extra)
+ self.config.add_view(route_name=name, view=view,
+ permission=permission, context=context,
+ renderer=renderer, attr=attr)
self.registrations.append((name, spec, False))
class static_view(object):
diff --git a/pyramid/tests/test_static.py b/pyramid/tests/test_static.py
index 588dc32e2..e7506628a 100644
--- a/pyramid/tests/test_static.py
+++ b/pyramid/tests/test_static.py
@@ -391,43 +391,83 @@ class TestStaticURLInfo(unittest.TestCase):
def test_add_viewname(self):
from pyramid.static import static_view
- class Config:
- def add_route(self, *arg, **kw):
- self.arg = arg
- self.kw = kw
- config = Config()
+ config = DummyConfig()
inst = self._makeOne(config)
inst.add('view', 'anotherpackage:path', cache_max_age=1)
expected = [('view/', 'anotherpackage:path/', False)]
self.assertEqual(inst.registrations, expected)
- self.assertEqual(config.arg, ('view/', 'view/*subpath'))
- self.assertEqual(config.kw['view_permission'],
+ self.assertEqual(config.route_args, ('view/', 'view/*subpath'))
+ self.assertEqual(config.view_kw['permission'],
'__no_permission_required__')
- self.assertEqual(config.kw['view'].__class__, static_view)
- self.assertEqual(config.kw['view'].app.cache_max_age, 1)
- self.assertEqual(inst.registrations, expected)
+ self.assertEqual(config.view_kw['view'].__class__, static_view)
+ self.assertEqual(config.view_kw['view'].app.cache_max_age, 1)
def test_add_viewname_with_permission(self):
- class Config:
- def add_route(self, *arg, **kw):
- self.arg = arg
- self.kw = kw
- config = Config()
+ config = DummyConfig()
inst = self._makeOne(config)
inst.add('view', 'anotherpackage:path', cache_max_age=1,
permission='abc')
- self.assertEqual(config.kw['view_permission'], 'abc')
+ self.assertEqual(config.view_kw['permission'], 'abc')
def test_add_viewname_with_view_permission(self):
- class Config:
- def add_route(self, *arg, **kw):
- self.arg = arg
- self.kw = kw
- config = Config()
+ config = DummyConfig()
inst = self._makeOne(config)
inst.add('view', 'anotherpackage:path', cache_max_age=1,
view_permission='abc')
- self.assertEqual(config.kw['view_permission'], 'abc')
+ self.assertEqual(config.view_kw['permission'], 'abc')
+
+ def test_add_viewname_with_view_context(self):
+ config = DummyConfig()
+ inst = self._makeOne(config)
+ inst.add('view', 'anotherpackage:path', cache_max_age=1,
+ view_context=DummyContext)
+ self.assertEqual(config.view_kw['context'], DummyContext)
+
+ def test_add_viewname_with_view_for(self):
+ config = DummyConfig()
+ inst = self._makeOne(config)
+ inst.add('view', 'anotherpackage:path', cache_max_age=1,
+ view_for=DummyContext)
+ self.assertEqual(config.view_kw['context'], DummyContext)
+
+ def test_add_viewname_with_for_(self):
+ config = DummyConfig()
+ inst = self._makeOne(config)
+ inst.add('view', 'anotherpackage:path', cache_max_age=1,
+ for_=DummyContext)
+ self.assertEqual(config.view_kw['context'], DummyContext)
+
+ def test_add_viewname_with_view_renderer(self):
+ config = DummyConfig()
+ inst = self._makeOne(config)
+ inst.add('view', 'anotherpackage:path', cache_max_age=1,
+ view_renderer='mypackage:templates/index.pt')
+ self.assertEqual(config.view_kw['renderer'],
+ 'mypackage:templates/index.pt')
+
+ def test_add_viewname_with_renderer(self):
+ config = DummyConfig()
+ inst = self._makeOne(config)
+ inst.add('view', 'anotherpackage:path', cache_max_age=1,
+ renderer='mypackage:templates/index.pt')
+ self.assertEqual(config.view_kw['renderer'],
+ 'mypackage:templates/index.pt')
+
+ def test_add_viewname_with_view_attr(self):
+ config = DummyConfig()
+ inst = self._makeOne(config)
+ inst.add('view', 'anotherpackage:path', cache_max_age=1,
+ view_attr='attr')
+ self.assertEqual(config.view_kw['attr'], 'attr')
+
+class DummyConfig:
+ def add_route(self, *args, **kw):
+ self.route_args = args
+ self.route_kw = kw
+
+ def add_view(self, *args, **kw):
+ self.view_args = args
+ self.view_kw = kw
class DummyStartResponse:
def __call__(self, status, headerlist, exc_info=None):