summaryrefslogtreecommitdiff
path: root/docs/tutorials/wiki
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tutorials/wiki')
-rw-r--r--docs/tutorials/wiki/NOTE-relocatable.txt13
-rw-r--r--docs/tutorials/wiki/authorization.rst94
-rw-r--r--docs/tutorials/wiki/basiclayout.rst42
-rw-r--r--docs/tutorials/wiki/definingmodels.rst16
-rw-r--r--docs/tutorials/wiki/definingviews.rst6
-rw-r--r--docs/tutorials/wiki/installation.rst63
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/__init__.py8
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/login.py44
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/security.py1
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt8
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt8
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt8
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt8
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/tests.py24
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/views.py56
-rw-r--r--docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py6
-rw-r--r--docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt8
-rw-r--r--docs/tutorials/wiki/src/basiclayout/tutorial/tests.py2
-rw-r--r--docs/tutorials/wiki/src/basiclayout/tutorial/views.py5
-rw-r--r--docs/tutorials/wiki/src/models/tutorial/__init__.py6
-rw-r--r--docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt8
-rw-r--r--docs/tutorials/wiki/src/models/tutorial/tests.py10
-rw-r--r--docs/tutorials/wiki/src/models/tutorial/views.py2
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/__init__.py8
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/login.py44
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/security.py1
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt8
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/templates/login.pt8
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt8
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/templates/view.pt8
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/tests.py16
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/views.py56
-rw-r--r--docs/tutorials/wiki/src/views/tutorial/__init__.py2
-rw-r--r--docs/tutorials/wiki/src/views/tutorial/templates/edit.pt8
-rw-r--r--docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt8
-rw-r--r--docs/tutorials/wiki/src/views/tutorial/templates/view.pt8
-rw-r--r--docs/tutorials/wiki/src/views/tutorial/views.py17
-rw-r--r--docs/tutorials/wiki/tests.rst25
38 files changed, 347 insertions, 324 deletions
diff --git a/docs/tutorials/wiki/NOTE-relocatable.txt b/docs/tutorials/wiki/NOTE-relocatable.txt
new file mode 100644
index 000000000..cec2639f3
--- /dev/null
+++ b/docs/tutorials/wiki/NOTE-relocatable.txt
@@ -0,0 +1,13 @@
+We specifically use relative package references where possible so this demo
+works even if the user names their package (in the 'bin/paster create -t
+zodb ...' step) something other than 'tutorial'.
+
+Specifically:
+
+- use relative imports
+- use plain relative URLs for resources (like stylesheets and images) in
+ page templates.
+
+Direct uses of the package name, like in __init__.py 'config.scan()'
+statements, are already adjusted by the paster/pcreate, so we don't have to
+worry about them.
diff --git a/docs/tutorials/wiki/authorization.rst b/docs/tutorials/wiki/authorization.rst
index 1835ce7ea..fa18d4a41 100644
--- a/docs/tutorials/wiki/authorization.rst
+++ b/docs/tutorials/wiki/authorization.rst
@@ -4,7 +4,7 @@ Adding Authorization
Our application currently allows anyone with access to the server to view,
edit, and add pages to our wiki. For purposes of demonstration we'll change
-our application to allow people whom are members of a *group* named
+our application to allow people who are members of a *group* named
``group:editors`` to add and edit wiki pages but we'll continue allowing
anyone with access to the server to view pages. :app:`Pyramid` provides
facilities for :term:`authorization` and :term:`authentication`. We'll make
@@ -27,8 +27,8 @@ The source code for this tutorial stage can be browsed via
`http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki/src/authorization/
<http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki/src/authorization/>`_.
-Adding Authentication and Authorization Policies
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Add Authentication and Authorization Policies
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We'll change our package's ``__init__.py`` file to enable an
``AuthTktAuthenticationPolicy`` and an ``ACLAuthorizationPolicy`` to enable
@@ -42,7 +42,7 @@ declarative security checking. We need to import the new policies:
Then, we'll add those policies to the configuration:
.. literalinclude:: src/authorization/tutorial/__init__.py
- :lines: 20-25
+ :lines: 17-22
:linenos:
:language: python
@@ -60,8 +60,8 @@ look like so:
:linenos:
:language: python
-Adding ``security.py``
-~~~~~~~~~~~~~~~~~~~~~~
+Add ``security.py``
+~~~~~~~~~~~~~~~~~~~
Add a ``security.py`` module within your package (in the same
directory as ``__init__.py``, ``views.py``, etc.) with the following
@@ -73,17 +73,16 @@ content:
The ``groupfinder`` function defined here is an :term:`authentication policy`
"callback"; it is a callable that accepts a userid and a request. If the
-userid exists in the system, the callback will
-return a sequence of group identifiers (or an empty sequence if the user
-isn't a member of any groups). If the userid *does not* exist in the system,
-the callback will return ``None``. In a production system, user and group data will
-most often come from a database, but here we use "dummy" data to represent
-user and groups sources. Note that the ``editor`` user is a member of the
-``group:editors`` group in our dummy group data (the ``GROUPS`` data
-structure).
-
-Giving Our Root Resource an ACL
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+userid exists in the system, the callback will return a sequence of group
+identifiers (or an empty sequence if the user isn't a member of any groups).
+If the userid *does not* exist in the system, the callback will return
+``None``. In a production system, user and group data will most often come
+from a database, but here we use "dummy" data to represent user and groups
+sources. Note that the ``editor`` user is a member of the ``group:editors``
+group in our dummy group data (the ``GROUPS`` data structure).
+
+Give Our Root Resource an ACL
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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
@@ -119,8 +118,8 @@ Our resulting ``models.py`` file will now look like so:
:linenos:
:language: python
-Adding Login and Logout Views
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Add Login and Logout Views
+~~~~~~~~~~~~~~~~~~~~~~~~~~
We'll add a ``login`` view which renders a login form and processes
the post from the login form, checking credentials.
@@ -129,18 +128,24 @@ We'll also add a ``logout`` view to our application and provide a link
to it. This view will clear the credentials of the logged in user and
redirect back to the front page.
-We'll add a different file (for presentation convenience) to add login
-and logout views. Add a file named ``login.py`` to your application
-(in the same directory as ``views.py``) with the following content:
+We'll add these views to the existing ``views.py`` file we have in our
+project. Here's what the ``login`` view callable will look like:
+
+.. literalinclude:: src/authorization/tutorial/views.py
+ :pyobject: login
+ :linenos:
+ :language: python
+
+Here's what the ``logout`` view callable will look like:
-.. literalinclude:: src/authorization/tutorial/login.py
+.. literalinclude:: src/authorization/tutorial/views.py
+ :pyobject: logout
:linenos:
:language: python
-Note that the ``login`` view callable in the ``login.py`` file has *two* view
-configuration decorators. The order of these decorators is unimportant.
-Each just adds a different :term:`view configuration` for the ``login`` view
-callable.
+Note that the ``login`` view callable has *two* view configuration
+decorators. The order of these decorators is unimportant. Each just adds a
+different :term:`view configuration` for the ``login`` view callable.
The first view configuration decorator configures the ``login`` view callable
so it will be invoked when someone visits ``/login`` (when the context is a
@@ -157,14 +162,18 @@ 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
-~~~~~~~~~~~~~~~~~~~~~~~
+Note that we're relying on some additional imports within the bodies of these
+views (e.g. ``remember`` and ``forget``). We'll see a rendering of the
+entire views.py file a little later here to show you where those come from.
-Then we need to change each of our ``view_page``, ``edit_page`` and
-``add_page`` views in ``views.py`` to pass a "logged in" parameter
-into its template. We'll add something like this to each view body:
+Change Existing Views
+~~~~~~~~~~~~~~~~~~~~~
+
+In order to indicate whether the current user is logged in, we need to change
+each of our ``view_page``, ``edit_page`` and ``add_page`` views in
+``views.py`` to pass a "logged in" parameter into its template. We'll add
+something like this to each view body:
-.. ignore-next-block
.. code-block:: python
:linenos:
@@ -175,7 +184,6 @@ We'll then change the return value of each view that has an associated
``renderer`` to pass the resulting ``logged_in`` value to the
template. For example:
-.. ignore-next-block
.. code-block:: python
:linenos:
@@ -184,8 +192,8 @@ template. For example:
logged_in = logged_in,
edit_url = edit_url)
-Adding ``permission`` Declarations to our ``view_config`` Decorators
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Add ``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`
@@ -216,11 +224,11 @@ decorators. To do so, within ``views.py``:
function consults the ``GROUPS`` data structure. This means
that the ``editor`` user can add and edit pages.
-Adding the ``login.pt`` Template
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Add the ``login.pt`` Template
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Add a ``login.pt`` template to your templates directory. It's
-referred to within the login view we just added to ``login.py``.
+referred to within the login view we just added to ``views.py``.
.. literalinclude:: src/authorization/tutorial/templates/login.pt
:language: xml
@@ -241,8 +249,8 @@ class="app-welcome align-right">`` div:
<a href="${request.application_url}/logout">Logout</a>
</span>
-Seeing Our Changes To ``views.py`` and our Templates
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+See Our Changes To ``views.py`` and our Templates
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Our ``views.py`` module will look something like this when we're done:
@@ -262,8 +270,8 @@ Our ``view.pt`` template will look something like this when we're done:
:linenos:
:language: xml
-Viewing the Application in a Browser
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+View the Application in a Browser
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We can finally examine our application in a browser. The views we'll try are
as follows:
diff --git a/docs/tutorials/wiki/basiclayout.rst b/docs/tutorials/wiki/basiclayout.rst
index 47cac597b..56f817a85 100644
--- a/docs/tutorials/wiki/basiclayout.rst
+++ b/docs/tutorials/wiki/basiclayout.rst
@@ -2,7 +2,7 @@
Basic Layout
============
-The starter files generated by the ``pyramid_zodb`` scaffold are basic, but
+The starter files generated by the ``zodb`` scaffold 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.
@@ -10,8 +10,8 @@ The source code for this tutorial stage can be browsed via
`http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki/src/basiclayout/
<http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki/src/basiclayout/>`_.
-App Startup with ``__init__.py``
---------------------------------
+Appplication Configuration with ``__init__.py``
+------------------------------------------------
A directory on disk can be turned into a Python :term:`package` by containing
an ``__init__.py`` file. Even if empty, this marks a directory as a Python
@@ -35,7 +35,7 @@ point happens to be the ``main`` function within the file named
#. *Line 12*. We construct a :term:`Configurator` with a :term:`root
factory` and the settings keywords parsed by :term:`PasteDeploy`. The root
- factory is named ``get_root``.
+ factory is named ``root_factory``.
#. *Line 13*. Register a 'static view' which answers requests which start
with with URL path ``/static`` using the
@@ -45,16 +45,19 @@ point happens to be the ``main`` function within the file named
``http://localhost:6543/static/`` and below. The first argument is the
"name" ``static``, which indicates that the URL path prefix of the view
will be ``/static``. the The second argument of this tag is the "path",
- which is an :term:`asset specification`, so it finds the resources it
- should serve within the ``static`` directory inside the ``tutorial``
- package.
+ which is a relative :term:`asset specification`, so it finds the resources
+ it should serve within the ``static`` directory inside the ``tutorial``
+ package. The scaffold could have alternately used an *absolute* asset
+ specification as the path (``tutorial:static``) but it does not.
#. *Line 14*. 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. The argument to
- :meth:`~pyramid.config.Configurator.scan` is the package name to scan,
- which is ``tutorial``.
+ 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
+ :meth:`~pyramid.config.Configurator.scan`, which implies that the scan
+ should take place in the current package (in this case, ``tutorial``).
+ The scaffold could have equivalently said ``config.scan('tutorial')`` but
+ it chose to omit the package name argument.
#. *Line 15*. Use the
:meth:`pyramid.config.Configurator.make_wsgi_app` method
@@ -69,7 +72,7 @@ hierarchically in a :term:`resource tree`. This tree is consulted by
tree represents the site structure, but it *also* represents the
: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`` scaffold put the classes that implement our
+where the ``zodb`` scaffold put the classes that implement our
resource objects, each of which happens also to be a domain model object.
Here is the source for ``models.py``:
@@ -119,7 +122,7 @@ Let's try to understand the components in this module:
decoration` to perform a :term:`view configuration` registration. This
view configuration registration will be activated when the application is
started. It will be activated by virtue of it being found as the result
- of a :term:`scan` (when Line 17 of ``__init__.py`` is run).
+ of a :term:`scan` (when Line 14 of ``__init__.py`` is run).
The ``@view_config`` decorator accepts a number of keyword arguments. We
use two keyword arguments here: ``context`` and ``renderer``.
@@ -131,12 +134,15 @@ Let's try to understand the components in this module:
model, this view callable will be invoked.
The ``renderer`` argument names an :term:`asset specification` of
- ``tutorial:templates/mytemplate.pt``. This asset specification points at
- a :term:`Chameleon` template which lives in the ``mytemplate.pt`` file
+ ``templates/mytemplate.pt``. This asset specification points at a
+ :term:`Chameleon` template which lives in the ``mytemplate.pt`` file
within the ``templates`` directory of the ``tutorial`` package. And
indeed if you look in the ``templates`` directory of this package, you'll
see a ``mytemplate.pt`` template file, which renders the default home page
- of the generated project.
+ of the generated project. This asset specification is *relative* (to the
+ view.py's current package). We could have alternately an used the
+ absolute asset specification ``tutorial:templates/mytemplate.pt``, but
+ chose to use the relative version.
Since this call to ``@view_config`` doesn't pass a ``name`` argument, the
``my_view`` function which it decorates represents the "default" view
@@ -144,7 +150,7 @@ Let's try to understand the components in this module:
#. *Lines 5-6*. We define a :term:`view callable` named ``my_view``, which
we decorated in the step above. This view callable is a *function* we
- write generated by the ``pyramid_zodb`` scaffold that is given a
+ write generated by the ``zodb`` scaffold that is given a
``request`` and which returns a dictionary. The ``mytemplate.pt``
:term:`renderer` named by the asset specification in the step above will
convert this dictionary to a :term:`response` on our behalf.
diff --git a/docs/tutorials/wiki/definingmodels.rst b/docs/tutorials/wiki/definingmodels.rst
index ee9c13ab2..cdf3b6092 100644
--- a/docs/tutorials/wiki/definingmodels.rst
+++ b/docs/tutorials/wiki/definingmodels.rst
@@ -18,8 +18,8 @@ The source code for this tutorial stage can be browsed via
`http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki/src/models/
<http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki/src/models/>`_.
-Deleting the Database
----------------------
+Delete the Database
+-------------------
In the next step, we're going to remove the ``MyModel`` Python model
class from our ``models.py`` file. Since this class is referred to within
@@ -30,8 +30,8 @@ directory before proceeding any further. It's always fine to do this as long
as you don't care about the content of the database; the database itself will
be recreated as necessary.
-Making Edits to ``models.py``
------------------------------
+Edit ``models.py``
+------------------
.. note::
@@ -73,8 +73,8 @@ front page) into the Wiki within the ``appmaker``. This will provide
:term:`traversal` a :term:`resource tree` to work against when it attempts to
resolve URLs to resources.
-Looking at the Result of Our Edits to ``models.py``
----------------------------------------------------
+Look at the Result of Our Edits to ``models.py``
+------------------------------------------------
The result of all of our edits to ``models.py`` will end up looking
something like this:
@@ -83,8 +83,8 @@ something like this:
:linenos:
:language: python
-Viewing the Application in a Browser
-------------------------------------
+View the Application in a Browser
+---------------------------------
We can't. At this point, our system is in a "non-runnable" state; we'll need
to change view-related files in the next chapter to be able to start the
diff --git a/docs/tutorials/wiki/definingviews.rst b/docs/tutorials/wiki/definingviews.rst
index c21367559..371cae8eb 100644
--- a/docs/tutorials/wiki/definingviews.rst
+++ b/docs/tutorials/wiki/definingviews.rst
@@ -293,12 +293,10 @@ replicate within the body of this guide, however it is available `online
<http://github.com/Pylons/pyramid/blob/master/docs/tutorials/wiki/src/views/tutorial/static/pylons.css>`_.
This CSS file will be accessed via
-e.g. ``http://localhost:6543/static/pylons.css`` by virtue of the call to
+e.g. ``/static/pylons.css`` by virtue of the call to
``add_static_view`` directive we've made in the ``__init__.py`` file. Any
number and type of static assets can be placed in this directory (or
-subdirectories) and are just referred to by URL or by using the convenience
-method ``static_url`` e.g. ``request.static_url('{{package}}:static/foo.css')``
-within templates.
+subdirectories) and are just referred to by URL.
Viewing the Application in a Browser
====================================
diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst
index c55c310ef..330b17c86 100644
--- a/docs/tutorials/wiki/installation.rst
+++ b/docs/tutorials/wiki/installation.rst
@@ -127,8 +127,8 @@ Preparation, Windows
.. _making_a_project:
-Making a Project
-================
+Make a Project
+==============
Your next step is to create a project. :app:`Pyramid` supplies a variety of
scaffolds to generate sample projects. For this tutorial, we will use the
@@ -149,14 +149,18 @@ On Windows:
c:\pyramidtut> Scripts\pcreate -s zodb tutorial
+.. note:: You don't have to call it `tutorial` -- the code uses
+ relative paths for imports and finding templates and static
+ resources.
+
.. note:: If you are using Windows, the ``zodb`` scaffold
doesn't currently deal gracefully with installation into a location
that contains spaces in the path. If you experience startup
problems, try putting both the virtualenv and the project into
directories that do not contain spaces in their paths.
-Installing the Project in "Development Mode"
-============================================
+Install the Project in "Development Mode"
+=========================================
In order to do development on the project easily, you must "register"
the project as a development egg in your workspace using the
@@ -180,8 +184,8 @@ On Windows:
.. _running_tests:
-Running the Tests
-=================
+Run the Tests
+=============
After you've installed the project in development mode, you may run
the tests for the project.
@@ -198,48 +202,53 @@ On Windows:
c:\pyramidtut\tutorial> ..\Scripts\python setup.py test -q
-Starting the Application
-========================
+Expose Test Coverage Information
+================================
-Start the application.
+You can run the ``nosetests`` command to see test coverage
+information. This runs the tests in the same way that ``setup.py
+test`` does but provides additional "coverage" information, exposing
+which lines of your project are "covered" (or not covered) by the
+tests.
On UNIX:
.. code-block:: text
- $ ../bin/pserve development.ini --reload
+ $ ../bin/nosetests --cover-package=tutorial --cover-erase --with-coverage
On Windows:
.. code-block:: text
- c:\pyramidtut\tutorial> ..\Scripts\pserve development.ini --reload
+ c:\pyramidtut\tutorial> ..\Scripts\nosetests --cover-package=tutorial ^
+ --cover-erase --with-coverage
-Exposing Test Coverage Information
-==================================
+Looks like the code in the ``zodb`` scaffold for ZODB projects is
+missing some test coverage, particularly in the file named
+``models.py``.
-You can run the ``nosetests`` command to see test coverage
-information. This runs the tests in the same way that ``setup.py
-test`` does but provides additional "coverage" information, exposing
-which lines of your project are "covered" (or not covered) by the
-tests.
+Start the Application
+=====================
+
+Start the application.
On UNIX:
.. code-block:: text
- $ ../bin/nosetests --cover-package=tutorial --cover-erase --with-coverage
+ $ ../bin/pserve development.ini --reload
On Windows:
.. code-block:: text
- c:\pyramidtut\tutorial> ..\Scripts\nosetests --cover-package=tutorial ^
- --cover-erase --with-coverage
+ c:\pyramidtut\tutorial> ..\Scripts\pserve development.ini --reload
-Looks like the code in the ``pyramid_zodb`` scaffold for ZODB projects is
-missing some test coverage, particularly in the file named
-``models.py``.
+.. note::
+
+ Your OS firewall, if any, may pop up a dialog asking for authorization
+ to allow python to accept incoming network connections.
Visit the Application in a Browser
==================================
@@ -252,10 +261,10 @@ page. You can read more about the purpose of the icon at
:ref:`debug_toolbar`. It allows you to get information about your
application while you develop.
-Decisions the ``pyramid_zodb`` Scaffold Has Made For You
-========================================================
+Decisions the ``zodb`` Scaffold Has Made For You
+================================================
-Creating a project using the ``pyramid_zodb`` scaffold makes the following
+Creating a project using the ``zodb`` scaffold makes the following
assumptions:
- you are willing to use :term:`ZODB` as persistent storage
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki/src/authorization/tutorial/__init__.py
index 2d6eb5ecb..20ee685ee 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/authorization/tutorial/__init__.py
@@ -4,8 +4,8 @@ from pyramid_zodbconn import get_connection
from pyramid.authentication import AuthTktAuthenticationPolicy
from pyramid.authorization import ACLAuthorizationPolicy
-from tutorial.models import appmaker
-from tutorial.security import groupfinder
+from .models import appmaker
+from .security import groupfinder
def root_factory(request):
conn = get_connection(request)
@@ -20,6 +20,6 @@ def main(global_config, **settings):
config = Configurator(root_factory=root_factory, settings=settings,
authentication_policy=authn_policy,
authorization_policy=authz_policy)
- config.add_static_view('static', 'tutorial:static', cache_max_age=3600)
- config.scan('tutorial')
+ config.add_static_view('static', 'static', cache_max_age=3600)
+ config.scan()
return config.make_wsgi_app()
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/login.py b/docs/tutorials/wiki/src/authorization/tutorial/login.py
deleted file mode 100644
index d608a7d0b..000000000
--- a/docs/tutorials/wiki/src/authorization/tutorial/login.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from pyramid.httpexceptions import HTTPFound
-
-from pyramid.security import remember
-from pyramid.security import forget
-from pyramid.view import view_config
-
-from tutorial.security import USERS
-
-@view_config(context='tutorial.models.Wiki', name='login',
- renderer='templates/login.pt')
-@view_config(context='pyramid.httpexceptions.HTTPForbidden',
- renderer='templates/login.pt')
-def login(request):
- login_url = request.resource_url(request.context, 'login')
- referrer = request.url
- if referrer == login_url:
- referrer = '/' # never use the login form itself as came_from
- came_from = request.params.get('came_from', referrer)
- message = ''
- login = ''
- password = ''
- if 'form.submitted' in request.params:
- login = request.params['login']
- password = request.params['password']
- if USERS.get(login) == password:
- headers = remember(request, login)
- return HTTPFound(location = came_from,
- headers = headers)
- message = 'Failed login'
-
- return dict(
- message = message,
- url = request.application_url + '/login',
- came_from = came_from,
- login = login,
- password = password,
- )
-
-@view_config(context='tutorial.models.Wiki', name='logout')
-def logout(request):
- headers = forget(request)
- return HTTPFound(location = request.resource_url(request.context),
- headers = headers)
-
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/security.py b/docs/tutorials/wiki/src/authorization/tutorial/security.py
index cfd13071e..d88c9c71f 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/security.py
+++ b/docs/tutorials/wiki/src/authorization/tutorial/security.py
@@ -5,4 +5,3 @@ GROUPS = {'editor':['group:editors']}
def groupfinder(userid, request):
if userid in USERS:
return GROUPS.get(userid, [])
-
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt
index f9da6c414..0d0738f7f 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt
+++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt
@@ -9,13 +9,13 @@
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
<link rel="shortcut icon"
- href="${request.static_url('tutorial:static/favicon.ico')}" />
+ href="/static/favicon.ico" />
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/pylons.css')}"
+ href="/static/pylons.css"
type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/ie6.css')}"
+ href="/static/ie6.css"
type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head>
@@ -25,7 +25,7 @@
<div class="top-small align-center">
<div>
<img width="220" height="50" alt="pyramid"
- src="${request.static_url('tutorial:static/pyramid-small.png')}" />
+ src="/static/pyramid-small.png" />
</div>
</div>
</div>
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt
index 64e592ea9..2c7235761 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt
+++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt
@@ -9,13 +9,13 @@
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
<link rel="shortcut icon"
- href="${request.static_url('tutorial:static/favicon.ico')}" />
+ href="/static/favicon.ico" />
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/pylons.css')}"
+ href="/static/pylons.css"
type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/ie6.css')}"
+ href="/static/ie6.css"
type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head>
@@ -25,7 +25,7 @@
<div class="top-small align-center">
<div>
<img width="220" height="50" alt="pyramid"
- src="${request.static_url('tutorial:static/pyramid-small.png')}" />
+ src="/static/pyramid-small.png" />
</div>
</div>
</div>
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt
index 14b88d16a..3597c679b 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt
@@ -5,19 +5,19 @@
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
- <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" />
+ <link rel="shortcut icon" href="/static/favicon.ico" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" />
- <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" />
+ <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
- <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" />
+ <link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head>
<body>
<div id="wrap">
<div id="top">
<div class="top align-center">
- <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div>
+ <div><img src="/static/pyramid.png" width="750" height="169" alt="pyramid"/></div>
</div>
</div>
<div id="middle">
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt
index d207a0c23..9dd6540cf 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt
+++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt
@@ -9,13 +9,13 @@
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
<link rel="shortcut icon"
- href="${request.static_url('tutorial:static/favicon.ico')}" />
+ href="/static/favicon.ico" />
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/pylons.css')}"
+ href="/static/pylons.css"
type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/ie6.css')}"
+ href="/static/ie6.css"
type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head>
@@ -25,7 +25,7 @@
<div class="top-small align-center">
<div>
<img width="220" height="50" alt="pyramid"
- src="${request.static_url('tutorial:static/pyramid-small.png')}" />
+ src="/static/pyramid-small.png" />
</div>
</div>
</div>
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/tests.py b/docs/tutorials/wiki/src/authorization/tutorial/tests.py
index a4a4e2754..77e7cce29 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/tests.py
+++ b/docs/tutorials/wiki/src/authorization/tutorial/tests.py
@@ -5,7 +5,7 @@ from pyramid import testing
class PageModelTests(unittest.TestCase):
def _getTargetClass(self):
- from tutorial.models import Page
+ from .models import Page
return Page
def _makeOne(self, data=u'some data'):
@@ -14,11 +14,11 @@ class PageModelTests(unittest.TestCase):
def test_constructor(self):
instance = self._makeOne()
self.assertEqual(instance.data, u'some data')
-
+
class WikiModelTests(unittest.TestCase):
def _getTargetClass(self):
- from tutorial.models import Wiki
+ from .models import Wiki
return Wiki
def _makeOne(self):
@@ -31,7 +31,7 @@ class WikiModelTests(unittest.TestCase):
class AppmakerTests(unittest.TestCase):
def _callFUT(self, zodb_root):
- from tutorial.models import appmaker
+ from .models import appmaker
return appmaker(zodb_root)
def test_it(self):
@@ -42,7 +42,7 @@ class AppmakerTests(unittest.TestCase):
class ViewWikiTests(unittest.TestCase):
def test_it(self):
- from tutorial.views import view_wiki
+ from .views import view_wiki
context = testing.DummyResource()
request = testing.DummyRequest()
response = view_wiki(context, request)
@@ -50,7 +50,7 @@ class ViewWikiTests(unittest.TestCase):
class ViewPageTests(unittest.TestCase):
def _callFUT(self, context, request):
- from tutorial.views import view_page
+ from .views import view_page
return view_page(context, request)
def test_it(self):
@@ -72,11 +72,11 @@ class ViewPageTests(unittest.TestCase):
'</p>\n</div>\n')
self.assertEqual(info['edit_url'],
'http://example.com/thepage/edit_page')
-
-
+
+
class AddPageTests(unittest.TestCase):
def _callFUT(self, context, request):
- from tutorial.views import add_page
+ from .views import add_page
return add_page(context, request)
def test_it_notsubmitted(self):
@@ -88,7 +88,7 @@ class AddPageTests(unittest.TestCase):
self.assertEqual(info['save_url'],
request.resource_url(
context, 'add_page', 'AnotherPage'))
-
+
def test_it_submitted(self):
context = testing.DummyResource()
request = testing.DummyRequest({'form.submitted':True,
@@ -102,7 +102,7 @@ class AddPageTests(unittest.TestCase):
class EditPageTests(unittest.TestCase):
def _callFUT(self, context, request):
- from tutorial.views import edit_page
+ from .views import edit_page
return edit_page(context, request)
def test_it_notsubmitted(self):
@@ -112,7 +112,7 @@ class EditPageTests(unittest.TestCase):
self.assertEqual(info['page'], context)
self.assertEqual(info['save_url'],
request.resource_url(context, 'edit_page'))
-
+
def test_it_submitted(self):
context = testing.DummyResource()
request = testing.DummyRequest({'form.submitted':True,
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/views.py b/docs/tutorials/wiki/src/authorization/tutorial/views.py
index a570410ca..2f0502c17 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/views.py
+++ b/docs/tutorials/wiki/src/authorization/tutorial/views.py
@@ -2,19 +2,26 @@ from docutils.core import publish_parts
import re
from pyramid.httpexceptions import HTTPFound
+
from pyramid.view import view_config
-from pyramid.security import authenticated_userid
-from tutorial.models import Page
+from pyramid.security import (
+ authenticated_userid,
+ remember,
+ forget,
+ )
+
+from .security import USERS
+from .models import Page
# regular expression used to find WikiWords
wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)")
-@view_config(context='tutorial.models.Wiki', permission='view')
+@view_config(context='.models.Wiki', permission='view')
def view_wiki(context, request):
return HTTPFound(location=request.resource_url(context, 'FrontPage'))
-@view_config(context='tutorial.models.Page',
+@view_config(context='.models.Page',
renderer='templates/view.pt', permission='view')
def view_page(context, request):
wiki = context.__parent__
@@ -38,7 +45,7 @@ def view_page(context, request):
return dict(page = context, content = content, edit_url = edit_url,
logged_in = logged_in)
-@view_config(name='add_page', context='tutorial.models.Wiki',
+@view_config(name='add_page', context='.models.Wiki',
renderer='templates/edit.pt',
permission='edit')
def add_page(context, request):
@@ -59,7 +66,7 @@ def add_page(context, request):
return dict(page = page, save_url = save_url, logged_in = logged_in)
-@view_config(name='edit_page', context='tutorial.models.Page',
+@view_config(name='edit_page', context='.models.Page',
renderer='templates/edit.pt',
permission='edit')
def edit_page(context, request):
@@ -72,4 +79,39 @@ def edit_page(context, request):
return dict(page = context,
save_url = request.resource_url(context, 'edit_page'),
logged_in = logged_in)
-
+
+@view_config(context='.models.Wiki', name='login',
+ renderer='templates/login.pt')
+@view_config(context='pyramid.httpexceptions.HTTPForbidden',
+ renderer='templates/login.pt')
+def login(request):
+ login_url = request.resource_url(request.context, 'login')
+ referrer = request.url
+ if referrer == login_url:
+ referrer = '/' # never use the login form itself as came_from
+ came_from = request.params.get('came_from', referrer)
+ message = ''
+ login = ''
+ password = ''
+ if 'form.submitted' in request.params:
+ login = request.params['login']
+ password = request.params['password']
+ if USERS.get(login) == password:
+ headers = remember(request, login)
+ return HTTPFound(location = came_from,
+ headers = headers)
+ message = 'Failed login'
+
+ return dict(
+ message = message,
+ url = request.application_url + '/login',
+ came_from = came_from,
+ login = login,
+ password = password,
+ )
+
+@view_config(context='.models.Wiki', name='logout')
+def logout(request):
+ headers = forget(request)
+ return HTTPFound(location = request.resource_url(request.context),
+ headers = headers)
diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py b/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py
index e49a61129..b63933fc5 100644
--- a/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py
@@ -1,6 +1,6 @@
from pyramid.config import Configurator
from pyramid_zodbconn import get_connection
-from tutorial.models import appmaker
+from .models import appmaker
def root_factory(request):
conn = get_connection(request)
@@ -10,6 +10,6 @@ def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
config = Configurator(root_factory=root_factory, settings=settings)
- config.add_static_view('static', 'tutorial:static', cache_max_age=3600)
- config.scan('tutorial')
+ 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/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt
index f9f351c97..557e071ed 100644
--- a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt
@@ -5,19 +5,19 @@
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
- <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" />
+ <link rel="shortcut icon" href="/static/favicon.ico" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" />
- <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" />
+ <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
- <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" />
+ <link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head>
<body>
<div id="wrap">
<div id="top">
<div class="top align-center">
- <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div>
+ <div><img src="/static/pyramid.png" width="750" height="169" alt="pyramid"/></div>
</div>
</div>
<div id="middle">
diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/tests.py b/docs/tutorials/wiki/src/basiclayout/tutorial/tests.py
index 1f3c3bb4d..8d2374be1 100644
--- a/docs/tutorials/wiki/src/basiclayout/tutorial/tests.py
+++ b/docs/tutorials/wiki/src/basiclayout/tutorial/tests.py
@@ -10,7 +10,7 @@ class ViewTests(unittest.TestCase):
testing.tearDown()
def test_my_view(self):
- from tutorial.views import my_view
+ from .views import my_view
request = testing.DummyRequest()
info = my_view(request)
self.assertEqual(info['project'], 'tutorial')
diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/views.py b/docs/tutorials/wiki/src/basiclayout/tutorial/views.py
index 157b9ac8f..4265b6bf7 100644
--- a/docs/tutorials/wiki/src/basiclayout/tutorial/views.py
+++ b/docs/tutorials/wiki/src/basiclayout/tutorial/views.py
@@ -1,7 +1,6 @@
from pyramid.view import view_config
-from tutorial.models import MyModel
+from .models import MyModel
-@view_config(context=MyModel,
- renderer='tutorial:templates/mytemplate.pt')
+@view_config(context=MyModel, renderer='templates/mytemplate.pt')
def my_view(request):
return {'project':'tutorial'}
diff --git a/docs/tutorials/wiki/src/models/tutorial/__init__.py b/docs/tutorials/wiki/src/models/tutorial/__init__.py
index 2d637b9de..c59f36e7b 100644
--- a/docs/tutorials/wiki/src/models/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/models/tutorial/__init__.py
@@ -1,6 +1,6 @@
from pyramid.config import Configurator
from pyramid_zodbconn import get_connection
-from tutorial.models import appmaker
+from .models import appmaker
def root_factory(request):
conn = get_connection(request)
@@ -10,7 +10,7 @@ def main(global_config, **settings):
""" This function returns a WSGI application.
"""
config = Configurator(root_factory=root_factory, settings=settings)
- config.add_static_view('static', 'tutorial:static', cache_max_age=3600)
- config.scan('tutorial')
+ 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/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt
index 14b88d16a..3597c679b 100644
--- a/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt
@@ -5,19 +5,19 @@
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
- <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" />
+ <link rel="shortcut icon" href="/static/favicon.ico" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" />
- <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" />
+ <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
- <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" />
+ <link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head>
<body>
<div id="wrap">
<div id="top">
<div class="top align-center">
- <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div>
+ <div><img src="/static/pyramid.png" width="750" height="169" alt="pyramid"/></div>
</div>
</div>
<div id="middle">
diff --git a/docs/tutorials/wiki/src/models/tutorial/tests.py b/docs/tutorials/wiki/src/models/tutorial/tests.py
index 51c97a95d..9fd13a18d 100644
--- a/docs/tutorials/wiki/src/models/tutorial/tests.py
+++ b/docs/tutorials/wiki/src/models/tutorial/tests.py
@@ -5,7 +5,7 @@ from pyramid import testing
class PageModelTests(unittest.TestCase):
def _getTargetClass(self):
- from tutorial.models import Page
+ from .models import Page
return Page
def _makeOne(self, data=u'some data'):
@@ -14,11 +14,11 @@ class PageModelTests(unittest.TestCase):
def test_constructor(self):
instance = self._makeOne()
self.assertEqual(instance.data, u'some data')
-
+
class WikiModelTests(unittest.TestCase):
def _getTargetClass(self):
- from tutorial.models import Wiki
+ from .models import Wiki
return Wiki
def _makeOne(self):
@@ -32,7 +32,7 @@ class WikiModelTests(unittest.TestCase):
class AppmakerTests(unittest.TestCase):
def _callFUT(self, zodb_root):
- from tutorial.models import appmaker
+ from .models import appmaker
return appmaker(zodb_root)
def test_no_app_root(self):
@@ -55,7 +55,7 @@ class ViewTests(unittest.TestCase):
testing.tearDown()
def test_my_view(self):
- from tutorial.views import my_view
+ from .views import my_view
request = testing.DummyRequest()
info = my_view(request)
self.assertEqual(info['project'], 'tutorial')
diff --git a/docs/tutorials/wiki/src/models/tutorial/views.py b/docs/tutorials/wiki/src/models/tutorial/views.py
index 2346602c9..7c1f1d228 100644
--- a/docs/tutorials/wiki/src/models/tutorial/views.py
+++ b/docs/tutorials/wiki/src/models/tutorial/views.py
@@ -1,5 +1,5 @@
from pyramid.view import view_config
-@view_config(renderer='tutorial:templates/mytemplate.pt')
+@view_config(renderer='templates/mytemplate.pt')
def my_view(request):
return {'project':'tutorial'}
diff --git a/docs/tutorials/wiki/src/tests/tutorial/__init__.py b/docs/tutorials/wiki/src/tests/tutorial/__init__.py
index 2d6eb5ecb..20ee685ee 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/tests/tutorial/__init__.py
@@ -4,8 +4,8 @@ from pyramid_zodbconn import get_connection
from pyramid.authentication import AuthTktAuthenticationPolicy
from pyramid.authorization import ACLAuthorizationPolicy
-from tutorial.models import appmaker
-from tutorial.security import groupfinder
+from .models import appmaker
+from .security import groupfinder
def root_factory(request):
conn = get_connection(request)
@@ -20,6 +20,6 @@ def main(global_config, **settings):
config = Configurator(root_factory=root_factory, settings=settings,
authentication_policy=authn_policy,
authorization_policy=authz_policy)
- config.add_static_view('static', 'tutorial:static', cache_max_age=3600)
- config.scan('tutorial')
+ 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/tutorial/login.py b/docs/tutorials/wiki/src/tests/tutorial/login.py
deleted file mode 100644
index d608a7d0b..000000000
--- a/docs/tutorials/wiki/src/tests/tutorial/login.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from pyramid.httpexceptions import HTTPFound
-
-from pyramid.security import remember
-from pyramid.security import forget
-from pyramid.view import view_config
-
-from tutorial.security import USERS
-
-@view_config(context='tutorial.models.Wiki', name='login',
- renderer='templates/login.pt')
-@view_config(context='pyramid.httpexceptions.HTTPForbidden',
- renderer='templates/login.pt')
-def login(request):
- login_url = request.resource_url(request.context, 'login')
- referrer = request.url
- if referrer == login_url:
- referrer = '/' # never use the login form itself as came_from
- came_from = request.params.get('came_from', referrer)
- message = ''
- login = ''
- password = ''
- if 'form.submitted' in request.params:
- login = request.params['login']
- password = request.params['password']
- if USERS.get(login) == password:
- headers = remember(request, login)
- return HTTPFound(location = came_from,
- headers = headers)
- message = 'Failed login'
-
- return dict(
- message = message,
- url = request.application_url + '/login',
- came_from = came_from,
- login = login,
- password = password,
- )
-
-@view_config(context='tutorial.models.Wiki', name='logout')
-def logout(request):
- headers = forget(request)
- return HTTPFound(location = request.resource_url(request.context),
- headers = headers)
-
diff --git a/docs/tutorials/wiki/src/tests/tutorial/security.py b/docs/tutorials/wiki/src/tests/tutorial/security.py
index cfd13071e..d88c9c71f 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/security.py
+++ b/docs/tutorials/wiki/src/tests/tutorial/security.py
@@ -5,4 +5,3 @@ GROUPS = {'editor':['group:editors']}
def groupfinder(userid, request):
if userid in USERS:
return GROUPS.get(userid, [])
-
diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt
index f9da6c414..0d0738f7f 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt
+++ b/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt
@@ -9,13 +9,13 @@
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
<link rel="shortcut icon"
- href="${request.static_url('tutorial:static/favicon.ico')}" />
+ href="/static/favicon.ico" />
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/pylons.css')}"
+ href="/static/pylons.css"
type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/ie6.css')}"
+ href="/static/ie6.css"
type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head>
@@ -25,7 +25,7 @@
<div class="top-small align-center">
<div>
<img width="220" height="50" alt="pyramid"
- src="${request.static_url('tutorial:static/pyramid-small.png')}" />
+ src="/static/pyramid-small.png" />
</div>
</div>
</div>
diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt
index 64e592ea9..2c7235761 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt
+++ b/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt
@@ -9,13 +9,13 @@
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
<link rel="shortcut icon"
- href="${request.static_url('tutorial:static/favicon.ico')}" />
+ href="/static/favicon.ico" />
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/pylons.css')}"
+ href="/static/pylons.css"
type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/ie6.css')}"
+ href="/static/ie6.css"
type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head>
@@ -25,7 +25,7 @@
<div class="top-small align-center">
<div>
<img width="220" height="50" alt="pyramid"
- src="${request.static_url('tutorial:static/pyramid-small.png')}" />
+ src="/static/pyramid-small.png" />
</div>
</div>
</div>
diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt
index 14b88d16a..3597c679b 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt
@@ -5,19 +5,19 @@
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
- <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" />
+ <link rel="shortcut icon" href="/static/favicon.ico" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" />
- <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" />
+ <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
- <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" />
+ <link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head>
<body>
<div id="wrap">
<div id="top">
<div class="top align-center">
- <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div>
+ <div><img src="/static/pyramid.png" width="750" height="169" alt="pyramid"/></div>
</div>
</div>
<div id="middle">
diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt
index d207a0c23..9dd6540cf 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt
+++ b/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt
@@ -9,13 +9,13 @@
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
<link rel="shortcut icon"
- href="${request.static_url('tutorial:static/favicon.ico')}" />
+ href="/static/favicon.ico" />
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/pylons.css')}"
+ href="/static/pylons.css"
type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/ie6.css')}"
+ href="/static/ie6.css"
type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head>
@@ -25,7 +25,7 @@
<div class="top-small align-center">
<div>
<img width="220" height="50" alt="pyramid"
- src="${request.static_url('tutorial:static/pyramid-small.png')}" />
+ src="/static/pyramid-small.png" />
</div>
</div>
</div>
diff --git a/docs/tutorials/wiki/src/tests/tutorial/tests.py b/docs/tutorials/wiki/src/tests/tutorial/tests.py
index b1d4e68c3..81f7a1882 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/tests.py
+++ b/docs/tutorials/wiki/src/tests/tutorial/tests.py
@@ -5,7 +5,7 @@ from pyramid import testing
class PageModelTests(unittest.TestCase):
def _getTargetClass(self):
- from tutorial.models import Page
+ from .models import Page
return Page
def _makeOne(self, data=u'some data'):
@@ -18,7 +18,7 @@ class PageModelTests(unittest.TestCase):
class WikiModelTests(unittest.TestCase):
def _getTargetClass(self):
- from tutorial.models import Wiki
+ from .models import Wiki
return Wiki
def _makeOne(self):
@@ -31,7 +31,7 @@ class WikiModelTests(unittest.TestCase):
class AppmakerTests(unittest.TestCase):
def _callFUT(self, zodb_root):
- from tutorial.models import appmaker
+ from .models import appmaker
return appmaker(zodb_root)
def test_it(self):
@@ -42,7 +42,7 @@ class AppmakerTests(unittest.TestCase):
class ViewWikiTests(unittest.TestCase):
def test_it(self):
- from tutorial.views import view_wiki
+ from .views import view_wiki
context = testing.DummyResource()
request = testing.DummyRequest()
response = view_wiki(context, request)
@@ -50,7 +50,7 @@ class ViewWikiTests(unittest.TestCase):
class ViewPageTests(unittest.TestCase):
def _callFUT(self, context, request):
- from tutorial.views import view_page
+ from .views import view_page
return view_page(context, request)
def test_it(self):
@@ -76,7 +76,7 @@ class ViewPageTests(unittest.TestCase):
class AddPageTests(unittest.TestCase):
def _callFUT(self, context, request):
- from tutorial.views import add_page
+ from .views import add_page
return add_page(context, request)
def test_it_notsubmitted(self):
@@ -102,7 +102,7 @@ class AddPageTests(unittest.TestCase):
class EditPageTests(unittest.TestCase):
def _callFUT(self, context, request):
- from tutorial.views import edit_page
+ from .views import edit_page
return edit_page(context, request)
def test_it_notsubmitted(self):
@@ -133,7 +133,7 @@ class FunctionalTests(unittest.TestCase):
def setUp(self):
import tempfile
import os.path
- from tutorial import main
+ from . import main
self.tmpdir = tempfile.mkdtemp()
dbpath = os.path.join( self.tmpdir, 'test.db')
diff --git a/docs/tutorials/wiki/src/tests/tutorial/views.py b/docs/tutorials/wiki/src/tests/tutorial/views.py
index a570410ca..2f0502c17 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/views.py
+++ b/docs/tutorials/wiki/src/tests/tutorial/views.py
@@ -2,19 +2,26 @@ from docutils.core import publish_parts
import re
from pyramid.httpexceptions import HTTPFound
+
from pyramid.view import view_config
-from pyramid.security import authenticated_userid
-from tutorial.models import Page
+from pyramid.security import (
+ authenticated_userid,
+ remember,
+ forget,
+ )
+
+from .security import USERS
+from .models import Page
# regular expression used to find WikiWords
wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)")
-@view_config(context='tutorial.models.Wiki', permission='view')
+@view_config(context='.models.Wiki', permission='view')
def view_wiki(context, request):
return HTTPFound(location=request.resource_url(context, 'FrontPage'))
-@view_config(context='tutorial.models.Page',
+@view_config(context='.models.Page',
renderer='templates/view.pt', permission='view')
def view_page(context, request):
wiki = context.__parent__
@@ -38,7 +45,7 @@ def view_page(context, request):
return dict(page = context, content = content, edit_url = edit_url,
logged_in = logged_in)
-@view_config(name='add_page', context='tutorial.models.Wiki',
+@view_config(name='add_page', context='.models.Wiki',
renderer='templates/edit.pt',
permission='edit')
def add_page(context, request):
@@ -59,7 +66,7 @@ def add_page(context, request):
return dict(page = page, save_url = save_url, logged_in = logged_in)
-@view_config(name='edit_page', context='tutorial.models.Page',
+@view_config(name='edit_page', context='.models.Page',
renderer='templates/edit.pt',
permission='edit')
def edit_page(context, request):
@@ -72,4 +79,39 @@ def edit_page(context, request):
return dict(page = context,
save_url = request.resource_url(context, 'edit_page'),
logged_in = logged_in)
-
+
+@view_config(context='.models.Wiki', name='login',
+ renderer='templates/login.pt')
+@view_config(context='pyramid.httpexceptions.HTTPForbidden',
+ renderer='templates/login.pt')
+def login(request):
+ login_url = request.resource_url(request.context, 'login')
+ referrer = request.url
+ if referrer == login_url:
+ referrer = '/' # never use the login form itself as came_from
+ came_from = request.params.get('came_from', referrer)
+ message = ''
+ login = ''
+ password = ''
+ if 'form.submitted' in request.params:
+ login = request.params['login']
+ password = request.params['password']
+ if USERS.get(login) == password:
+ headers = remember(request, login)
+ return HTTPFound(location = came_from,
+ headers = headers)
+ message = 'Failed login'
+
+ return dict(
+ message = message,
+ url = request.application_url + '/login',
+ came_from = came_from,
+ login = login,
+ password = password,
+ )
+
+@view_config(context='.models.Wiki', name='logout')
+def logout(request):
+ headers = forget(request)
+ return HTTPFound(location = request.resource_url(request.context),
+ headers = headers)
diff --git a/docs/tutorials/wiki/src/views/tutorial/__init__.py b/docs/tutorials/wiki/src/views/tutorial/__init__.py
index 009013b3f..957a0b705 100644
--- a/docs/tutorials/wiki/src/views/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/views/tutorial/__init__.py
@@ -10,6 +10,6 @@ def main(global_config, **settings):
""" This function returns a WSGI application.
"""
config = Configurator(root_factory=root_factory, settings=settings)
- config.add_static_view('static', 'tutorial:static', cache_max_age=3600)
+ config.add_static_view('static', 'static', cache_max_age=3600)
config.scan('tutorial')
return config.make_wsgi_app()
diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/edit.pt b/docs/tutorials/wiki/src/views/tutorial/templates/edit.pt
index 6dbb0edde..24ed2e592 100644
--- a/docs/tutorials/wiki/src/views/tutorial/templates/edit.pt
+++ b/docs/tutorials/wiki/src/views/tutorial/templates/edit.pt
@@ -9,13 +9,13 @@
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
<link rel="shortcut icon"
- href="${request.static_url('tutorial:static/favicon.ico')}" />
+ href="/static/favicon.ico" />
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/pylons.css')}"
+ href="/static/pylons.css"
type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/ie6.css')}"
+ href="/static/ie6.css"
type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head>
@@ -25,7 +25,7 @@
<div class="top-small align-center">
<div>
<img width="220" height="50" alt="pyramid"
- src="${request.static_url('tutorial:static/pyramid-small.png')}" />
+ src="/static/pyramid-small.png" />
</div>
</div>
</div>
diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt
index 14b88d16a..3597c679b 100644
--- a/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt
@@ -5,19 +5,19 @@
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
- <link rel="shortcut icon" href="${request.static_url('tutorial:static/favicon.ico')}" />
+ <link rel="shortcut icon" href="/static/favicon.ico" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" />
- <link rel="stylesheet" href="${request.static_url('tutorial:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" />
+ <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
- <link rel="stylesheet" href="${request.static_url('tutorial:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" />
+ <link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head>
<body>
<div id="wrap">
<div id="top">
<div class="top align-center">
- <div><img src="${request.static_url('tutorial:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div>
+ <div><img src="/static/pyramid.png" width="750" height="169" alt="pyramid"/></div>
</div>
</div>
<div id="middle">
diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/view.pt b/docs/tutorials/wiki/src/views/tutorial/templates/view.pt
index 537ae3a15..424c4302a 100644
--- a/docs/tutorials/wiki/src/views/tutorial/templates/view.pt
+++ b/docs/tutorials/wiki/src/views/tutorial/templates/view.pt
@@ -9,13 +9,13 @@
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
<link rel="shortcut icon"
- href="${request.static_url('tutorial:static/favicon.ico')}" />
+ href="/static/favicon.ico" />
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/pylons.css')}"
+ href="/static/pylons.css"
type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
<link rel="stylesheet"
- href="${request.static_url('tutorial:static/ie6.css')}"
+ href="/static/ie6.css"
type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head>
@@ -25,7 +25,7 @@
<div class="top-small align-center">
<div>
<img width="220" height="50" alt="pyramid"
- src="${request.static_url('tutorial:static/pyramid-small.png')}" />
+ src="/static/pyramid-small.png" />
</div>
</div>
</div>
diff --git a/docs/tutorials/wiki/src/views/tutorial/views.py b/docs/tutorials/wiki/src/views/tutorial/views.py
index 245cda682..016f5b6bb 100644
--- a/docs/tutorials/wiki/src/views/tutorial/views.py
+++ b/docs/tutorials/wiki/src/views/tutorial/views.py
@@ -4,17 +4,16 @@ import re
from pyramid.httpexceptions import HTTPFound
from pyramid.view import view_config
-from tutorial.models import Page
+from .models import Page
# regular expression used to find WikiWords
wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)")
-@view_config(context='tutorial.models.Wiki')
+@view_config(context='.models.Wiki')
def view_wiki(context, request):
return HTTPFound(location=request.resource_url(context, 'FrontPage'))
-@view_config(context='tutorial.models.Page',
- renderer='tutorial:templates/view.pt')
+@view_config(context='.models.Page', renderer='templates/view.pt')
def view_page(context, request):
wiki = context.__parent__
@@ -33,8 +32,8 @@ def view_page(context, request):
edit_url = request.resource_url(context, 'edit_page')
return dict(page = context, content = content, edit_url = edit_url)
-@view_config(name='add_page', context='tutorial.models.Wiki',
- renderer='tutorial:templates/edit.pt')
+@view_config(name='add_page', context='.models.Wiki',
+ renderer='templates/edit.pt')
def add_page(context, request):
name = request.subpath[0]
if 'form.submitted' in request.params:
@@ -50,8 +49,8 @@ def add_page(context, request):
page.__parent__ = context
return dict(page = page, save_url = save_url)
-@view_config(name='edit_page', context='tutorial.models.Page',
- renderer='tutorial:templates/edit.pt')
+@view_config(name='edit_page', context='.models.Page',
+ renderer='templates/edit.pt')
def edit_page(context, request):
if 'form.submitted' in request.params:
context.data = request.params['body']
@@ -59,5 +58,3 @@ def edit_page(context, request):
return dict(page = context,
save_url = request.resource_url(context, 'edit_page'))
-
-
diff --git a/docs/tutorials/wiki/tests.rst b/docs/tutorials/wiki/tests.rst
index 841baa8d1..1ddb8f408 100644
--- a/docs/tutorials/wiki/tests.rst
+++ b/docs/tutorials/wiki/tests.rst
@@ -6,22 +6,21 @@ We will now add tests for the models and the views and a few functional
tests in the ``tests.py``. Tests ensure that an application works, and
that it continues to work after some changes are made in the future.
-Testing the Models
-==================
+Test the Models
+===============
-We write tests for the model
-classes and the appmaker. Changing ``tests.py``, we'll write a separate test
-class for each model class, and we'll write a test class for the
-``appmaker``.
+We write tests for the model classes and the appmaker. Changing
+``tests.py``, we'll write a separate test class for each model class, and
+we'll write a test class for the ``appmaker``.
To do so, we'll retain the ``tutorial.tests.ViewTests`` class provided as a
-result of the ``pyramid_zodb`` project generator. We'll add three test
+result of the ``zodb`` project generator. We'll add three test
classes: one for the ``Page`` model named ``PageModelTests``, one for the
``Wiki`` model named ``WikiModelTests``, and one for the appmaker named
``AppmakerTests``.
-Testing the Views
-=================
+Test the Views
+==============
We'll modify our ``tests.py`` file, adding tests for each view function we
added above. As a result, we'll *delete* the ``ViewTests`` test in the file,
@@ -38,8 +37,8 @@ tested in the unit tests, like logging in, logging out, checking that
the ``viewer`` user cannot add or edit pages, but the ``editor`` user
can, and so on.
-Viewing the results of all our edits to ``tests.py``
-====================================================
+View the results of all our edits to ``tests.py``
+=================================================
Once we're done with the ``tests.py`` module, it will look a lot like the
below:
@@ -48,8 +47,8 @@ below:
:linenos:
:language: python
-Running the Tests
-=================
+Run the Tests
+=============
We can run these tests by using ``setup.py test`` in the same way we did in
:ref:`running_tests`. However, first we must edit our ``setup.py`` to