summaryrefslogtreecommitdiff
path: root/docs/tutorials
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2010-12-23 20:01:42 -0500
committerChris McDonough <chrism@plope.com>2010-12-23 20:01:42 -0500
commitb743bb4da42198f223ec756936dc0c581b08b534 (patch)
tree73c030ae3ffd241f5dc3dcebb72de661d6afd57a /docs/tutorials
parentd1138fdd4fe55358dcb583c5ddee3f45043d1fb5 (diff)
downloadpyramid-b743bb4da42198f223ec756936dc0c581b08b534.tar.gz
pyramid-b743bb4da42198f223ec756936dc0c581b08b534.tar.bz2
pyramid-b743bb4da42198f223ec756936dc0c581b08b534.zip
tutorial accuracy and wording improvements
Diffstat (limited to 'docs/tutorials')
-rw-r--r--docs/tutorials/wiki/authorization.rst174
-rw-r--r--docs/tutorials/wiki/basiclayout.rst12
-rw-r--r--docs/tutorials/wiki/definingmodels.rst44
-rw-r--r--docs/tutorials/wiki/definingviews.rst150
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/login.py4
5 files changed, 194 insertions, 190 deletions
diff --git a/docs/tutorials/wiki/authorization.rst b/docs/tutorials/wiki/authorization.rst
index 34cde288f..57c4a3ce5 100644
--- a/docs/tutorials/wiki/authorization.rst
+++ b/docs/tutorials/wiki/authorization.rst
@@ -23,15 +23,13 @@ For any :app:`Pyramid` application to perform authorization, we need to add a
registry` to add an :term:`authentication policy` and a :term:`authorization
policy`.
-Changing ``__init__.py``
-~~~~~~~~~~~~~~~~~~~~~~~~
+Adding Authentication and Authorization Policies
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We'll change our ``__init__.py`` file to enable an
+We'll change our package's ``__init__.py`` file to enable an
``AuthTktAuthenticationPolicy`` and an ``ACLAuthorizationPolicy`` to enable
-declarative security checking. We'll also add a new view stanza, which
-specifies a :term:`forbidden view`. This configures our login view to show
-up when :app:`Pyramid` detects that a view invocation can not be authorized.
-When you're done, your ``__init__.py`` will look like so:
+declarative security checking. When you're done, your ``__init__.py`` will
+look like so:
.. literalinclude:: src/authorization/tutorial/__init__.py
:linenos:
@@ -84,6 +82,22 @@ and logout views. Add a file named ``login.py`` to your application
:linenos:
:language: python
+Note that the ``login`` view callable in the ``login.py`` file has *two* view
+configuration decorators. In the first view configuration decorator, we
+configured the ``login`` view callable so it will be invoked when someone
+visits ``/login`` (when the context is a Wiki and the view name is
+``login``). The second decorator (with context of
+``pyramid.exceptions.Forbidden``) specifies a :term:`forbidden view`. This
+configures our login view to show up when :app:`Pyramid` detects that a view
+invocation can not be authorized. Because we've configured a forbidden view,
+the ``login`` view callable will be invoked whenever one of our users tries
+to execute a view callable that they are disallowed from invoking based on
+the :term:`authorization policy` in use. In our application, for example,
+this means that if a user has not logged in, and he tries to add or edit a
+Wiki page, he will be shown the login form. Before being allowed to continue
+on to the add or edit form, he will have to provide credentials that give him
+permission to add or edit via this login form.
+
Changing Existing Views
~~~~~~~~~~~~~~~~~~~~~~~
@@ -138,17 +152,15 @@ class="main_content">`` div:
<a href="${request.application_url}/logout">Logout</a>
</span>
-Giving Our Root Model Object an ACL
------------------------------------
+Giving Our Root Resource an ACL
+-------------------------------
-We need to give our root model object an :term:`ACL`. This ACL will
-be sufficient to provide enough information to the :app:`Pyramid`
-security machinery to challenge a user who doesn't have appropriate
-credentials when he attempts to invoke the ``add_page`` or
-``edit_page`` views.
+We need to give our root resource object an :term:`ACL`. This ACL will be
+sufficient to provide enough information to the :app:`Pyramid` security
+machinery to challenge a user who doesn't have appropriate credentials when
+he attempts to invoke the ``add_page`` or ``edit_page`` views.
-We need to perform some imports at module scope in our ``models.py``
-file:
+We need to perform some imports at module scope in our ``models.py`` file:
.. code-block:: python
:linenos:
@@ -156,8 +168,8 @@ file:
from pyramid.security import Allow
from pyramid.security import Everyone
-Our root model is a ``Wiki`` object. We'll add the following line at
-class scope to our ``Wiki`` class:
+Our root resource object is a ``Wiki`` instance. We'll add the following
+line at class scope to our ``Wiki`` class:
.. code-block:: python
:linenos:
@@ -165,12 +177,11 @@ class scope to our ``Wiki`` class:
__acl__ = [ (Allow, Everyone, 'view'),
(Allow, 'group:editors', 'edit') ]
-It's only happenstance that we're assigning this ACL at class scope.
-An ACL can be attached to an object *instance* too; this is how "row
-level security" can be achieved in :app:`Pyramid` applications. We
-actually only need *one* ACL for the entire system, however, because
-our security requirements are simple, so this feature is not
-demonstrated.
+It's only happenstance that we're assigning this ACL at class scope. An ACL
+can be attached to an object *instance* too; this is how "row level security"
+can be achieved in :app:`Pyramid` applications. We actually only need *one*
+ACL for the entire system, however, because our security requirements are
+simple, so this feature is not demonstrated.
Our resulting ``models.py`` file will now look like so:
@@ -181,76 +192,71 @@ Our resulting ``models.py`` file will now look like so:
Adding ``permission`` Declarations to our ``view_config`` Decorators
--------------------------------------------------------------------
-To protect each of our views with a particular permission, we need to
-pass a ``permission`` argument to each of our
-:class:`pyramid.view.view_config` decorators. To do so, within
-``views.py``:
+To protect each of our views with a particular permission, we need to pass a
+``permission`` argument to each of our :class:`pyramid.view.view_config`
+decorators. To do so, within ``views.py``:
-- We add ``permission='view'`` to the decorator attached to the
- ``view_wiki`` view function. This makes the assertion that only
- users who possess the effective ``view`` permission at the time of
- the request may invoke this view. We've granted
- :data:`pyramid.security.Everyone` the view permission at the root
- model via its ACL, so everyone will be able to invoke the
- ``view_wiki`` view.
+- We add ``permission='view'`` to the decorator attached to the ``view_wiki``
+ view function. This makes the assertion that only users who possess the
+ ``view`` permission against the context resource at the time of the request
+ may invoke this view. We've granted :data:`pyramid.security.Everyone` the
+ view permission at the root model via its ACL, so everyone will be able to
+ invoke the ``view_wiki`` view.
-- We add ``permission='view'`` to the decorator attached to the
- ``view_page`` view function. This makes the assertion that only
- users who possess the effective ``view`` permission at the time of
+- We add ``permission='view'`` to the decorator attached to the ``view_page``
+ view function. This makes the assertion that only users who possess the
+ effective ``view`` permission against the context resource at the time of
the request may invoke this view. We've granted
- :data:`pyramid.security.Everyone` the view permission at the root
- model via its ACL, so everyone will be able to invoke the
- ``view_page`` view.
-
-- We add ``permission='edit'`` to the decorator attached to the
- ``add_page`` view function. This makes the assertion that only
- users who possess the effective ``edit`` permission at the time of
- the request may invoke this view. We've granted the
- ``group:editors`` principal the ``edit`` permission at the root
- model via its ACL, so only the a user whom is a member of the group
- named ``group:editors`` will able to invoke the ``add_page`` view.
- We've likewise given the ``editor`` user membership to this group
- via thes ``security.py`` file by mapping him to the
- ``group:editors`` group in the ``GROUPS`` data structure (``GROUPS =
- {'editor':['group:editors']}``); the ``groupfinder`` function
- consults the ``GROUPS`` data structure. This means that the
- ``editor`` user can add pages.
-
-- We add ``permission='edit'`` to the decorator attached to the
- ``edit_page`` view function. This makes the assertion that only
- users who possess the effective ``edit`` permission at the time of
- the request may invoke this view. We've granted the
- ``group:editors`` principal the ``edit`` permission at the root
- model via its ACL, so only the a user whom is a member of the group
- named ``group:editors`` will able to invoke the ``edit_page`` view.
- We've likewise given the ``editor`` user membership to this group
- via thes ``security.py`` file by mapping him to the
- ``group:editors`` group in the ``GROUPS`` data structure (``GROUPS =
- {'editor':['group:editors']}``); the ``groupfinder`` function
- consults the ``GROUPS`` data structure. This means that the
- ``editor`` user can edit pages.
+ :data:`pyramid.security.Everyone` the view permission at the root model via
+ its ACL, so everyone will be able to invoke the ``view_page`` view.
+
+- We add ``permission='edit'`` to the decorator attached to the ``add_page``
+ view function. This makes the assertion that only users who possess the
+ effective ``edit`` permission against the context resource at the time of
+ the request may invoke this view. We've granted the ``group:editors``
+ principal the ``edit`` permission at the root model via its ACL, so only
+ the a user whom is a member of the group named ``group:editors`` will able
+ to invoke the ``add_page`` view. We've likewise given the ``editor`` user
+ membership to this group via thes ``security.py`` file by mapping him to
+ the ``group:editors`` group in the ``GROUPS`` data structure (``GROUPS =
+ {'editor':['group:editors']}``); the ``groupfinder`` function consults the
+ ``GROUPS`` data structure. This means that the ``editor`` user can add
+ pages.
+
+- We add ``permission='edit'`` to the decorator attached to the ``edit_page``
+ view function. This makes the assertion that only users who possess the
+ effective ``edit`` permission against the context resource at the time of
+ the request may invoke this view. We've granted the ``group:editors``
+ principal the ``edit`` permission at the root model via its ACL, so only
+ the a user whom is a member of the group named ``group:editors`` will able
+ to invoke the ``edit_page`` view. We've likewise given the ``editor`` user
+ membership to this group via thes ``security.py`` file by mapping him to
+ the ``group:editors`` group in the ``GROUPS`` data structure (``GROUPS =
+ {'editor':['group:editors']}``); the ``groupfinder`` function consults the
+ ``GROUPS`` data structure. This means that the ``editor`` user can edit
+ pages.
Viewing the Application in a Browser
------------------------------------
-We can finally examine our application in a browser. The views we'll
-try are as follows:
+We can finally examine our application in a browser. The views we'll try are
+as follows:
-- Visiting ``http://localhost:6543/`` in a browser invokes the
- ``view_wiki`` view. This always redirects to the ``view_page`` view
- of the FrontPage page object. It is executable by any user.
+- Visiting ``http://localhost:6543/`` in a browser invokes the ``view_wiki``
+ view. This always redirects to the ``view_page`` view of the ``FrontPage``
+ page resource. It is executable by any user.
-- Visiting ``http://localhost:6543/FrontPage/`` in a browser invokes
- the ``view_page`` view of the front page page object. This is
- because it's the :term:`default view` (a view without a ``name``)
- for ``Page`` objects. It is executable by any user.
+- Visiting ``http://localhost:6543/FrontPage/`` in a browser invokes the
+ ``view_page`` view of the ``FrontPage`` Page resource. This is because
+ it's the :term:`default view` (a view without a ``name``) for ``Page``
+ resources. It is executable by any user.
-- Visiting ``http://localhost:6543/FrontPage/edit_page`` in a browser
- invokes the edit view for the front page object. It is executable
- by only the ``editor`` user. If a different user (or the anonymous
- user) invokes it, a login form will be displayed. Supplying the
- credentials with the username ``editor``, password ``editor`` will
- show the edit page form being displayed.
+- Visiting ``http://localhost:6543/FrontPage/edit_page`` in a browser invokes
+ the edit view for the ``FrontPage`` Page resource. It is executable by
+ only the ``editor`` user. If a different user (or the anonymous user)
+ invokes it, a login form will be displayed. Supplying the credentials with
+ the username ``editor``, password ``editor`` will show the edit page form
+ being displayed.
- Visiting ``http://localhost:6543/add_page/SomePageName`` in a
browser invokes the add view for a page. It is executable by only
diff --git a/docs/tutorials/wiki/basiclayout.rst b/docs/tutorials/wiki/basiclayout.rst
index 8e6e89e57..f6e1f800a 100644
--- a/docs/tutorials/wiki/basiclayout.rst
+++ b/docs/tutorials/wiki/basiclayout.rst
@@ -2,10 +2,9 @@
Basic Layout
============
-The starter files generated by the ``pyramid_zodb`` template are basic,
-but they provide a good orientation for the high-level patterns common
-to most :term:`traversal` -based :app:`Pyramid` (and :term:`ZODB`
-based) projects.
+The starter files generated by the ``pyramid_zodb`` template are basic, but
+they provide a good orientation for the high-level patterns common to most
+:term:`traversal` -based :app:`Pyramid` (and :term:`ZODB` based) projects.
The source code for this tutorial stage can be browsed via
`http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki/src/basiclayout/
@@ -78,11 +77,10 @@ Resources and Models with ``models.py``
hierarchically in a :term:`resource tree`. This tree is consulted by
:term:`traversal` to map URLs to code. In this application, the resource
tree represents the site structure, but it *also* represents the
-:term:`domain model` of the application, because eeach resource is a node
+:term:`domain model` of the application, because each resource is a node
stored persistently in a :term:`ZODB` database. The ``models.py`` file is
where the ``pyramid_zodb`` Paster template put the classes that implement our
-resource objects, each of which happens also to be a domain model
-object.
+resource objects, each of which happens also to be a domain model object.
Here is the source for ``models.py``:
diff --git a/docs/tutorials/wiki/definingmodels.rst b/docs/tutorials/wiki/definingmodels.rst
index 078a8e014..f201f6dc7 100644
--- a/docs/tutorials/wiki/definingmodels.rst
+++ b/docs/tutorials/wiki/definingmodels.rst
@@ -38,12 +38,11 @@ we're not going to use it.
.. note::
- There is nothing automagically special about the filename
- ``models.py``. A project may have many models throughout its
- codebase in arbitrarily-named files. Files implementing models
- often have ``model`` in their filenames (or they may live in a
- Python subpackage of your application package named ``models``) ,
- but this is only by convention.
+ There is nothing automagically special about the filename ``models.py``. A
+ project may have many models throughout its codebase in arbitrarily-named
+ files. Files implementing models often have ``model`` in their filenames,
+ or they may live in a Python subpackage of your application package named
+ ``models``, but this is only by convention.
Then, we'll add a ``Wiki`` class. Because this is a ZODB application, this
class should inherit from :class:`persistent.mapping.PersistentMapping`. We
@@ -131,6 +130,22 @@ When we're done changing ``tests.py``, it will look something like so:
:linenos:
:language: python
+Declaring Dependencies in Our ``setup.py`` File
+-----------------------------------------------
+
+Our application now depends on packages which are not dependencies of the
+original "tutorial" application as it was generated by the ``paster create``
+command. We'll add these dependencies to our ``tutorial`` package's
+``setup.py`` file by assigning these dependencies to both the
+``install_requires`` and the ``tests_require`` parameters to the ``setup``
+function. In particular, we require the ``docutils`` package.
+
+Our resulting ``setup.py`` should look like so:
+
+.. literalinclude:: src/models/setup.py
+ :linenos:
+ :language: python
+
Running the Tests
-----------------
@@ -160,20 +175,3 @@ The expected output is something like this:
OK
-Declaring Dependencies in Our ``setup.py`` File
------------------------------------------------
-
-Our application depends on packages which are not dependencies of the
-original "tutorial" application as it was generated by the ``paster
-create`` command. We'll add these dependencies to our ``tutorial``
-package's ``setup.py`` file by assigning these dependencies to both
-the ``install_requires`` and the ``tests_require`` parameters to the
-``setup`` function. In particular, we require the ``docutils``
-package.
-
-Our resulting ``setup.py`` should look like so:
-
-.. literalinclude:: src/models/setup.py
- :linenos:
- :language: python
-
diff --git a/docs/tutorials/wiki/definingviews.rst b/docs/tutorials/wiki/definingviews.rst
index 2c016b373..5b0e5dca1 100644
--- a/docs/tutorials/wiki/definingviews.rst
+++ b/docs/tutorials/wiki/definingviews.rst
@@ -18,19 +18,22 @@ callable is assumed to return a :term:`response` object.
However, a :app:`Pyramid` view can also be defined as callable which accepts
*two* arguments: a :term:`context` and a :term:`request`. In :term:`url
-dispatch` based applications, the context object is rarely used in the view
+dispatch` based applications, the context resource is rarely used in the view
body itself, so within code that uses URL-dispatch-only, it's common to
-define views as callables that accept only a request to avoid the visual
-"noise". This application, however, uses :term:`traversal` to map URLs to
-resources, so we're often interested in the context; it's not "noise" to use.
+define views as callables that accept only a ``request`` to avoid the visual
+"noise" of a ``context`` argument. This application, however, uses
+:term:`traversal` to map URLs to a context :term:`resource`, and since our
+:term:`resource tree` also represents our application's "domain model", we're
+often interested in the context, because it represents the persistent storage
+of our application. For this reason, having ``context`` in the callable
+argument list is not "noise" to us; instead it's actually rather important
+within the view code we'll define in this application.
The single-arg (``request`` -only) or two-arg (``context`` and ``request``)
calling conventions will work in any :app:`Pyramid` application for any view;
-they can be used interchangeably as necessary. In :term:`traversal` based
-applications, such as the application we're building in this tutorial, the
-context is used frequently within the body of a view method, so we'll be
-using the two-argument ``(context, request)`` syntax in this application for
-views that we add.
+they can be used interchangeably as necessary. We'll be using the
+two-argument ``(context, request)`` view callable argument list syntax in
+this application.
We're going to define several :term:`view callable` functions then wire them
into :app:`Pyramid` using some :term:`view configuration`.
@@ -43,7 +46,7 @@ Adding View Functions
=====================
We're going to add four :term:`view callable` functions to our ``views.py``
-module. One view (named ``view_wiki``) will display the wiki itself (it will
+module. One view named ``view_wiki`` will display the wiki itself (it will
answer on the root URL), another named ``view_page`` will display an
individual page, another named ``add_page`` will allow a page to be added,
and a final view named ``edit_page`` will allow a page to be edited.
@@ -52,36 +55,35 @@ The ``view_wiki`` view function
-------------------------------
The ``view_wiki`` function will be configured to respond as the default view
-callable for a ``Wiki`` resource object. We'll provide it with a
-``@view_config`` decorator which names the class ``tutorial.models.Wiki`` as
-its context. This means that when a Wiki object is the context, and no
-:term:`view name` exists in the request, this view will be used. The view
-configuration associated with ``view_wiki`` does not use a ``renderer``
-because the view callable always returns a :term:`response` object rather
-than a dictionary. No renderer is necessary when a view returns a response
-object.
-
-The view callable always redirects to the ``Page`` object named "FrontPage".
-It returns an instance of the :class:`pyramid.httpexceptions.HTTPFound` class
-(instances of which implement the WebOb :term:`response` interface), and the
-:func:`pyramid.url.resource_url` API. :func:`pyramid.url.resource_url`
-constructs a URL to the ``FrontPage`` page resource
-(e.g. ``http://localhost:6543/FrontPage``), and uses it as the "location" of
-the HTTPFound response, forming an HTTP redirect.
+callable for a Wiki resource. We'll provide it with a ``@view_config``
+decorator which names the class ``tutorial.models.Wiki`` as its context.
+This means that when a Wiki resource is the context, and no :term:`view name`
+exists in the request, this view will be used. The view configuration
+associated with ``view_wiki`` does not use a ``renderer`` because the view
+callable always returns a :term:`response` object rather than a dictionary.
+No renderer is necessary when a view returns a response object.
+
+The ``view_wiki`` view callable always redirects to the URL of a Page
+resource named "FrontPage". To do so, it returns an instance of the
+:class:`pyramid.httpexceptions.HTTPFound` class (instances of which implement
+the WebOb :term:`response` interface). The :func:`pyramid.url.resource_url`
+API. :func:`pyramid.url.resource_url` constructs a URL to the ``FrontPage``
+page resource (e.g. ``http://localhost:6543/FrontPage``), and uses it as the
+"location" of the HTTPFound response, forming an HTTP redirect.
The ``view_page`` view function
-------------------------------
The ``view_page`` function will be configured to respond as the default view
-of a ``Page`` resource. We'll provide it with a ``@view_config`` decorator
-which names the class ``tutorial.models.Wiki`` as its context. This means
-that when a Page object is the context, and no :term:`view name` exists in
-the request, this view will be used. We inform :app:`Pyramid` this view will
-use the ``templates/view.pt`` template file as a ``renderer``.
+of a Page resource. We'll provide it with a ``@view_config`` decorator which
+names the class ``tutorial.models.Wiki`` as its context. This means that
+when a Page resource is the context, and no :term:`view name` exists in the
+request, this view will be used. We inform :app:`Pyramid` this view will use
+the ``templates/view.pt`` template file as a ``renderer``.
The ``view_page`` function generates the :term:`ReStructuredText` body of a
page (stored as the ``data`` attribute of the context passed to the view; the
-context will be a Page object) as HTML. Then it substitutes an HTML anchor
+context will be a Page resource) as HTML. Then it substitutes an HTML anchor
for each *WikiWord* reference in the rendered HTML using a compiled regular
expression.
@@ -96,7 +98,7 @@ substitution value and returns it.
As a result, the ``content`` variable is now a fully formed bit of HTML
containing various view and add links for WikiWords based on the content of
-our current page object.
+our current page resource.
We then generate an edit URL (because it's easier to do here than in the
template), and we wrap up a number of arguments in a dictionary and return
@@ -118,13 +120,13 @@ callable. In the ``view_wiki`` view callable, we unconditionally return a
The ``add_page`` view function
------------------------------
-The ``add_page`` function will be configured to respond when the context is a
-Wiki and the :term:`view name` is ``add_page``. We'll provide it with a
-``@view_config`` decorator which names the string ``add_page`` as its
-:term:`view name` (via name=), the class ``tutorial.models.Wiki`` as its
+The ``add_page`` function will be configured to respond when the context
+resource is a Wiki and the :term:`view name` is ``add_page``. We'll provide
+it with a ``@view_config`` decorator which names the string ``add_page`` as
+its :term:`view name` (via name=), the class ``tutorial.models.Wiki`` as its
context, and the renderer named ``templates/edit.pt``. This means that when
-a Wiki object is the context, and a :term:`view name` exists as the result of
-traverasal named ``add_page``, this view will be used. We inform
+a Wiki resource is the context, and a :term:`view name` named ``add_page``
+exists as the result of traversal, this view will be used. We inform
:app:`Pyramid` this view will use the ``templates/edit.pt`` template file as
a ``renderer``. We share the same template between add and edit views, thus
``edit.pt`` instead of ``add.pt``.
@@ -132,9 +134,9 @@ a ``renderer``. We share the same template between add and edit views, thus
The ``add_page`` function will be invoked when a user clicks on a WikiWord
which isn't yet represented as a page in the system. The ``check`` function
within the ``view_page`` view generates URLs to this view. It also acts as a
-handler for the form that is generated when we want to add a page object.
-The ``context`` of the ``add_page`` view is always a Wiki object (*not* a
-Page object).
+handler for the form that is generated when we want to add a page resource.
+The ``context`` of the ``add_page`` view is always a Wiki resource (*not* a
+Page resource).
The request :term:`subpath` in :app:`Pyramid` is the sequence of names that
are found *after* the :term:`view name` in the URL segments given in the
@@ -151,14 +153,14 @@ expression ``'form.submitted' in request.params`` is ``False``), the view
renders a template. To do so, it generates a "save url" which the template
use as the form post URL during rendering. We're lazy here, so we're trying
to use the same template (``templates/edit.pt``) for the add view as well as
-the page edit view. To do so, we create a dummy Page object in order to
-satisfy the edit form's desire to have *some* page object exposed as
+the page edit view. To do so, we create a dummy Page resource object in
+order to satisfy the edit form's desire to have *some* page object exposed as
``page``, and we'll render the template to a response.
If the view rendering *is* a result of a form submission (if the expression
``'form.submitted' in request.params`` is ``True``), we scrape the page body
from the form data, create a Page object using the name in the subpath and
-the page body, and save it into "our context" (the wiki) using the
+the page body, and save it into "our context" (the Wiki) using the
``__setitem__`` method of the context. We then redirect back to the
``view_page`` view (the default view for a page) for the newly created page.
@@ -166,23 +168,23 @@ The ``edit_page`` view function
-------------------------------
The ``edit_page`` function will be configured to respond when the context is
-a Page and the :term:`view name` is ``edit_page``. We'll provide it with a
-``@view_config`` decorator which names the string ``edit_page`` as its
-:term:`view name` (via name=), the class ``tutorial.models.Page`` as its
+a Page resource and the :term:`view name` is ``edit_page``. We'll provide it
+with a ``@view_config`` decorator which names the string ``edit_page`` as its
+:term:`view name` (via ``name=``), the class ``tutorial.models.Page`` as its
context, and the renderer named ``templates/edit.pt``. This means that when
-a Page object is the context, and a :term:`view name` exists as the result of
-traverasal named ``edit_page``, this view will be used. We inform
+a Page resource is the context, and a :term:`view name` exists as the result
+of traverasal named ``edit_page``, this view will be used. We inform
:app:`Pyramid` this view will use the ``templates/edit.pt`` template file as
a ``renderer``.
The ``edit_page`` function will be invoked when a user clicks the "Edit this
Page" button on the view form. It renders an edit form but it also acts as
-the handler for the form it renders. The ``context`` of the ``edit_page``
-view will *always* be a Page object (never a Wiki object).
+the form post view callable for the form it renders. The ``context`` of the
+``edit_page`` view will *always* be a Page resource (never a Wiki resource).
If the view execution is *not* a result of a form submission (if the
expression ``'form.submitted' in request.params`` is ``False``), the view
-simply renders the edit form, passing the request, the page object, and a
+simply renders the edit form, passing the request, the page resource, and a
save_url which will be used as the action of the generated form.
If the view execution *is* a result of a form submission (if the expression
@@ -208,8 +210,8 @@ Most view callables we've added expected to be rendered via a
:term:`template`. The default templating systems in :app:`Pyramid` are
:term:`Chameleon` and :term:`Mako`. Chameleon is a variant of :term:`ZPT`,
which is an XML-based templating language. Mako is a non-XML-based
-templating language. Because we have to pick one, we'll use Chameleon for
-this tutorial.
+templating language. Because we had to pick one, we chose Chameleon for this
+tutorial.
The templates we create will live in the ``templates`` directory of our
tutorial package. Chameleon templates must have a ``.pt`` extension to be
@@ -218,8 +220,8 @@ recognized as such.
The ``view.pt`` Template
------------------------
-The ``view.pt`` template is used for viewing a single wiki page. It is used
-by the ``view_page`` view function. It should have a div that is "structure
+The ``view.pt`` template is used for viewing a single Page. It is used by
+the ``view_page`` view function. It should have a div that is "structure
replaced" with the ``content`` value provided by the view. It should also
have a link on the rendered page that points at the "edit" URL (the URL which
invokes the ``edit_page`` view for the page being viewed).
@@ -244,12 +246,12 @@ the below:
The ``edit.pt`` Template
------------------------
-The ``edit.pt`` template is used for adding and editing a wiki page. It is
-used by the ``add_page`` and ``edit_page`` view functions. It should display
-a page containing a form that POSTs back to the "save_url" argument supplied
-by the view. The form should have a "body" textarea field (the page data),
-and a submit button that has the name "form.submitted". The textarea in the
-form should be filled with any existing page data when it is rendered.
+The ``edit.pt`` template is used for adding and editing a Page. It is used
+by the ``add_page`` and ``edit_page`` view functions. It should display a
+page containing a form that POSTs back to the "save_url" argument supplied by
+the view. The form should have a "body" textarea field (the page data), and
+a submit button that has the name "form.submitted". The textarea in the form
+should be filled with any existing page data when it is rendered.
Once we're done with the ``edit.pt`` template, it will look a lot like the
below:
@@ -258,10 +260,10 @@ below:
:linenos:
:language: xml
-Static Resources
-----------------
+Static Assets
+-------------
-Our templates name a single static resource named ``style.css``. We need to
+Our templates name a single static asset named ``style.css``. We need to
create this and place it in a file named ``style.css`` within our package's
``static`` directory. This file is a little too long to replicate within the
body of this guide, however it is available `online
@@ -270,7 +272,7 @@ body of this guide, however it is available `online
This CSS file will be accessed via
e.g. ``http://localhost:6543/static/style.css`` by virtue of the call to
``add_static_view`` directive we've made in the ``__init__`` file. Any
-number and type of static resources can be placed in this directory (or
+number and type of static assets can be placed in this directory (or
subdirectories) and are just referred to by URL within templates.
Testing the Views
@@ -324,20 +326,20 @@ Viewing the Application in a Browser
Once we've completed our edits, we can finally examine our application in a
browser. The views we'll try are as follows:
-- Visiting ``http://localhost:6543/`` in a browser invokes the
- ``view_wiki`` view. This always redirects to the ``view_page`` view
- of the FrontPage page object.
+- Visiting ``http://localhost:6543/`` in a browser invokes the ``view_wiki``
+ view. This always redirects to the ``view_page`` view of the ``FrontPage``
+ Page resource.
- Visiting ``http://localhost:6543/FrontPage/`` in a browser invokes
- the ``view_page`` view of the front page page object. This is
+ the ``view_page`` view of the front page resource. This is
because it's the *default view* (a view without a ``name``) for Page
- objects.
+ resources.
- Visiting ``http://localhost:6543/FrontPage/edit_page`` in a browser
- invokes the edit view for the front page object.
+ invokes the edit view for the ``FrontPage`` Page resource.
- Visiting ``http://localhost:6543/add_page/SomePageName`` in a
- browser invokes the add view for a page.
+ browser invokes the add view for a Page.
- To generate an error, visit ``http://localhost:6543/add_page`` which
will generate an ``IndexError`` for the expression
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/login.py b/docs/tutorials/wiki/src/authorization/tutorial/login.py
index 59e71a1d9..463db71a6 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/login.py
+++ b/docs/tutorials/wiki/src/authorization/tutorial/login.py
@@ -7,10 +7,10 @@ from pyramid.url import resource_url
from tutorial.security import USERS
-@view_config(context='pyramid.exceptions.Forbidden',
- renderer='templates/login.pt')
@view_config(context='tutorial.models.Wiki', name='login',
renderer='templates/login.pt')
+@view_config(context='pyramid.exceptions.Forbidden',
+ renderer='templates/login.pt')
def login(request):
login_url = resource_url(request.context, request, 'login')
referrer = request.url