summaryrefslogtreecommitdiff
path: root/docs/tutorials/wiki
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tutorials/wiki')
-rw-r--r--docs/tutorials/wiki/authorization.rst88
-rw-r--r--docs/tutorials/wiki/background.rst2
-rw-r--r--docs/tutorials/wiki/basiclayout.rst28
-rw-r--r--docs/tutorials/wiki/definingmodels.rst6
-rw-r--r--docs/tutorials/wiki/definingviews.rst51
-rw-r--r--docs/tutorials/wiki/design.rst7
-rw-r--r--docs/tutorials/wiki/distributing.rst9
-rw-r--r--docs/tutorials/wiki/index.rst7
-rw-r--r--docs/tutorials/wiki/installation.rst270
-rw-r--r--docs/tutorials/wiki/src/authorization/.coveragerc3
-rw-r--r--docs/tutorials/wiki/src/authorization/CHANGES.txt2
-rw-r--r--docs/tutorials/wiki/src/authorization/README.txt27
-rw-r--r--docs/tutorials/wiki/src/authorization/development.ini10
-rw-r--r--docs/tutorials/wiki/src/authorization/production.ini11
-rw-r--r--docs/tutorials/wiki/src/authorization/pytest.ini3
-rw-r--r--docs/tutorials/wiki/src/authorization/setup.py61
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/__init__.py2
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/security.py17
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt1
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt1
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt67
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt1
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/tests.py2
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/views.py6
-rw-r--r--docs/tutorials/wiki/src/basiclayout/.coveragerc3
-rw-r--r--docs/tutorials/wiki/src/basiclayout/CHANGES.txt2
-rw-r--r--docs/tutorials/wiki/src/basiclayout/README.txt27
-rw-r--r--docs/tutorials/wiki/src/basiclayout/development.ini10
-rw-r--r--docs/tutorials/wiki/src/basiclayout/production.ini11
-rw-r--r--docs/tutorials/wiki/src/basiclayout/pytest.ini3
-rw-r--r--docs/tutorials/wiki/src/basiclayout/setup.py60
-rw-r--r--docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py2
-rw-r--r--docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt10
-rw-r--r--docs/tutorials/wiki/src/basiclayout/tutorial/tests.py2
-rw-r--r--docs/tutorials/wiki/src/basiclayout/tutorial/views.py2
-rw-r--r--docs/tutorials/wiki/src/installation/.coveragerc3
-rw-r--r--docs/tutorials/wiki/src/installation/CHANGES.txt2
-rw-r--r--docs/tutorials/wiki/src/installation/README.txt27
-rw-r--r--docs/tutorials/wiki/src/installation/development.ini10
-rw-r--r--docs/tutorials/wiki/src/installation/production.ini11
-rw-r--r--docs/tutorials/wiki/src/installation/pytest.ini3
-rw-r--r--docs/tutorials/wiki/src/installation/setup.py60
-rw-r--r--docs/tutorials/wiki/src/installation/tutorial/__init__.py2
-rw-r--r--docs/tutorials/wiki/src/installation/tutorial/templates/mytemplate.pt10
-rw-r--r--docs/tutorials/wiki/src/installation/tutorial/tests.py2
-rw-r--r--docs/tutorials/wiki/src/installation/tutorial/views.py2
-rw-r--r--docs/tutorials/wiki/src/models/.coveragerc3
-rw-r--r--docs/tutorials/wiki/src/models/CHANGES.txt2
-rw-r--r--docs/tutorials/wiki/src/models/README.txt27
-rw-r--r--docs/tutorials/wiki/src/models/development.ini10
-rw-r--r--docs/tutorials/wiki/src/models/production.ini11
-rw-r--r--docs/tutorials/wiki/src/models/pytest.ini3
-rw-r--r--docs/tutorials/wiki/src/models/setup.py60
-rw-r--r--docs/tutorials/wiki/src/models/tutorial/__init__.py2
-rw-r--r--docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt10
-rw-r--r--docs/tutorials/wiki/src/models/tutorial/tests.py2
-rw-r--r--docs/tutorials/wiki/src/models/tutorial/views.py2
-rw-r--r--docs/tutorials/wiki/src/tests/.coveragerc3
-rw-r--r--docs/tutorials/wiki/src/tests/CHANGES.txt2
-rw-r--r--docs/tutorials/wiki/src/tests/README.txt27
-rw-r--r--docs/tutorials/wiki/src/tests/development.ini10
-rw-r--r--docs/tutorials/wiki/src/tests/production.ini11
-rw-r--r--docs/tutorials/wiki/src/tests/pytest.ini3
-rw-r--r--docs/tutorials/wiki/src/tests/setup.py61
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/__init__.py2
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/security.py17
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt1
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/templates/login.pt1
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/templates/view.pt1
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/tests.py11
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/views.py6
-rw-r--r--docs/tutorials/wiki/src/views/.coveragerc3
-rw-r--r--docs/tutorials/wiki/src/views/CHANGES.txt2
-rw-r--r--docs/tutorials/wiki/src/views/README.txt27
-rw-r--r--docs/tutorials/wiki/src/views/development.ini10
-rw-r--r--docs/tutorials/wiki/src/views/production.ini11
-rw-r--r--docs/tutorials/wiki/src/views/pytest.ini3
-rw-r--r--docs/tutorials/wiki/src/views/setup.py60
-rw-r--r--docs/tutorials/wiki/src/views/tutorial/__init__.py2
-rw-r--r--docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt67
-rw-r--r--docs/tutorials/wiki/src/views/tutorial/templates/view.pt1
-rw-r--r--docs/tutorials/wiki/src/views/tutorial/tests.py2
-rw-r--r--docs/tutorials/wiki/src/views/tutorial/views.py12
-rw-r--r--docs/tutorials/wiki/tests.rst18
84 files changed, 716 insertions, 736 deletions
diff --git a/docs/tutorials/wiki/authorization.rst b/docs/tutorials/wiki/authorization.rst
index 44097b35b..0ba734f83 100644
--- a/docs/tutorials/wiki/authorization.rst
+++ b/docs/tutorials/wiki/authorization.rst
@@ -18,6 +18,7 @@ require permission, instead of a default "403 Forbidden" page.
We will implement the access control with the following steps:
+* Add password hashing dependencies.
* Add users and groups (``security.py``, a new module).
* Add an :term:`ACL` (``models.py``).
* Add an :term:`authentication policy` and an :term:`authorization policy`
@@ -25,7 +26,7 @@ We will implement the access control with the following steps:
* Add :term:`permission` declarations to the ``edit_page`` and ``add_page``
views (``views.py``).
-Then we will add the login and logout feature:
+Then we will add the login and logout features:
* Add ``login`` and ``logout`` views (``views.py``).
* Add a login template (``login.pt``).
@@ -38,11 +39,32 @@ Then we will add the login and logout feature:
Access control
--------------
+
+Add dependencies
+~~~~~~~~~~~~~~~~
+
+Just like in :ref:`wiki_defining_views`, we need a new dependency. We need to add the `bcrypt <https://pypi.python.org/pypi/bcrypt>`_ package, to our tutorial package's ``setup.py`` file by assigning this dependency to the ``requires`` parameter in the ``setup()`` function.
+
+Open ``setup.py`` and edit it to look like the following:
+
+.. literalinclude:: src/authorization/setup.py
+ :linenos:
+ :emphasize-lines: 21
+ :language: python
+
+Only the highlighted line needs to be added.
+
+Do not forget to run ``pip install -e .`` just like in :ref:`wiki-running-pip-install`.
+
+.. note::
+
+ We are using the ``bcrypt`` package from PyPI to hash our passwords securely. There are other one-way hash algorithms for passwords if bcrypt is an issue on your system. Just make sure that it's an algorithm approved for storing passwords versus a generic one-way hash.
+
+
Add users and groups
~~~~~~~~~~~~~~~~~~~~
-Create a new ``tutorial/security.py`` module with the
-following content:
+Create a new ``tutorial/security.py`` module with the following content:
.. literalinclude:: src/authorization/tutorial/security.py
:linenos:
@@ -51,7 +73,7 @@ following content:
The ``groupfinder`` function accepts a userid and a request and
returns one of these values:
-- If the userid exists in the system, it will return a sequence of group
+- If ``userid`` exists in the system, it 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, it will return ``None``.
@@ -61,26 +83,38 @@ request)`` returns ``None``. We will use ``groupfinder()`` as an
:term:`authentication policy` "callback" that will provide the
:term:`principal` or principals for a user.
-In a production system, user and group data will most often come from a
+There are two helper methods that will help us later to authenticate users.
+The first is ``hash_password`` which takes a raw password and transforms it using
+bcrypt into an irreversible representation, a process known as "hashing". The
+second method, ``check_password``, will allow us to compare the hashed value of the
+submitted password against the hashed value of the password stored in the user's
+record. If the two hashed values match, then the submitted
+password is valid, and we can authenticate the user.
+
+We hash passwords so that it is impossible to decrypt and use them to
+authenticate in the application. If we stored passwords foolishly in clear text,
+then anyone with access to the database could retrieve any password to authenticate
+as any user.
+
+In a production system, user and group data will most often be saved and come from a
database, but here we use "dummy" data to represent user and groups sources.
Add an ACL
~~~~~~~~~~
Open ``tutorial/models.py`` and add the following import
-statement at the head:
+statement near the top:
.. literalinclude:: src/authorization/tutorial/models.py
- :lines: 4-7
- :linenos:
+ :lines: 4-8
+ :lineno-match:
:language: python
Add the following lines to the ``Wiki`` class:
.. literalinclude:: src/authorization/tutorial/models.py
:lines: 9-13
- :linenos:
- :lineno-start: 9
+ :lineno-match:
:emphasize-lines: 4-5
:language: python
@@ -89,10 +123,10 @@ permission is allowed, and :data:`~pyramid.security.Everyone`, a special
:term:`principal` that is associated to all requests. Both are used in the
:term:`ACE` entries that make up the ACL.
-The ACL is a list that needs to be named `__acl__` and be an attribute of a
+The ACL is a list that needs to be named ``__acl__`` and be an attribute of a
class. We define an :term:`ACL` with two :term:`ACE` entries: the first entry
-allows any user the `view` permission. The second entry allows the
-``group:editors`` principal the `edit` permission.
+allows any user the ``view`` permission. The second entry allows the
+``group:editors`` principal the ``edit`` permission.
The ``Wiki`` class that contains the ACL is the :term:`resource` constructor
for the :term:`root` resource, which is a ``Wiki`` instance. The ACL is
@@ -115,15 +149,14 @@ statements:
.. literalinclude:: src/authorization/tutorial/__init__.py
:lines: 1-8
:linenos:
- :emphasize-lines: 4-5,8
+ :emphasize-lines: 3-6,8
:language: python
Now add those policies to the configuration:
.. literalinclude:: src/authorization/tutorial/__init__.py
:lines: 18-23
- :linenos:
- :lineno-start: 18
+ :lineno-match:
:emphasize-lines: 1-3,5-6
:language: python
@@ -146,12 +179,12 @@ Open ``tutorial/views.py`` and add a ``permission='edit'`` parameter
to the ``@view_config`` decorators for ``add_page()`` and ``edit_page()``:
.. literalinclude:: src/authorization/tutorial/views.py
- :lines: 50-52
+ :lines: 49-51
:emphasize-lines: 2-3
:language: python
.. literalinclude:: src/authorization/tutorial/views.py
- :lines: 70-72
+ :lines: 68-70
:emphasize-lines: 2-3
:language: python
@@ -213,9 +246,8 @@ cookie.
Now add the ``login`` and ``logout`` views at the end of the file:
.. literalinclude:: src/authorization/tutorial/views.py
- :lines: 82-116
- :linenos:
- :lineno-start: 82
+ :lines: 80-
+ :lineno-match:
:language: python
``login()`` has two decorators:
@@ -252,17 +284,17 @@ the return value of ``view_page()``, ``add_page()``, and ``edit_page()`` as
follows:
.. literalinclude:: src/authorization/tutorial/views.py
- :lines: 47-48
+ :lines: 46-47
:emphasize-lines: 1-2
:language: python
.. literalinclude:: src/authorization/tutorial/views.py
- :lines: 67-68
+ :lines: 65-66
:emphasize-lines: 1-2
:language: python
.. literalinclude:: src/authorization/tutorial/views.py
- :lines: 78-80
+ :lines: 76-78
:emphasize-lines: 2-3
:language: python
@@ -279,7 +311,7 @@ Open ``tutorial/templates/edit.pt`` and
indicated by the highlighted lines.
.. literalinclude:: src/authorization/tutorial/templates/edit.pt
- :lines: 34-38
+ :lines: 35-39
:emphasize-lines: 3-5
:language: html
@@ -313,7 +345,7 @@ Our ``tutorial/views.py`` will look like this when we're done:
.. literalinclude:: src/authorization/tutorial/views.py
:linenos:
- :emphasize-lines: 8,11-15,17,24,29,48,52,68,72,80,82-120
+ :emphasize-lines: 8,11-15,17,24,29,47,51,66,70,78,80-
:language: python
Only the highlighted lines need to be added or edited.
@@ -323,7 +355,7 @@ we're done:
.. literalinclude:: src/authorization/tutorial/templates/edit.pt
:linenos:
- :emphasize-lines: 36-38
+ :emphasize-lines: 37-39
:language: html
Only the highlighted lines need to be added or edited.
@@ -333,7 +365,7 @@ we're done:
.. literalinclude:: src/authorization/tutorial/templates/view.pt
:linenos:
- :emphasize-lines: 36-38
+ :emphasize-lines: 37-39
:language: html
Only the highlighted lines need to be added or edited.
diff --git a/docs/tutorials/wiki/background.rst b/docs/tutorials/wiki/background.rst
index 31dcd6b53..c583b375c 100644
--- a/docs/tutorials/wiki/background.rst
+++ b/docs/tutorials/wiki/background.rst
@@ -13,7 +13,7 @@ Python web framework experience.
To code along with this tutorial, the developer will need a UNIX
machine with development tools (Mac OS X with XCode, any Linux or BSD
-variant, etc.) *or* a Windows system of any kind.
+variant, and so on) *or* a Windows system of any kind.
.. warning::
diff --git a/docs/tutorials/wiki/basiclayout.rst b/docs/tutorials/wiki/basiclayout.rst
index 20bfdf754..d00eab956 100644
--- a/docs/tutorials/wiki/basiclayout.rst
+++ b/docs/tutorials/wiki/basiclayout.rst
@@ -4,7 +4,7 @@
Basic Layout
============
-The starter files generated by the ``zodb`` scaffold are very basic, but
+The starter files generated by the ``zodb`` cookiecutter are very basic, but
they provide a good orientation for the high-level patterns common to most
:term:`traversal`-based (and :term:`ZODB`-based) :app:`Pyramid` projects.
@@ -44,7 +44,11 @@ Open ``tutorial/__init__.py``. It should already contain the following:
#. *Line 15*. Include support for the :term:`Chameleon` template rendering
bindings, allowing us to use the ``.pt`` templates.
-#. *Line 16*. Register a "static view", which answers requests whose URL
+#. *Line 16*. Include support for ``pyramid_tm``, allowing Pyramid requests to join the active transaction as provided by the `transaction <https://pypi.python.org/pypi/transaction>`_ package.
+
+#. *Line 17*. Include support for ``pyramid_zodbconn``, providing integration between :term:`ZODB` and a Pyramid application.
+
+#. *Line 18*. Register a "static view", which answers requests whose URL
paths start with ``/static``, using the
:meth:`pyramid.config.Configurator.add_static_view` method. This
statement registers a view that will serve up static assets, such as CSS
@@ -54,19 +58,19 @@ Open ``tutorial/__init__.py``. It should already contain the following:
will be ``/static``. The second argument of this tag is the "path",
which is a relative :term:`asset specification`, so it finds the resources
it should serve within the ``static`` directory inside the ``tutorial``
- package. Alternatively the scaffold could have used an *absolute* asset
+ package. Alternatively the cookiecutter could have used an *absolute* asset
specification as the path (``tutorial:static``).
-#. *Line 17*. Perform a :term:`scan`. A scan will find :term:`configuration
+#. *Line 19*. Perform a :term:`scan`. A scan will find :term:`configuration
decoration`, such as view configuration decorators (e.g., ``@view_config``)
in the source code of the ``tutorial`` package and will take actions based
on these decorators. We don't pass any arguments to
: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
+ The cookiecutter could have equivalently said ``config.scan('tutorial')``, but
it chose to omit the package name argument.
-#. *Line 18*. Use the
+#. *Line 20*. Use the
:meth:`pyramid.config.Configurator.make_wsgi_app` method
to return a :term:`WSGI` application.
@@ -79,7 +83,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 ``zodb`` scaffold put the classes that implement our
+where the ``zodb`` cookiecutter put the classes that implement our
resource objects, each of which also happens to be a domain model object.
Here is the source for ``models.py``:
@@ -93,7 +97,7 @@ Here is the source for ``models.py``:
because the class inherits from the
:class:`persistent.mapping.PersistentMapping` class. The ``__parent__``
and ``__name__`` are important parts of the :term:`traversal` protocol.
- By default, have these as ``None`` indicating that this is the
+ By default, set these to ``None`` to indicate that this is the
:term:`root` object.
#. *Lines 8-14*. ``appmaker`` is used to return the *application
@@ -110,7 +114,7 @@ Here is the source for ``models.py``:
Views With ``views.py``
-----------------------
-Our scaffold generated a default ``views.py`` on our behalf. It
+Our cookiecutter generated a default ``views.py`` on our behalf. It
contains a single view, which is used to render the page shown when you visit
the URL ``http://localhost:6543/``.
@@ -156,7 +160,7 @@ Let's try to understand the components in this module:
#. *Lines 6-7*. 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 ``zodb`` scaffold that is given a
+ write generated by the ``zodb`` cookiecutter 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.
@@ -168,8 +172,8 @@ Let's try to understand the components in this module:
Configuration in ``development.ini``
------------------------------------
-The ``development.ini`` (in the tutorial :term:`project` directory, as
-opposed to the tutorial :term:`package` directory) looks like this:
+The ``development.ini`` (in the ``tutorial`` :term:`project` directory, as
+opposed to the ``tutorial`` :term:`package` directory) looks like this:
.. literalinclude:: src/basiclayout/development.ini
:language: ini
diff --git a/docs/tutorials/wiki/definingmodels.rst b/docs/tutorials/wiki/definingmodels.rst
index 73dce14d5..419fede62 100644
--- a/docs/tutorials/wiki/definingmodels.rst
+++ b/docs/tutorials/wiki/definingmodels.rst
@@ -4,7 +4,7 @@
Defining the Domain Model
=========================
-The first change we'll make to our stock ``pcreate``-generated application will
+The first change we'll make to our stock cookiecutter-generated application will
be to define two :term:`resource` constructors, one representing a wiki page,
and another representing the wiki as a mapping of wiki page names to page
objects. We'll do this inside our ``models.py`` file.
@@ -50,7 +50,9 @@ The first thing we want to do is remove the ``MyModel`` class from the
generated ``models.py`` file. The ``MyModel`` class is only a sample and
we're not going to use it.
-Then, we'll add a ``Wiki`` class. We want it to inherit from the
+Then we'll add an import at the top for the :class:`persistent.Persistent` class. We'll use this for a new ``Page`` class in a moment.
+
+Then we'll add a ``Wiki`` class. We want it to inherit from the
:class:`persistent.mapping.PersistentMapping` class because it provides
mapping behavior, and it makes sure that our Wiki page is stored as a
"first-class" persistent object in our ZODB database.
diff --git a/docs/tutorials/wiki/definingviews.rst b/docs/tutorials/wiki/definingviews.rst
index ac94d8059..442d5ed18 100644
--- a/docs/tutorials/wiki/definingviews.rst
+++ b/docs/tutorials/wiki/definingviews.rst
@@ -4,7 +4,7 @@
Defining Views
==============
-A :term:`view callable` in a :term:`traversal` -based :app:`Pyramid`
+A :term:`view callable` in a :term:`traversal`-based :app:`Pyramid`
application is typically a simple Python function that accepts two
parameters: :term:`context` and :term:`request`. A view callable is
assumed to return a :term:`response` object.
@@ -16,7 +16,7 @@ assumed to return a :term:`response` object.
this one-argument pattern used in other :app:`Pyramid` tutorials
and applications. Either calling convention will work in any
:app:`Pyramid` application; the calling conventions can be used
- interchangeably as necessary. In :term:`traversal` based applications,
+ interchangeably as necessary. In :term:`traversal`-based applications,
URLs are mapped 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
@@ -36,7 +36,7 @@ Declaring Dependencies in Our ``setup.py`` File
The view code in our application will depend on a package which is not a
dependency of the original "tutorial" application. The original "tutorial"
-application was generated by the ``pcreate`` command; it doesn't know
+application was generated by the cookiecutter; it doesn't know
about our custom application requirements.
We need to add a dependency on the ``docutils`` package to our ``tutorial``
@@ -52,6 +52,7 @@ Open ``setup.py`` and edit it to look like the following:
Only the highlighted line needs to be added.
+.. _wiki-running-pip-install:
Running ``pip install -e .``
============================
@@ -74,15 +75,15 @@ On Windows:
.. code-block:: doscon
- c:\pyramidtut> cd tutorial
- c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e .
+ c:\> cd tutorial
+ c:\tutorial> %VENV%\Scripts\pip install -e .
Success executing this command will end with a line to the console something
like:
.. code-block:: text
- Successfully installed docutils-0.12 tutorial-0.0
+ Successfully installed docutils-0.13.1 tutorial
Adding view functions in ``views.py``
@@ -98,11 +99,11 @@ like the following:
We added some imports and created a regular expression to find "WikiWords".
We got rid of the ``my_view`` view function and its decorator that was added
-when we originally rendered the ``zodb`` scaffold. It was only an example and
+when we originally rendered the ``zodb`` cookiecutter. It was only an example and
isn't relevant to our application.
Then we added four :term:`view callable` functions to our ``views.py``
-module:
+module:
* ``view_wiki()`` - Displays the wiki itself. It will answer on the root URL.
* ``view_page()`` - Displays an individual page.
@@ -126,8 +127,7 @@ Following is the code for the ``view_wiki`` view function and its decorator:
.. literalinclude:: src/views/tutorial/views.py
:lines: 12-14
- :lineno-start: 12
- :linenos:
+ :lineno-match:
:language: python
.. note:: In our code, we use an *import* that is *relative* to our package
@@ -165,8 +165,7 @@ Here is the code for the ``view_page`` view function and its decorator:
.. literalinclude:: src/views/tutorial/views.py
:lines: 16-33
- :lineno-start: 16
- :linenos:
+ :lineno-match:
:language: python
The ``view_page`` function is configured to respond as the default view
@@ -219,8 +218,7 @@ Here is the code for the ``add_page`` view function and its decorator:
.. literalinclude:: src/views/tutorial/views.py
:lines: 35-50
- :lineno-start: 35
- :linenos:
+ :lineno-match:
:language: python
The ``add_page`` function is configured to respond when the context resource
@@ -247,7 +245,7 @@ are found *after* the :term:`view name` in the URL segments given in the
add view is invoked via, e.g., ``http://localhost:6543/add_page/SomeName``,
the :term:`subpath` will be a tuple: ``('SomeName',)``.
-The add view takes the zeroth element of the subpath (the wiki page name),
+The add view takes the zero\ :sup:`th` element of the subpath (the wiki page name),
and aliases it to the name attribute in order to know the name of the page
we're trying to add.
@@ -274,8 +272,7 @@ Here is the code for the ``edit_page`` view function and its decorator:
.. literalinclude:: src/views/tutorial/views.py
:lines: 52-60
- :lineno-start: 52
- :linenos:
+ :lineno-match:
:language: python
The ``edit_page`` function is configured to respond when the context is
@@ -316,26 +313,26 @@ extension to be recognized as such.
The ``view.pt`` template
------------------------
-Create ``tutorial/templates/view.pt`` and add the following
-content:
+Rename ``tutorial/templates/mytemplate.pt`` to ``tutorial/templates/view.pt`` and edit the emphasized lines to look like the following:
.. literalinclude:: src/views/tutorial/templates/view.pt
:linenos:
:language: html
+ :emphasize-lines: 11-12,37-52
This template is used by ``view_page()`` for displaying a single
wiki page. It includes:
- A ``div`` element that is replaced with the ``content`` value provided by
- the view (lines 36-38). ``content`` contains HTML, so the ``structure``
+ the view (lines 37-39). ``content`` contains HTML, so the ``structure``
keyword is used to prevent escaping it (i.e., changing ">" to "&gt;", etc.)
- A link that points at the "edit" URL which invokes the ``edit_page`` view
- for the page being viewed (lines 40-42).
+ for the page being viewed (lines 41-43).
The ``edit.pt`` template
------------------------
-Create ``tutorial/templates/edit.pt`` and add the following content:
+Copy ``tutorial/templates/view.pt`` to ``tutorial/templates/edit.pt`` and edit the emphasized lines to look like the following:
.. literalinclude:: src/views/tutorial/templates/edit.pt
:linenos:
@@ -344,12 +341,12 @@ Create ``tutorial/templates/edit.pt`` and add the following content:
This template is used by ``add_page()`` and ``edit_page()`` for adding and
editing a wiki page. It displays a page containing a form that includes:
-- A 10 row by 60 column ``textarea`` field named ``body`` that is filled
- with any existing page data when it is rendered (line 45).
-- A submit button that has the name ``form.submitted`` (line 48).
+- A 10-row by 60-column ``textarea`` field named ``body`` that is filled
+ with any existing page data when it is rendered (line 46).
+- A submit button that has the name ``form.submitted`` (line 49).
The form POSTs back to the ``save_url`` argument supplied by the view (line
-43). The view will use the ``body`` and ``form.submitted`` values.
+44). The view will use the ``body`` and ``form.submitted`` values.
.. note:: Our templates use a ``request`` object that none of our tutorial
views return in their dictionary. ``request`` is one of several names that
@@ -394,5 +391,5 @@ each of the following URLs, checking that the result is as expected:
- http://localhost:6543/add_page/SomePageName invokes the add view for a Page.
- To generate an error, visit http://localhost:6543/add_page which will
- generate an ``IndexErrorr: tuple index out of range`` error. You'll see an
+ generate an ``IndexError: tuple index out of range`` error. You'll see an
interactive traceback facility provided by :term:`pyramid_debugtoolbar`.
diff --git a/docs/tutorials/wiki/design.rst b/docs/tutorials/wiki/design.rst
index f2a02176b..30d443bb8 100644
--- a/docs/tutorials/wiki/design.rst
+++ b/docs/tutorials/wiki/design.rst
@@ -43,11 +43,8 @@ editing, and viewing wiki pages, plus one view for the wiki front page.
Two templates will be used, one for viewing, and one for both adding
and editing wiki pages.
-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 had to pick one,
-we chose Chameleon for this tutorial.
+As of version 1.5 :app:`Pyramid` no longer ships with templating systems. In this tutorial, we will use :term:`Chameleon`. Chameleon is a variant of :term:`ZPT`, which is an XML-based templating language.
+
Security
--------
diff --git a/docs/tutorials/wiki/distributing.rst b/docs/tutorials/wiki/distributing.rst
index 386b880e6..fb0a552e0 100644
--- a/docs/tutorials/wiki/distributing.rst
+++ b/docs/tutorials/wiki/distributing.rst
@@ -6,9 +6,8 @@ Distributing Your Application
Once your application works properly, you can create a "tarball" from it by
using the ``setup.py sdist`` command. The following commands assume your
-current working directory is the ``tutorial`` package we've created and that
-the parent directory of the ``tutorial`` package is a virtual environment
-representing a :app:`Pyramid` environment.
+current working directory contains the ``tutorial`` package and the
+``setup.py`` file.
On UNIX:
@@ -20,7 +19,7 @@ On Windows:
.. code-block:: doscon
- c:\pyramidtut> %VENV%\Scripts\python setup.py sdist
+ c:\tutorial> %VENV%\Scripts\python setup.py sdist
The output of such a command will be something like:
@@ -35,7 +34,7 @@ The output of such a command will be something like:
Note that this command creates a tarball in the "dist" subdirectory named
``tutorial-0.0.tar.gz``. You can send this file to your friends to show them
your cool new application. They should be able to install it by pointing the
-``pip install .`` command directly at it. Or you can upload it to `PyPI
+``pip install`` command directly at it. Or you can upload it to `PyPI
<https://pypi.python.org/pypi>`_ and share it with the rest of the world, where
it can be downloaded via ``pip install`` remotely like any other package people
download from PyPI.
diff --git a/docs/tutorials/wiki/index.rst b/docs/tutorials/wiki/index.rst
index 7808c7623..7bd58656b 100644
--- a/docs/tutorials/wiki/index.rst
+++ b/docs/tutorials/wiki/index.rst
@@ -5,13 +5,12 @@ ZODB + Traversal Wiki Tutorial
This tutorial introduces a :term:`ZODB` and :term:`traversal`-based
:app:`Pyramid` application to a developer familiar with Python. It will be
-most familiar to developers with previous :term:`Zope` experience. When the
-is finished, the developer will have created a basic Wiki application with
+most familiar to developers with previous :term:`Zope` experience. When
+finished, the developer will have created a basic Wiki application with
authentication.
For cut and paste purposes, the source code for all stages of this
-tutorial can be browsed on GitHub at `docs/tutorials/wiki/src
-<https://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki/src>`_,
+tutorial can be browsed on GitHub at `GitHub <https://github.com/Pylons/pyramid/>`_ for a specific branch or version under ``docs/tutorials/wiki/src``,
which corresponds to the same location if you have Pyramid sources.
.. toctree::
diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst
index 6172b122b..de057b1cc 100644
--- a/docs/tutorials/wiki/installation.rst
+++ b/docs/tutorials/wiki/installation.rst
@@ -15,159 +15,125 @@ install Pyramid**. Thereby you will satisfy the following requirements.
* You've satisfied the :ref:`requirements-for-installing-packages`.
-Create directory to contain the project
----------------------------------------
-
-We need a workspace for our project files.
-
-On UNIX
-^^^^^^^
-
-.. code-block:: bash
+Install cookiecutter
+--------------------
+We will use a :term:`cookiecutter` to create a Python package project from a Python package project template. See `Cookiecutter Installation <https://cookiecutter.readthedocs.io/en/latest/installation.html>`_ for instructions.
- $ mkdir ~/pyramidtut
-On Windows
-^^^^^^^^^^
-
-.. code-block:: doscon
-
- c:\> mkdir pyramidtut
-
-
-Create and use a virtual Python environment
--------------------------------------------
+Generate a Pyramid project from a cookiecutter
+----------------------------------------------
-Next let's create a virtual environment workspace for our project. We will use
-the ``VENV`` environment variable instead of the absolute path of the virtual
-environment.
+We will create a Pyramid project in your home directory for UNIX or at the root for Windows. It is assumed you know the path to where you installed ``cookiecutter``. Issue the following commands and override the defaults in the prompts as follows.
On UNIX
^^^^^^^
.. code-block:: bash
- $ export VENV=~/pyramidtut
- $ python3 -m venv $VENV
+ $ cd ~
+ $ cookiecutter https://github.com/Pylons/pyramid-cookiecutter-zodb
On Windows
^^^^^^^^^^
.. code-block:: doscon
- c:\> set VENV=c:\pyramidtut
+ c:\> cd \
+ c:\> cookiecutter https://github.com/Pylons/pyramid-cookiecutter-zodb
-Each version of Python uses different paths, so you will need to adjust the
-path to the command for your Python version.
+On all operating systems
+^^^^^^^^^^^^^^^^^^^^^^^^
+If prompted for the first item, accept the default ``yes`` by hitting return.
-Python 2.7:
-
-.. code-block:: doscon
-
- c:\> c:\Python27\Scripts\virtualenv %VENV%
-
-Python 3.5:
-
-.. code-block:: doscon
-
- c:\> c:\Python35\Scripts\python -m venv %VENV%
+.. code-block:: text
+ You've cloned ~/.cookiecutters/pyramid-cookiecutter-zodb before.
+ Is it okay to delete and re-clone it? [yes]: yes
+ project_name [Pyramid Scaffold]: myproj
+ repo_name [myproj]: tutorial
-Upgrade ``pip`` and ``setuptools`` in the virtual environment
--------------------------------------------------------------
+Change directory into your newly created project
+------------------------------------------------
On UNIX
^^^^^^^
.. code-block:: bash
- $ $VENV/bin/pip install --upgrade pip setuptools
+ $ cd tutorial
On Windows
^^^^^^^^^^
.. code-block:: doscon
- c:\> %VENV%\Scripts\pip install --upgrade pip setuptools
+ c:\> cd tutorial
-Install Pyramid into the virtual Python environment
----------------------------------------------------
+Set and use a ``VENV`` environment variable
+-------------------------------------------
+
+We will set the ``VENV`` environment variable to the absolute path of the virtual environment, and use it going forward.
On UNIX
^^^^^^^
-.. parsed-literal::
+.. code-block:: bash
- $ $VENV/bin/pip install "pyramid==\ |release|\ "
+ $ export VENV=~/tutorial
On Windows
^^^^^^^^^^
-.. parsed-literal::
-
- c:\\> %VENV%\\Scripts\\pip install "pyramid==\ |release|\ "
+.. code-block:: doscon
+ c:\tutorial> set VENV=c:\tutorial
-Change directory to your virtual Python environment
----------------------------------------------------
-Change directory to the ``pyramidtut`` directory, which is both your workspace
-and your virtual environment.
+Create a virtual environment
+----------------------------
On UNIX
^^^^^^^
.. code-block:: bash
- $ cd pyramidtut
+ $ python3 -m venv $VENV
On Windows
^^^^^^^^^^
-.. code-block:: doscon
+Each version of Python uses different paths, so you might need to adjust the path to the command for your Python version. Recent versions of the Python 3 installer for Windows now install a Python launcher.
- c:\> cd pyramidtut
+Python 2.7:
+.. code-block:: doscon
-.. _making_a_project:
+ c:\tutorial> c:\Python27\Scripts\virtualenv %VENV%
-Making a project
-----------------
+Python 3.6:
-Your next step is to create a project. For this tutorial, we will use
-the :term:`scaffold` named ``zodb``, which generates an application
-that uses :term:`ZODB` and :term:`traversal`.
+.. code-block:: doscon
-:app:`Pyramid` supplies a variety of scaffolds to generate sample projects. We
-will use ``pcreate``, a script that comes with Pyramid, to create our project
-using a scaffold.
+ c:\tutorial> python -m venv %VENV%
-By passing ``zodb`` into the ``pcreate`` command, the script creates the files
-needed to use ZODB. By passing in our application name ``tutorial``, the script
-inserts that application name into all the required files.
-The below instructions assume your current working directory is "pyramidtut".
+Upgrade packaging tools in the virtual environment
+--------------------------------------------------
On UNIX
^^^^^^^
.. code-block:: bash
- $ $VENV/bin/pcreate -s zodb tutorial
+ $ $VENV/bin/pip install --upgrade pip setuptools
On Windows
^^^^^^^^^^
.. code-block:: doscon
- c:\pyramidtut> %VENV%\Scripts\pcreate -s zodb tutorial
-
-.. note:: If you are using Windows, the ``zodb`` scaffold may not deal
- gracefully with installation into a location that contains spaces in the
- path. If you experience startup problems, try putting both the virtual
- environment and the project into directories that do not contain spaces in
- their paths.
+ c:\tutorial> %VENV%\Scripts\pip install --upgrade pip setuptools
.. _installing_project_in_dev_mode_zodb:
@@ -175,76 +141,51 @@ On Windows
Installing 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 ``pip install -e .``
-command. In order to do so, change directory to the ``tutorial`` directory that
-you created in :ref:`making_a_project`, and run the ``pip install -e .``
-command using the virtual environment Python interpreter.
+In order to do development on the project easily, you must "register" the project as a development egg in your workspace. We will install testing requirements at the same time. We do so with the following command.
On UNIX
^^^^^^^
.. code-block:: bash
- $ cd tutorial
- $ $VENV/bin/pip install -e .
+ $ $VENV/bin/pip install -e ".[testing]"
On Windows
^^^^^^^^^^
.. code-block:: doscon
- c:\pyramidtut> cd tutorial
- c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e .
-
-The console will show ``pip`` checking for packages and installing missing
-packages. Success executing this command will show a line like the following:
-
-.. code-block:: bash
+ c:\tutorial> %VENV%\Scripts\pip install -e ".[testing]"
- Successfully installed BTrees-4.2.0 Chameleon-2.24 Mako-1.0.4 \
- MarkupSafe-0.23 Pygments-2.1.3 ZConfig-3.1.0 ZEO-4.2.0b1 ZODB-4.2.0 \
- ZODB3-3.11.0 mock-2.0.0 pbr-1.8.1 persistent-4.1.1 pyramid-chameleon-0.3 \
- pyramid-debugtoolbar-2.4.2 pyramid-mako-1.0.2 pyramid-tm-0.12.1 \
- pyramid-zodbconn-0.7 six-1.10.0 transaction-1.4.4 tutorial waitress-0.8.10 \
- zc.lockfile-1.1.0 zdaemon-4.1.0 zodbpickle-0.6.0 zodburi-2.0
+On all operating systems
+^^^^^^^^^^^^^^^^^^^^^^^^
+The console will show ``pip`` checking for packages and installing missing packages. Success executing this command will show a line like the following:
-.. _install-testing-requirements-zodb:
+.. code-block:: bash
-Install testing requirements
-----------------------------
+ Successfully installed BTrees-4.3.1 Chameleon-3.0 Mako-1.0.6 \
+ MarkupSafe-0.23 PasteDeploy-1.5.2 Pygments-2.1.3 WebOb-1.6.3 \
+ WebTest-2.0.23 ZConfig-3.1.0 ZEO-5.0.4 ZODB-5.1.1 ZODB3-3.11.0 \
+ beautifulsoup4-4.5.1 coverage-4.2 mock-2.0.0 pbr-1.10.0 persistent-4.2.2 \
+ py-1.4.31 pyramid-1.7.3 pyramid-chameleon-0.3 pyramid-debugtoolbar-3.0.5 \
+ pyramid-mako-1.0.2 pyramid-tm-1.1.1 pyramid-zodbconn-0.7 pytest-3.0.5 \
+ pytest-cov-2.4.0 repoze.lru-0.6 six-1.10.0 transaction-2.0.3 \
+ translationstring-1.3 tutorial venusian-1.0 waitress-1.0.1 \
+ zc.lockfile-1.2.1 zdaemon-4.2.0 zodbpickle-0.6.0 zodburi-2.0 \
+ zope.deprecation-4.2.0 zope.interface-4.3.3
-In order to run tests, we need to install the testing requirements. This is
-done through our project's ``setup.py`` file, in the ``tests_require`` and
-``extras_require`` stanzas, and by issuing the command below for your
-operating system.
+Testing requirements are defined in our project's ``setup.py`` file, in the ``tests_require`` and ``extras_require`` stanzas.
.. literalinclude:: src/installation/setup.py
- :language: python
- :linenos:
- :lineno-start: 22
- :lines: 22-26
+ :language: python
+ :lineno-match:
+ :lines: 22-26
.. literalinclude:: src/installation/setup.py
- :language: python
- :linenos:
- :lineno-start: 45
- :lines: 45-47
-
-On UNIX
-^^^^^^^
-
-.. code-block:: bash
-
- $ $VENV/bin/pip install -e ".[testing]"
-
-On Windows
-^^^^^^^^^^
-
-.. code-block:: doscon
-
- c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e ".[testing]"
+ :language: python
+ :lineno-match:
+ :lines: 46-48
.. _running_tests:
@@ -269,7 +210,7 @@ On Windows
.. code-block:: doscon
- c:\pyramidtut\tutorial> %VENV%\Scripts\py.test -q
+ c:\tutorial> %VENV%\Scripts\py.test -q
For a successful test run, you should see output that ends like this:
@@ -284,7 +225,7 @@ Expose test coverage information
You can run the ``py.test`` command to see test coverage information. This
runs the tests in the same way that ``py.test`` does, but provides additional
-"coverage" information, exposing which lines of your project are covered by the
+:term:`coverage` information, exposing which lines of your project are covered by the
tests.
We've already installed the ``pytest-cov`` package into our virtual
@@ -302,41 +243,39 @@ On Windows
.. code-block:: doscon
- c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov \
- --cov-report=term-missing
+ c:\tutorial> %VENV%\Scripts\py.test --cov --cov-report=term-missing
If successful, you will see output something like this:
.. code-block:: bash
- ======================== test session starts ========================
- platform Python 3.5.1, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
- rootdir: /Users/stevepiercy/projects/pyramidtut/tutorial, inifile:
- plugins: cov-2.2.1
- collected 1 items
-
- tutorial/tests.py .
- ------------------ coverage: platform Python 3.5.1 ------------------
- Name Stmts Miss Cover Missing
- ----------------------------------------------------
- tutorial/__init__.py 12 7 42% 7-8, 14-18
- tutorial/models.py 10 6 40% 9-14
- tutorial/tests.py 12 0 100%
- tutorial/views.py 4 0 100%
- ----------------------------------------------------
- TOTAL 38 13 66%
-
- ===================== 1 passed in 0.31 seconds ======================
+ ======================== test session starts ========================
+ platform Python 3.6.0, pytest-3.0.5, py-1.4.31, pluggy-0.4.0
+ rootdir: /Users/stevepiercy/tutorial, inifile:
+ plugins: cov-2.4.0
+ collected 1 items
+
+ tutorial/tests.py .
+ ------------------ coverage: platform Python 3.6.0 ------------------
+ Name Stmts Miss Cover Missing
+ -------------------------------------------------------
+ tutorial/__init__.py 14 9 36% 7-8, 14-20
+ tutorial/models.py 10 6 40% 9-14
+ tutorial/views.py 4 0 100%
+ -------------------------------------------------------
+ TOTAL 28 15 46%
+
+ ===================== 1 passed in 0.31 seconds ======================
Our package doesn't quite have 100% test coverage.
-.. _test_and_coverage_scaffold_defaults_zodb:
+.. _test_and_coverage_cookiecutter_defaults_zodb:
-Test and coverage scaffold defaults
------------------------------------
+Test and coverage cookiecutter defaults
+---------------------------------------
-Scaffolds include configuration defaults for ``py.test`` and test coverage.
+Cookiecutters include configuration defaults for ``py.test`` and test coverage.
These configuration files are ``pytest.ini`` and ``.coveragerc``, located at
the root of your package. Without these defaults, we would need to specify the
path to the module on which we want to run tests and coverage.
@@ -353,11 +292,10 @@ On Windows
.. code-block:: doscon
- c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov=tutorial \
- --cov-report=term-missing tutorial\tests.py -q
+ c:\tutorial> %VENV%\Scripts\py.test --cov=tutorial tutorial\tests.py -q
py.test follows :ref:`conventions for Python test discovery
-<pytest:test discovery>`, and the configuration defaults from the scaffold
+<pytest:test discovery>`, and the configuration defaults from the cookiecutter
tell ``py.test`` where to find the module on which we want to run tests and
coverage.
@@ -370,7 +308,8 @@ coverage.
Start the application
---------------------
-Start the application.
+Start the application. See :ref:`what_is_this_pserve_thing` for more
+information on ``pserve``.
On UNIX
^^^^^^^
@@ -384,7 +323,7 @@ On Windows
.. code-block:: doscon
- c:\pyramidtut\tutorial> %VENV%\Scripts\pserve development.ini --reload
+ c:\tutorial> %VENV%\Scripts\pserve development.ini --reload
.. note::
@@ -395,9 +334,10 @@ If successful, you will see something like this on your console:
.. code-block:: text
- Starting subprocess with file monitor
- Starting server in PID 82349.
- serving on http://127.0.0.1:6543
+ Starting subprocess with file monitor
+ Starting server in PID 44078.
+ Serving on http://localhost:6543
+ Serving on http://localhost:6543
This means the server is ready to accept requests.
@@ -414,13 +354,13 @@ page. You can read more about the purpose of the icon at
application while you develop.
-Decisions the ``zodb`` scaffold has made for you
-------------------------------------------------
+Decisions the ``zodb`` cookiecutter has made for you
+----------------------------------------------------
-Creating a project using the ``zodb`` scaffold makes the following
+Creating a project using the ``zodb`` cookiecutter makes the following
assumptions:
-- You are willing to use :term:`ZODB` as persistent storage.
+- You are willing to use :term:`ZODB` for persistent storage.
- You are willing to use :term:`traversal` to map URLs to code.
diff --git a/docs/tutorials/wiki/src/authorization/.coveragerc b/docs/tutorials/wiki/src/authorization/.coveragerc
new file mode 100644
index 000000000..a1d87d03d
--- /dev/null
+++ b/docs/tutorials/wiki/src/authorization/.coveragerc
@@ -0,0 +1,3 @@
+[run]
+source = tutorial
+omit = tutorial/test*
diff --git a/docs/tutorials/wiki/src/authorization/CHANGES.txt b/docs/tutorials/wiki/src/authorization/CHANGES.txt
index 35a34f332..14b902fd1 100644
--- a/docs/tutorials/wiki/src/authorization/CHANGES.txt
+++ b/docs/tutorials/wiki/src/authorization/CHANGES.txt
@@ -1,4 +1,4 @@
0.0
---
-- Initial version
+- Initial version.
diff --git a/docs/tutorials/wiki/src/authorization/README.txt b/docs/tutorials/wiki/src/authorization/README.txt
index dcb3605b8..5ec53bf9d 100644
--- a/docs/tutorials/wiki/src/authorization/README.txt
+++ b/docs/tutorials/wiki/src/authorization/README.txt
@@ -1,12 +1,29 @@
-tutorial README
-==================
+myproj
+======
Getting Started
---------------
-- cd <directory containing this file>
+- Change directory into your newly created project.
-- $VENV/bin/pip install -e .
+ cd tutorial
-- $VENV/bin/pserve development.ini
+- Create a Python virtual environment.
+ python3 -m venv env
+
+- Upgrade packaging tools.
+
+ env/bin/pip install --upgrade pip setuptools wheel
+
+- Install the project in editable mode with its testing requirements.
+
+ env/bin/pip install -e ".[testing]"
+
+- Run your project's tests.
+
+ env/bin/pytest
+
+- Run your project.
+
+ env/bin/pserve development.ini
diff --git a/docs/tutorials/wiki/src/authorization/development.ini b/docs/tutorials/wiki/src/authorization/development.ini
index 6bf4b198e..74e7457d6 100644
--- a/docs/tutorials/wiki/src/authorization/development.ini
+++ b/docs/tutorials/wiki/src/authorization/development.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -13,10 +13,7 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_zodbconn
- pyramid_tm
-tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
# By default, the toolbar only appears for clients from IP addresses
@@ -29,12 +26,11 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
[server:main]
use = egg:waitress#main
-host = 127.0.0.1
-port = 6543
+listen = localhost:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki/src/authorization/production.ini b/docs/tutorials/wiki/src/authorization/production.ini
index 4e9892e7b..60b6fe253 100644
--- a/docs/tutorials/wiki/src/authorization/production.ini
+++ b/docs/tutorials/wiki/src/authorization/production.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -11,11 +11,7 @@ pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en
-pyramid.includes =
- pyramid_tm
- pyramid_zodbconn
-tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
###
@@ -24,12 +20,11 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = *:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki/src/authorization/pytest.ini b/docs/tutorials/wiki/src/authorization/pytest.ini
new file mode 100644
index 000000000..8b76bc410
--- /dev/null
+++ b/docs/tutorials/wiki/src/authorization/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = tutorial
+python_files = *.py
diff --git a/docs/tutorials/wiki/src/authorization/setup.py b/docs/tutorials/wiki/src/authorization/setup.py
index beeed75c9..4a9f041e3 100644
--- a/docs/tutorials/wiki/src/authorization/setup.py
+++ b/docs/tutorials/wiki/src/authorization/setup.py
@@ -18,37 +18,40 @@ requires = [
'ZODB3',
'waitress',
'docutils',
- ]
+ 'bcrypt',
+]
tests_require = [
'WebTest >= 1.3.1', # py3 compat
- 'pytest', # includes virtualenv
+ 'pytest',
'pytest-cov',
- ]
+]
-setup(name='tutorial',
- version='0.0',
- description='tutorial',
- long_description=README + '\n\n' + CHANGES,
- classifiers=[
- "Programming Language :: Python",
- "Framework :: Pyramid",
- "Topic :: Internet :: WWW/HTTP",
- "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
- ],
- author='',
- author_email='',
- url='',
- keywords='web pylons pyramid',
- packages=find_packages(),
- include_package_data=True,
- zip_safe=False,
- extras_require={
- 'testing': tests_require,
- },
- install_requires=requires,
- entry_points="""\
- [paste.app_factory]
- main = tutorial:main
- """,
- )
+setup(
+ name='tutorial',
+ version='0.0',
+ description='myproj',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ 'Programming Language :: Python',
+ 'Framework :: Pyramid',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
+ install_requires=requires,
+ entry_points={
+ 'paste.app_factory': [
+ 'main = tutorial:main',
+ ],
+ },
+)
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki/src/authorization/tutorial/__init__.py
index 39b94abd1..8af2ee5c0 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/authorization/tutorial/__init__.py
@@ -22,6 +22,8 @@ def main(global_config, **settings):
config.set_authentication_policy(authn_policy)
config.set_authorization_policy(authz_policy)
config.include('pyramid_chameleon')
+ config.include('pyramid_tm')
+ config.include('pyramid_zodbconn')
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/security.py b/docs/tutorials/wiki/src/authorization/tutorial/security.py
index d88c9c71f..cbb3acd5d 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/security.py
+++ b/docs/tutorials/wiki/src/authorization/tutorial/security.py
@@ -1,5 +1,18 @@
-USERS = {'editor':'editor',
- 'viewer':'viewer'}
+import bcrypt
+
+
+def hash_password(pw):
+ hashed_pw = bcrypt.hashpw(pw.encode('utf-8'), bcrypt.gensalt())
+ # return unicode instead of bytes because databases handle it better
+ return hashed_pw.decode('utf-8')
+
+def check_password(expected_hash, pw):
+ if expected_hash is not None:
+ return bcrypt.checkpw(pw.encode('utf-8'), expected_hash.encode('utf-8'))
+ return False
+
+USERS = {'editor': hash_password('editor'),
+ 'viewer': hash_password('viewer')}
GROUPS = {'editor':['group:editors']}
def groupfinder(userid, request):
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt
index 823fa8972..19adc5932 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt
+++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt
@@ -23,6 +23,7 @@
<script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
+
<body>
<div class="starter-template">
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt
index 4a938e9bb..02f7038fe 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt
+++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt
@@ -23,6 +23,7 @@
<script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
+
<body>
<div class="starter-template">
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt
deleted file mode 100644
index f8cbe2e2c..000000000
--- a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE html>
-<html lang="${request.locale_name}">
- <head>
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="description" content="pyramid web application">
- <meta name="author" content="Pylons Project">
- <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}">
-
- <title>ZODB Scaffold for The Pyramid Web Framework</title>
-
- <!-- Bootstrap core CSS -->
- <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
-
- <!-- Custom styles for this scaffold -->
- <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet">
-
- <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
- <!--[if lt IE 9]>
- <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
- <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
- <![endif]-->
- </head>
-
- <body>
-
- <div class="starter-template">
- <div class="container">
- <div class="row">
- <div class="col-md-2">
- <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework">
- </div>
- <div class="col-md-10">
- <div class="content">
- <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1>
- <p class="lead">Welcome to <span class="font-normal">${project}</span>, an&nbsp;application generated&nbsp;by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="links">
- <ul>
- <li class="current-version">Generated by v1.7</li>
- <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li>
- <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li>
- <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li>
- <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li>
- </ul>
- </div>
- </div>
- <div class="row">
- <div class="copyright">
- Copyright &copy; Pylons Project
- </div>
- </div>
- </div>
- </div>
-
-
- <!-- Bootstrap core JavaScript
- ================================================== -->
- <!-- Placed at the end of the document so the pages load faster -->
- <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script>
- <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script>
- </body>
-</html>
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt
index fa35d758d..17a715b50 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt
+++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt
@@ -23,6 +23,7 @@
<script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
+
<body>
<div class="starter-template">
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/tests.py b/docs/tutorials/wiki/src/authorization/tutorial/tests.py
index 40f3c47af..ca7a47279 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/tests.py
+++ b/docs/tutorials/wiki/src/authorization/tutorial/tests.py
@@ -14,4 +14,4 @@ class ViewTests(unittest.TestCase):
from .views import my_view
request = testing.DummyRequest()
info = my_view(request)
- self.assertEqual(info['project'], 'tutorial')
+ self.assertEqual(info['project'], 'myproj')
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/views.py b/docs/tutorials/wiki/src/authorization/tutorial/views.py
index c271d2cc1..ea2da01af 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/views.py
+++ b/docs/tutorials/wiki/src/authorization/tutorial/views.py
@@ -14,7 +14,7 @@ from pyramid.security import (
)
-from .security import USERS
+from .security import USERS, check_password
from .models import Page
# regular expression used to find WikiWords
@@ -43,7 +43,6 @@ def view_page(context, request):
content = publish_parts(context.data, writer_name='html')['html_body']
content = wikiwords.sub(check, content)
edit_url = request.resource_url(context, 'edit_page')
-
return dict(page=context, content=content, edit_url=edit_url,
logged_in=request.authenticated_userid)
@@ -63,7 +62,6 @@ def add_page(context, request):
page = Page('')
page.__name__ = pagename
page.__parent__ = context
-
return dict(page=page, save_url=save_url,
logged_in=request.authenticated_userid)
@@ -94,7 +92,7 @@ def login(request):
if 'form.submitted' in request.params:
login = request.params['login']
password = request.params['password']
- if USERS.get(login) == password:
+ if check_password(USERS.get(login), password):
headers = remember(request, login)
return HTTPFound(location=came_from,
headers=headers)
diff --git a/docs/tutorials/wiki/src/basiclayout/.coveragerc b/docs/tutorials/wiki/src/basiclayout/.coveragerc
new file mode 100644
index 000000000..a1d87d03d
--- /dev/null
+++ b/docs/tutorials/wiki/src/basiclayout/.coveragerc
@@ -0,0 +1,3 @@
+[run]
+source = tutorial
+omit = tutorial/test*
diff --git a/docs/tutorials/wiki/src/basiclayout/CHANGES.txt b/docs/tutorials/wiki/src/basiclayout/CHANGES.txt
index 35a34f332..14b902fd1 100644
--- a/docs/tutorials/wiki/src/basiclayout/CHANGES.txt
+++ b/docs/tutorials/wiki/src/basiclayout/CHANGES.txt
@@ -1,4 +1,4 @@
0.0
---
-- Initial version
+- Initial version.
diff --git a/docs/tutorials/wiki/src/basiclayout/README.txt b/docs/tutorials/wiki/src/basiclayout/README.txt
index dcb3605b8..5ec53bf9d 100644
--- a/docs/tutorials/wiki/src/basiclayout/README.txt
+++ b/docs/tutorials/wiki/src/basiclayout/README.txt
@@ -1,12 +1,29 @@
-tutorial README
-==================
+myproj
+======
Getting Started
---------------
-- cd <directory containing this file>
+- Change directory into your newly created project.
-- $VENV/bin/pip install -e .
+ cd tutorial
-- $VENV/bin/pserve development.ini
+- Create a Python virtual environment.
+ python3 -m venv env
+
+- Upgrade packaging tools.
+
+ env/bin/pip install --upgrade pip setuptools wheel
+
+- Install the project in editable mode with its testing requirements.
+
+ env/bin/pip install -e ".[testing]"
+
+- Run your project's tests.
+
+ env/bin/pytest
+
+- Run your project.
+
+ env/bin/pserve development.ini
diff --git a/docs/tutorials/wiki/src/basiclayout/development.ini b/docs/tutorials/wiki/src/basiclayout/development.ini
index 6bf4b198e..74e7457d6 100644
--- a/docs/tutorials/wiki/src/basiclayout/development.ini
+++ b/docs/tutorials/wiki/src/basiclayout/development.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -13,10 +13,7 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_zodbconn
- pyramid_tm
-tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
# By default, the toolbar only appears for clients from IP addresses
@@ -29,12 +26,11 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
[server:main]
use = egg:waitress#main
-host = 127.0.0.1
-port = 6543
+listen = localhost:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki/src/basiclayout/production.ini b/docs/tutorials/wiki/src/basiclayout/production.ini
index 4e9892e7b..60b6fe253 100644
--- a/docs/tutorials/wiki/src/basiclayout/production.ini
+++ b/docs/tutorials/wiki/src/basiclayout/production.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -11,11 +11,7 @@ pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en
-pyramid.includes =
- pyramid_tm
- pyramid_zodbconn
-tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
###
@@ -24,12 +20,11 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = *:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki/src/basiclayout/pytest.ini b/docs/tutorials/wiki/src/basiclayout/pytest.ini
new file mode 100644
index 000000000..8b76bc410
--- /dev/null
+++ b/docs/tutorials/wiki/src/basiclayout/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = tutorial
+python_files = *.py
diff --git a/docs/tutorials/wiki/src/basiclayout/setup.py b/docs/tutorials/wiki/src/basiclayout/setup.py
index 46b395568..5d1e9c7b5 100644
--- a/docs/tutorials/wiki/src/basiclayout/setup.py
+++ b/docs/tutorials/wiki/src/basiclayout/setup.py
@@ -17,37 +17,39 @@ requires = [
'transaction',
'ZODB3',
'waitress',
- ]
+]
tests_require = [
'WebTest >= 1.3.1', # py3 compat
- 'pytest', # includes virtualenv
+ 'pytest',
'pytest-cov',
- ]
+]
-setup(name='tutorial',
- version='0.0',
- description='tutorial',
- long_description=README + '\n\n' + CHANGES,
- classifiers=[
- "Programming Language :: Python",
- "Framework :: Pyramid",
- "Topic :: Internet :: WWW/HTTP",
- "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
- ],
- author='',
- author_email='',
- url='',
- keywords='web pylons pyramid',
- packages=find_packages(),
- include_package_data=True,
- zip_safe=False,
- extras_require={
- 'testing': tests_require,
- },
- install_requires=requires,
- entry_points="""\
- [paste.app_factory]
- main = tutorial:main
- """,
- )
+setup(
+ name='tutorial',
+ version='0.0',
+ description='myproj',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ 'Programming Language :: Python',
+ 'Framework :: Pyramid',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
+ install_requires=requires,
+ entry_points={
+ 'paste.app_factory': [
+ 'main = tutorial:main',
+ ],
+ },
+)
diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py b/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py
index f2a86df47..728f7ac02 100644
--- a/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py
@@ -13,6 +13,8 @@ def main(global_config, **settings):
"""
config = Configurator(root_factory=root_factory, settings=settings)
config.include('pyramid_chameleon')
+ config.include('pyramid_tm')
+ config.include('pyramid_zodbconn')
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 f8cbe2e2c..3ac122711 100644
--- a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt
@@ -8,7 +8,7 @@
<meta name="author" content="Pylons Project">
<link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}">
- <title>ZODB Scaffold for The Pyramid Web Framework</title>
+ <title>Cookiecutter ZODB project for the Pyramid Web Framework</title>
<!-- Bootstrap core CSS -->
<link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
@@ -33,18 +33,16 @@
</div>
<div class="col-md-10">
<div class="content">
- <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1>
- <p class="lead">Welcome to <span class="font-normal">${project}</span>, an&nbsp;application generated&nbsp;by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p>
+ <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB Project</span></h1>
+ <p class="lead">Welcome to <span class="font-normal">${project}</span>, a&nbsp;Pyramid application generated&nbsp;by<br><span class="font-normal">Cookiecutter</span>.</p>
</div>
</div>
</div>
<div class="row">
<div class="links">
<ul>
- <li class="current-version">Generated by v1.7</li>
- <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li>
<li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li>
- <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li>
+ <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="https://webchat.freenode.net/?channels=pyramid">IRC Channel</a></li>
<li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li>
</ul>
</div>
diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/tests.py b/docs/tutorials/wiki/src/basiclayout/tutorial/tests.py
index 40f3c47af..ca7a47279 100644
--- a/docs/tutorials/wiki/src/basiclayout/tutorial/tests.py
+++ b/docs/tutorials/wiki/src/basiclayout/tutorial/tests.py
@@ -14,4 +14,4 @@ class ViewTests(unittest.TestCase):
from .views import my_view
request = testing.DummyRequest()
info = my_view(request)
- self.assertEqual(info['project'], 'tutorial')
+ self.assertEqual(info['project'], 'myproj')
diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/views.py b/docs/tutorials/wiki/src/basiclayout/tutorial/views.py
index 628ce15ed..c1878bdd0 100644
--- a/docs/tutorials/wiki/src/basiclayout/tutorial/views.py
+++ b/docs/tutorials/wiki/src/basiclayout/tutorial/views.py
@@ -4,4 +4,4 @@ from .models import MyModel
@view_config(context=MyModel, renderer='templates/mytemplate.pt')
def my_view(request):
- return {'project': 'tutorial'}
+ return {'project': 'myproj'}
diff --git a/docs/tutorials/wiki/src/installation/.coveragerc b/docs/tutorials/wiki/src/installation/.coveragerc
new file mode 100644
index 000000000..a1d87d03d
--- /dev/null
+++ b/docs/tutorials/wiki/src/installation/.coveragerc
@@ -0,0 +1,3 @@
+[run]
+source = tutorial
+omit = tutorial/test*
diff --git a/docs/tutorials/wiki/src/installation/CHANGES.txt b/docs/tutorials/wiki/src/installation/CHANGES.txt
index 35a34f332..14b902fd1 100644
--- a/docs/tutorials/wiki/src/installation/CHANGES.txt
+++ b/docs/tutorials/wiki/src/installation/CHANGES.txt
@@ -1,4 +1,4 @@
0.0
---
-- Initial version
+- Initial version.
diff --git a/docs/tutorials/wiki/src/installation/README.txt b/docs/tutorials/wiki/src/installation/README.txt
index dcb3605b8..5ec53bf9d 100644
--- a/docs/tutorials/wiki/src/installation/README.txt
+++ b/docs/tutorials/wiki/src/installation/README.txt
@@ -1,12 +1,29 @@
-tutorial README
-==================
+myproj
+======
Getting Started
---------------
-- cd <directory containing this file>
+- Change directory into your newly created project.
-- $VENV/bin/pip install -e .
+ cd tutorial
-- $VENV/bin/pserve development.ini
+- Create a Python virtual environment.
+ python3 -m venv env
+
+- Upgrade packaging tools.
+
+ env/bin/pip install --upgrade pip setuptools wheel
+
+- Install the project in editable mode with its testing requirements.
+
+ env/bin/pip install -e ".[testing]"
+
+- Run your project's tests.
+
+ env/bin/pytest
+
+- Run your project.
+
+ env/bin/pserve development.ini
diff --git a/docs/tutorials/wiki/src/installation/development.ini b/docs/tutorials/wiki/src/installation/development.ini
index 6bf4b198e..74e7457d6 100644
--- a/docs/tutorials/wiki/src/installation/development.ini
+++ b/docs/tutorials/wiki/src/installation/development.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -13,10 +13,7 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_zodbconn
- pyramid_tm
-tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
# By default, the toolbar only appears for clients from IP addresses
@@ -29,12 +26,11 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
[server:main]
use = egg:waitress#main
-host = 127.0.0.1
-port = 6543
+listen = localhost:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki/src/installation/production.ini b/docs/tutorials/wiki/src/installation/production.ini
index 4e9892e7b..60b6fe253 100644
--- a/docs/tutorials/wiki/src/installation/production.ini
+++ b/docs/tutorials/wiki/src/installation/production.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -11,11 +11,7 @@ pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en
-pyramid.includes =
- pyramid_tm
- pyramid_zodbconn
-tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
###
@@ -24,12 +20,11 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = *:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki/src/installation/pytest.ini b/docs/tutorials/wiki/src/installation/pytest.ini
new file mode 100644
index 000000000..8b76bc410
--- /dev/null
+++ b/docs/tutorials/wiki/src/installation/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = tutorial
+python_files = *.py
diff --git a/docs/tutorials/wiki/src/installation/setup.py b/docs/tutorials/wiki/src/installation/setup.py
index 46b395568..5d1e9c7b5 100644
--- a/docs/tutorials/wiki/src/installation/setup.py
+++ b/docs/tutorials/wiki/src/installation/setup.py
@@ -17,37 +17,39 @@ requires = [
'transaction',
'ZODB3',
'waitress',
- ]
+]
tests_require = [
'WebTest >= 1.3.1', # py3 compat
- 'pytest', # includes virtualenv
+ 'pytest',
'pytest-cov',
- ]
+]
-setup(name='tutorial',
- version='0.0',
- description='tutorial',
- long_description=README + '\n\n' + CHANGES,
- classifiers=[
- "Programming Language :: Python",
- "Framework :: Pyramid",
- "Topic :: Internet :: WWW/HTTP",
- "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
- ],
- author='',
- author_email='',
- url='',
- keywords='web pylons pyramid',
- packages=find_packages(),
- include_package_data=True,
- zip_safe=False,
- extras_require={
- 'testing': tests_require,
- },
- install_requires=requires,
- entry_points="""\
- [paste.app_factory]
- main = tutorial:main
- """,
- )
+setup(
+ name='tutorial',
+ version='0.0',
+ description='myproj',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ 'Programming Language :: Python',
+ 'Framework :: Pyramid',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
+ install_requires=requires,
+ entry_points={
+ 'paste.app_factory': [
+ 'main = tutorial:main',
+ ],
+ },
+)
diff --git a/docs/tutorials/wiki/src/installation/tutorial/__init__.py b/docs/tutorials/wiki/src/installation/tutorial/__init__.py
index f2a86df47..728f7ac02 100644
--- a/docs/tutorials/wiki/src/installation/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/installation/tutorial/__init__.py
@@ -13,6 +13,8 @@ def main(global_config, **settings):
"""
config = Configurator(root_factory=root_factory, settings=settings)
config.include('pyramid_chameleon')
+ config.include('pyramid_tm')
+ config.include('pyramid_zodbconn')
config.add_static_view('static', 'static', cache_max_age=3600)
config.scan()
return config.make_wsgi_app()
diff --git a/docs/tutorials/wiki/src/installation/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/installation/tutorial/templates/mytemplate.pt
index f8cbe2e2c..3ac122711 100644
--- a/docs/tutorials/wiki/src/installation/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/installation/tutorial/templates/mytemplate.pt
@@ -8,7 +8,7 @@
<meta name="author" content="Pylons Project">
<link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}">
- <title>ZODB Scaffold for The Pyramid Web Framework</title>
+ <title>Cookiecutter ZODB project for the Pyramid Web Framework</title>
<!-- Bootstrap core CSS -->
<link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
@@ -33,18 +33,16 @@
</div>
<div class="col-md-10">
<div class="content">
- <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1>
- <p class="lead">Welcome to <span class="font-normal">${project}</span>, an&nbsp;application generated&nbsp;by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p>
+ <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB Project</span></h1>
+ <p class="lead">Welcome to <span class="font-normal">${project}</span>, a&nbsp;Pyramid application generated&nbsp;by<br><span class="font-normal">Cookiecutter</span>.</p>
</div>
</div>
</div>
<div class="row">
<div class="links">
<ul>
- <li class="current-version">Generated by v1.7</li>
- <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li>
<li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li>
- <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li>
+ <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="https://webchat.freenode.net/?channels=pyramid">IRC Channel</a></li>
<li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li>
</ul>
</div>
diff --git a/docs/tutorials/wiki/src/installation/tutorial/tests.py b/docs/tutorials/wiki/src/installation/tutorial/tests.py
index 40f3c47af..ca7a47279 100644
--- a/docs/tutorials/wiki/src/installation/tutorial/tests.py
+++ b/docs/tutorials/wiki/src/installation/tutorial/tests.py
@@ -14,4 +14,4 @@ class ViewTests(unittest.TestCase):
from .views import my_view
request = testing.DummyRequest()
info = my_view(request)
- self.assertEqual(info['project'], 'tutorial')
+ self.assertEqual(info['project'], 'myproj')
diff --git a/docs/tutorials/wiki/src/installation/tutorial/views.py b/docs/tutorials/wiki/src/installation/tutorial/views.py
index 628ce15ed..c1878bdd0 100644
--- a/docs/tutorials/wiki/src/installation/tutorial/views.py
+++ b/docs/tutorials/wiki/src/installation/tutorial/views.py
@@ -4,4 +4,4 @@ from .models import MyModel
@view_config(context=MyModel, renderer='templates/mytemplate.pt')
def my_view(request):
- return {'project': 'tutorial'}
+ return {'project': 'myproj'}
diff --git a/docs/tutorials/wiki/src/models/.coveragerc b/docs/tutorials/wiki/src/models/.coveragerc
new file mode 100644
index 000000000..a1d87d03d
--- /dev/null
+++ b/docs/tutorials/wiki/src/models/.coveragerc
@@ -0,0 +1,3 @@
+[run]
+source = tutorial
+omit = tutorial/test*
diff --git a/docs/tutorials/wiki/src/models/CHANGES.txt b/docs/tutorials/wiki/src/models/CHANGES.txt
index 35a34f332..14b902fd1 100644
--- a/docs/tutorials/wiki/src/models/CHANGES.txt
+++ b/docs/tutorials/wiki/src/models/CHANGES.txt
@@ -1,4 +1,4 @@
0.0
---
-- Initial version
+- Initial version.
diff --git a/docs/tutorials/wiki/src/models/README.txt b/docs/tutorials/wiki/src/models/README.txt
index dcb3605b8..5ec53bf9d 100644
--- a/docs/tutorials/wiki/src/models/README.txt
+++ b/docs/tutorials/wiki/src/models/README.txt
@@ -1,12 +1,29 @@
-tutorial README
-==================
+myproj
+======
Getting Started
---------------
-- cd <directory containing this file>
+- Change directory into your newly created project.
-- $VENV/bin/pip install -e .
+ cd tutorial
-- $VENV/bin/pserve development.ini
+- Create a Python virtual environment.
+ python3 -m venv env
+
+- Upgrade packaging tools.
+
+ env/bin/pip install --upgrade pip setuptools wheel
+
+- Install the project in editable mode with its testing requirements.
+
+ env/bin/pip install -e ".[testing]"
+
+- Run your project's tests.
+
+ env/bin/pytest
+
+- Run your project.
+
+ env/bin/pserve development.ini
diff --git a/docs/tutorials/wiki/src/models/development.ini b/docs/tutorials/wiki/src/models/development.ini
index 6bf4b198e..74e7457d6 100644
--- a/docs/tutorials/wiki/src/models/development.ini
+++ b/docs/tutorials/wiki/src/models/development.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -13,10 +13,7 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_zodbconn
- pyramid_tm
-tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
# By default, the toolbar only appears for clients from IP addresses
@@ -29,12 +26,11 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
[server:main]
use = egg:waitress#main
-host = 127.0.0.1
-port = 6543
+listen = localhost:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki/src/models/production.ini b/docs/tutorials/wiki/src/models/production.ini
index 4e9892e7b..60b6fe253 100644
--- a/docs/tutorials/wiki/src/models/production.ini
+++ b/docs/tutorials/wiki/src/models/production.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -11,11 +11,7 @@ pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en
-pyramid.includes =
- pyramid_tm
- pyramid_zodbconn
-tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
###
@@ -24,12 +20,11 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = *:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki/src/models/pytest.ini b/docs/tutorials/wiki/src/models/pytest.ini
new file mode 100644
index 000000000..8b76bc410
--- /dev/null
+++ b/docs/tutorials/wiki/src/models/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = tutorial
+python_files = *.py
diff --git a/docs/tutorials/wiki/src/models/setup.py b/docs/tutorials/wiki/src/models/setup.py
index 46b395568..5d1e9c7b5 100644
--- a/docs/tutorials/wiki/src/models/setup.py
+++ b/docs/tutorials/wiki/src/models/setup.py
@@ -17,37 +17,39 @@ requires = [
'transaction',
'ZODB3',
'waitress',
- ]
+]
tests_require = [
'WebTest >= 1.3.1', # py3 compat
- 'pytest', # includes virtualenv
+ 'pytest',
'pytest-cov',
- ]
+]
-setup(name='tutorial',
- version='0.0',
- description='tutorial',
- long_description=README + '\n\n' + CHANGES,
- classifiers=[
- "Programming Language :: Python",
- "Framework :: Pyramid",
- "Topic :: Internet :: WWW/HTTP",
- "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
- ],
- author='',
- author_email='',
- url='',
- keywords='web pylons pyramid',
- packages=find_packages(),
- include_package_data=True,
- zip_safe=False,
- extras_require={
- 'testing': tests_require,
- },
- install_requires=requires,
- entry_points="""\
- [paste.app_factory]
- main = tutorial:main
- """,
- )
+setup(
+ name='tutorial',
+ version='0.0',
+ description='myproj',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ 'Programming Language :: Python',
+ 'Framework :: Pyramid',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
+ install_requires=requires,
+ entry_points={
+ 'paste.app_factory': [
+ 'main = tutorial:main',
+ ],
+ },
+)
diff --git a/docs/tutorials/wiki/src/models/tutorial/__init__.py b/docs/tutorials/wiki/src/models/tutorial/__init__.py
index f2a86df47..728f7ac02 100644
--- a/docs/tutorials/wiki/src/models/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/models/tutorial/__init__.py
@@ -13,6 +13,8 @@ def main(global_config, **settings):
"""
config = Configurator(root_factory=root_factory, settings=settings)
config.include('pyramid_chameleon')
+ config.include('pyramid_tm')
+ config.include('pyramid_zodbconn')
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 f8cbe2e2c..3ac122711 100644
--- a/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt
@@ -8,7 +8,7 @@
<meta name="author" content="Pylons Project">
<link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}">
- <title>ZODB Scaffold for The Pyramid Web Framework</title>
+ <title>Cookiecutter ZODB project for the Pyramid Web Framework</title>
<!-- Bootstrap core CSS -->
<link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
@@ -33,18 +33,16 @@
</div>
<div class="col-md-10">
<div class="content">
- <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1>
- <p class="lead">Welcome to <span class="font-normal">${project}</span>, an&nbsp;application generated&nbsp;by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p>
+ <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB Project</span></h1>
+ <p class="lead">Welcome to <span class="font-normal">${project}</span>, a&nbsp;Pyramid application generated&nbsp;by<br><span class="font-normal">Cookiecutter</span>.</p>
</div>
</div>
</div>
<div class="row">
<div class="links">
<ul>
- <li class="current-version">Generated by v1.7</li>
- <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li>
<li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li>
- <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li>
+ <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="https://webchat.freenode.net/?channels=pyramid">IRC Channel</a></li>
<li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li>
</ul>
</div>
diff --git a/docs/tutorials/wiki/src/models/tutorial/tests.py b/docs/tutorials/wiki/src/models/tutorial/tests.py
index 40f3c47af..ca7a47279 100644
--- a/docs/tutorials/wiki/src/models/tutorial/tests.py
+++ b/docs/tutorials/wiki/src/models/tutorial/tests.py
@@ -14,4 +14,4 @@ class ViewTests(unittest.TestCase):
from .views import my_view
request = testing.DummyRequest()
info = my_view(request)
- self.assertEqual(info['project'], 'tutorial')
+ self.assertEqual(info['project'], 'myproj')
diff --git a/docs/tutorials/wiki/src/models/tutorial/views.py b/docs/tutorials/wiki/src/models/tutorial/views.py
index 628ce15ed..c1878bdd0 100644
--- a/docs/tutorials/wiki/src/models/tutorial/views.py
+++ b/docs/tutorials/wiki/src/models/tutorial/views.py
@@ -4,4 +4,4 @@ from .models import MyModel
@view_config(context=MyModel, renderer='templates/mytemplate.pt')
def my_view(request):
- return {'project': 'tutorial'}
+ return {'project': 'myproj'}
diff --git a/docs/tutorials/wiki/src/tests/.coveragerc b/docs/tutorials/wiki/src/tests/.coveragerc
new file mode 100644
index 000000000..a1d87d03d
--- /dev/null
+++ b/docs/tutorials/wiki/src/tests/.coveragerc
@@ -0,0 +1,3 @@
+[run]
+source = tutorial
+omit = tutorial/test*
diff --git a/docs/tutorials/wiki/src/tests/CHANGES.txt b/docs/tutorials/wiki/src/tests/CHANGES.txt
index 35a34f332..14b902fd1 100644
--- a/docs/tutorials/wiki/src/tests/CHANGES.txt
+++ b/docs/tutorials/wiki/src/tests/CHANGES.txt
@@ -1,4 +1,4 @@
0.0
---
-- Initial version
+- Initial version.
diff --git a/docs/tutorials/wiki/src/tests/README.txt b/docs/tutorials/wiki/src/tests/README.txt
index dcb3605b8..5ec53bf9d 100644
--- a/docs/tutorials/wiki/src/tests/README.txt
+++ b/docs/tutorials/wiki/src/tests/README.txt
@@ -1,12 +1,29 @@
-tutorial README
-==================
+myproj
+======
Getting Started
---------------
-- cd <directory containing this file>
+- Change directory into your newly created project.
-- $VENV/bin/pip install -e .
+ cd tutorial
-- $VENV/bin/pserve development.ini
+- Create a Python virtual environment.
+ python3 -m venv env
+
+- Upgrade packaging tools.
+
+ env/bin/pip install --upgrade pip setuptools wheel
+
+- Install the project in editable mode with its testing requirements.
+
+ env/bin/pip install -e ".[testing]"
+
+- Run your project's tests.
+
+ env/bin/pytest
+
+- Run your project.
+
+ env/bin/pserve development.ini
diff --git a/docs/tutorials/wiki/src/tests/development.ini b/docs/tutorials/wiki/src/tests/development.ini
index 6bf4b198e..74e7457d6 100644
--- a/docs/tutorials/wiki/src/tests/development.ini
+++ b/docs/tutorials/wiki/src/tests/development.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -13,10 +13,7 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_zodbconn
- pyramid_tm
-tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
# By default, the toolbar only appears for clients from IP addresses
@@ -29,12 +26,11 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
[server:main]
use = egg:waitress#main
-host = 127.0.0.1
-port = 6543
+listen = localhost:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki/src/tests/production.ini b/docs/tutorials/wiki/src/tests/production.ini
index 4e9892e7b..60b6fe253 100644
--- a/docs/tutorials/wiki/src/tests/production.ini
+++ b/docs/tutorials/wiki/src/tests/production.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -11,11 +11,7 @@ pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en
-pyramid.includes =
- pyramid_tm
- pyramid_zodbconn
-tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
###
@@ -24,12 +20,11 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = *:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki/src/tests/pytest.ini b/docs/tutorials/wiki/src/tests/pytest.ini
new file mode 100644
index 000000000..8b76bc410
--- /dev/null
+++ b/docs/tutorials/wiki/src/tests/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = tutorial
+python_files = *.py
diff --git a/docs/tutorials/wiki/src/tests/setup.py b/docs/tutorials/wiki/src/tests/setup.py
index beeed75c9..4a9f041e3 100644
--- a/docs/tutorials/wiki/src/tests/setup.py
+++ b/docs/tutorials/wiki/src/tests/setup.py
@@ -18,37 +18,40 @@ requires = [
'ZODB3',
'waitress',
'docutils',
- ]
+ 'bcrypt',
+]
tests_require = [
'WebTest >= 1.3.1', # py3 compat
- 'pytest', # includes virtualenv
+ 'pytest',
'pytest-cov',
- ]
+]
-setup(name='tutorial',
- version='0.0',
- description='tutorial',
- long_description=README + '\n\n' + CHANGES,
- classifiers=[
- "Programming Language :: Python",
- "Framework :: Pyramid",
- "Topic :: Internet :: WWW/HTTP",
- "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
- ],
- author='',
- author_email='',
- url='',
- keywords='web pylons pyramid',
- packages=find_packages(),
- include_package_data=True,
- zip_safe=False,
- extras_require={
- 'testing': tests_require,
- },
- install_requires=requires,
- entry_points="""\
- [paste.app_factory]
- main = tutorial:main
- """,
- )
+setup(
+ name='tutorial',
+ version='0.0',
+ description='myproj',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ 'Programming Language :: Python',
+ 'Framework :: Pyramid',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
+ install_requires=requires,
+ entry_points={
+ 'paste.app_factory': [
+ 'main = tutorial:main',
+ ],
+ },
+)
diff --git a/docs/tutorials/wiki/src/tests/tutorial/__init__.py b/docs/tutorials/wiki/src/tests/tutorial/__init__.py
index 39b94abd1..8af2ee5c0 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/tests/tutorial/__init__.py
@@ -22,6 +22,8 @@ def main(global_config, **settings):
config.set_authentication_policy(authn_policy)
config.set_authorization_policy(authz_policy)
config.include('pyramid_chameleon')
+ config.include('pyramid_tm')
+ config.include('pyramid_zodbconn')
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/security.py b/docs/tutorials/wiki/src/tests/tutorial/security.py
index d88c9c71f..cbb3acd5d 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/security.py
+++ b/docs/tutorials/wiki/src/tests/tutorial/security.py
@@ -1,5 +1,18 @@
-USERS = {'editor':'editor',
- 'viewer':'viewer'}
+import bcrypt
+
+
+def hash_password(pw):
+ hashed_pw = bcrypt.hashpw(pw.encode('utf-8'), bcrypt.gensalt())
+ # return unicode instead of bytes because databases handle it better
+ return hashed_pw.decode('utf-8')
+
+def check_password(expected_hash, pw):
+ if expected_hash is not None:
+ return bcrypt.checkpw(pw.encode('utf-8'), expected_hash.encode('utf-8'))
+ return False
+
+USERS = {'editor': hash_password('editor'),
+ 'viewer': hash_password('viewer')}
GROUPS = {'editor':['group:editors']}
def groupfinder(userid, request):
diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt
index 823fa8972..19adc5932 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt
+++ b/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt
@@ -23,6 +23,7 @@
<script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
+
<body>
<div class="starter-template">
diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt
index 4a938e9bb..02f7038fe 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt
+++ b/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt
@@ -23,6 +23,7 @@
<script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
+
<body>
<div class="starter-template">
diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt
index fa35d758d..17a715b50 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt
+++ b/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt
@@ -23,6 +23,7 @@
<script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
+
<body>
<div class="starter-template">
diff --git a/docs/tutorials/wiki/src/tests/tutorial/tests.py b/docs/tutorials/wiki/src/tests/tutorial/tests.py
index 04beaea44..098e9c1bd 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/tests.py
+++ b/docs/tutorials/wiki/src/tests/tutorial/tests.py
@@ -122,6 +122,17 @@ class EditPageTests(unittest.TestCase):
self.assertEqual(response.location, 'http://example.com/')
self.assertEqual(context.data, 'Hello yo!')
+class SecurityTests(unittest.TestCase):
+ def test_hashing(self):
+ from .security import hash_password, check_password
+ password = 'secretpassword'
+ hashed_password = hash_password(password)
+ self.assertTrue(check_password(hashed_password, password))
+
+ self.assertFalse(check_password(hashed_password, 'attackerpassword'))
+
+ self.assertFalse(check_password(None, password))
+
class FunctionalTests(unittest.TestCase):
viewer_login = '/login?login=viewer&password=viewer' \
diff --git a/docs/tutorials/wiki/src/tests/tutorial/views.py b/docs/tutorials/wiki/src/tests/tutorial/views.py
index c271d2cc1..ea2da01af 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/views.py
+++ b/docs/tutorials/wiki/src/tests/tutorial/views.py
@@ -14,7 +14,7 @@ from pyramid.security import (
)
-from .security import USERS
+from .security import USERS, check_password
from .models import Page
# regular expression used to find WikiWords
@@ -43,7 +43,6 @@ def view_page(context, request):
content = publish_parts(context.data, writer_name='html')['html_body']
content = wikiwords.sub(check, content)
edit_url = request.resource_url(context, 'edit_page')
-
return dict(page=context, content=content, edit_url=edit_url,
logged_in=request.authenticated_userid)
@@ -63,7 +62,6 @@ def add_page(context, request):
page = Page('')
page.__name__ = pagename
page.__parent__ = context
-
return dict(page=page, save_url=save_url,
logged_in=request.authenticated_userid)
@@ -94,7 +92,7 @@ def login(request):
if 'form.submitted' in request.params:
login = request.params['login']
password = request.params['password']
- if USERS.get(login) == password:
+ if check_password(USERS.get(login), password):
headers = remember(request, login)
return HTTPFound(location=came_from,
headers=headers)
diff --git a/docs/tutorials/wiki/src/views/.coveragerc b/docs/tutorials/wiki/src/views/.coveragerc
new file mode 100644
index 000000000..a1d87d03d
--- /dev/null
+++ b/docs/tutorials/wiki/src/views/.coveragerc
@@ -0,0 +1,3 @@
+[run]
+source = tutorial
+omit = tutorial/test*
diff --git a/docs/tutorials/wiki/src/views/CHANGES.txt b/docs/tutorials/wiki/src/views/CHANGES.txt
index 35a34f332..14b902fd1 100644
--- a/docs/tutorials/wiki/src/views/CHANGES.txt
+++ b/docs/tutorials/wiki/src/views/CHANGES.txt
@@ -1,4 +1,4 @@
0.0
---
-- Initial version
+- Initial version.
diff --git a/docs/tutorials/wiki/src/views/README.txt b/docs/tutorials/wiki/src/views/README.txt
index dcb3605b8..5ec53bf9d 100644
--- a/docs/tutorials/wiki/src/views/README.txt
+++ b/docs/tutorials/wiki/src/views/README.txt
@@ -1,12 +1,29 @@
-tutorial README
-==================
+myproj
+======
Getting Started
---------------
-- cd <directory containing this file>
+- Change directory into your newly created project.
-- $VENV/bin/pip install -e .
+ cd tutorial
-- $VENV/bin/pserve development.ini
+- Create a Python virtual environment.
+ python3 -m venv env
+
+- Upgrade packaging tools.
+
+ env/bin/pip install --upgrade pip setuptools wheel
+
+- Install the project in editable mode with its testing requirements.
+
+ env/bin/pip install -e ".[testing]"
+
+- Run your project's tests.
+
+ env/bin/pytest
+
+- Run your project.
+
+ env/bin/pserve development.ini
diff --git a/docs/tutorials/wiki/src/views/development.ini b/docs/tutorials/wiki/src/views/development.ini
index 6bf4b198e..74e7457d6 100644
--- a/docs/tutorials/wiki/src/views/development.ini
+++ b/docs/tutorials/wiki/src/views/development.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -13,10 +13,7 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_zodbconn
- pyramid_tm
-tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
# By default, the toolbar only appears for clients from IP addresses
@@ -29,12 +26,11 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
[server:main]
use = egg:waitress#main
-host = 127.0.0.1
-port = 6543
+listen = localhost:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki/src/views/production.ini b/docs/tutorials/wiki/src/views/production.ini
index 4e9892e7b..60b6fe253 100644
--- a/docs/tutorials/wiki/src/views/production.ini
+++ b/docs/tutorials/wiki/src/views/production.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -11,11 +11,7 @@ pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en
-pyramid.includes =
- pyramid_tm
- pyramid_zodbconn
-tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
###
@@ -24,12 +20,11 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = *:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
diff --git a/docs/tutorials/wiki/src/views/pytest.ini b/docs/tutorials/wiki/src/views/pytest.ini
new file mode 100644
index 000000000..8b76bc410
--- /dev/null
+++ b/docs/tutorials/wiki/src/views/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = tutorial
+python_files = *.py
diff --git a/docs/tutorials/wiki/src/views/setup.py b/docs/tutorials/wiki/src/views/setup.py
index beeed75c9..598ad8146 100644
--- a/docs/tutorials/wiki/src/views/setup.py
+++ b/docs/tutorials/wiki/src/views/setup.py
@@ -18,37 +18,39 @@ requires = [
'ZODB3',
'waitress',
'docutils',
- ]
+]
tests_require = [
'WebTest >= 1.3.1', # py3 compat
- 'pytest', # includes virtualenv
+ 'pytest',
'pytest-cov',
- ]
+]
-setup(name='tutorial',
- version='0.0',
- description='tutorial',
- long_description=README + '\n\n' + CHANGES,
- classifiers=[
- "Programming Language :: Python",
- "Framework :: Pyramid",
- "Topic :: Internet :: WWW/HTTP",
- "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
- ],
- author='',
- author_email='',
- url='',
- keywords='web pylons pyramid',
- packages=find_packages(),
- include_package_data=True,
- zip_safe=False,
- extras_require={
- 'testing': tests_require,
- },
- install_requires=requires,
- entry_points="""\
- [paste.app_factory]
- main = tutorial:main
- """,
- )
+setup(
+ name='tutorial',
+ version='0.0',
+ description='myproj',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ 'Programming Language :: Python',
+ 'Framework :: Pyramid',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
+ install_requires=requires,
+ entry_points={
+ 'paste.app_factory': [
+ 'main = tutorial:main',
+ ],
+ },
+)
diff --git a/docs/tutorials/wiki/src/views/tutorial/__init__.py b/docs/tutorials/wiki/src/views/tutorial/__init__.py
index f2a86df47..728f7ac02 100644
--- a/docs/tutorials/wiki/src/views/tutorial/__init__.py
+++ b/docs/tutorials/wiki/src/views/tutorial/__init__.py
@@ -13,6 +13,8 @@ def main(global_config, **settings):
"""
config = Configurator(root_factory=root_factory, settings=settings)
config.include('pyramid_chameleon')
+ config.include('pyramid_tm')
+ config.include('pyramid_zodbconn')
config.add_static_view('static', 'static', cache_max_age=3600)
config.scan()
return config.make_wsgi_app()
diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt
deleted file mode 100644
index f8cbe2e2c..000000000
--- a/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE html>
-<html lang="${request.locale_name}">
- <head>
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="description" content="pyramid web application">
- <meta name="author" content="Pylons Project">
- <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}">
-
- <title>ZODB Scaffold for The Pyramid Web Framework</title>
-
- <!-- Bootstrap core CSS -->
- <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
-
- <!-- Custom styles for this scaffold -->
- <link href="${request.static_url('tutorial:static/theme.css')}" rel="stylesheet">
-
- <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
- <!--[if lt IE 9]>
- <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
- <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
- <![endif]-->
- </head>
-
- <body>
-
- <div class="starter-template">
- <div class="container">
- <div class="row">
- <div class="col-md-2">
- <img class="logo img-responsive" src="${request.static_url('tutorial:static/pyramid.png')}" alt="pyramid web framework">
- </div>
- <div class="col-md-10">
- <div class="content">
- <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1>
- <p class="lead">Welcome to <span class="font-normal">${project}</span>, an&nbsp;application generated&nbsp;by<br>the <span class="font-normal">Pyramid Web Framework 1.7</span>.</p>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="links">
- <ul>
- <li class="current-version">Generated by v1.7</li>
- <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/">Docs</a></li>
- <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li>
- <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li>
- <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li>
- </ul>
- </div>
- </div>
- <div class="row">
- <div class="copyright">
- Copyright &copy; Pylons Project
- </div>
- </div>
- </div>
- </div>
-
-
- <!-- Bootstrap core JavaScript
- ================================================== -->
- <!-- Placed at the end of the document so the pages load faster -->
- <script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script>
- <script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script>
- </body>
-</html>
diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/view.pt b/docs/tutorials/wiki/src/views/tutorial/templates/view.pt
index 93580658b..5caaef4af 100644
--- a/docs/tutorials/wiki/src/views/tutorial/templates/view.pt
+++ b/docs/tutorials/wiki/src/views/tutorial/templates/view.pt
@@ -23,6 +23,7 @@
<script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
+
<body>
<div class="starter-template">
diff --git a/docs/tutorials/wiki/src/views/tutorial/tests.py b/docs/tutorials/wiki/src/views/tutorial/tests.py
index 40f3c47af..ca7a47279 100644
--- a/docs/tutorials/wiki/src/views/tutorial/tests.py
+++ b/docs/tutorials/wiki/src/views/tutorial/tests.py
@@ -14,4 +14,4 @@ class ViewTests(unittest.TestCase):
from .views import my_view
request = testing.DummyRequest()
info = my_view(request)
- self.assertEqual(info['project'], 'tutorial')
+ self.assertEqual(info['project'], 'myproj')
diff --git a/docs/tutorials/wiki/src/views/tutorial/views.py b/docs/tutorials/wiki/src/views/tutorial/views.py
index 61517c31d..fd2b0edc1 100644
--- a/docs/tutorials/wiki/src/views/tutorial/views.py
+++ b/docs/tutorials/wiki/src/views/tutorial/views.py
@@ -24,13 +24,13 @@ def view_page(context, request):
view_url = request.resource_url(page)
return '<a href="%s">%s</a>' % (view_url, word)
else:
- add_url = request.application_url + '/add_page/' + word
+ add_url = request.application_url + '/add_page/' + word
return '<a href="%s">%s</a>' % (add_url, word)
content = publish_parts(context.data, writer_name='html')['html_body']
content = wikiwords.sub(check, content)
edit_url = request.resource_url(context, 'edit_page')
- return dict(page = context, content = content, edit_url = edit_url)
+ return dict(page=context, content=content, edit_url=edit_url)
@view_config(name='add_page', context='.models.Wiki',
renderer='templates/edit.pt')
@@ -42,19 +42,19 @@ def add_page(context, request):
page.__name__ = pagename
page.__parent__ = context
context[pagename] = page
- return HTTPFound(location = request.resource_url(page))
+ return HTTPFound(location=request.resource_url(page))
save_url = request.resource_url(context, 'add_page', pagename)
page = Page('')
page.__name__ = pagename
page.__parent__ = context
- return dict(page = page, save_url = save_url)
+ return dict(page=page, save_url=save_url)
@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']
- return HTTPFound(location = request.resource_url(context))
+ return HTTPFound(location=request.resource_url(context))
return dict(page=context,
- save_url=request.resource_url(context, 'edit_page'))
+ save_url=request.resource_url(context, 'edit_page')) \ No newline at end of file
diff --git a/docs/tutorials/wiki/tests.rst b/docs/tutorials/wiki/tests.rst
index 85a023cc9..cd82c0118 100644
--- a/docs/tutorials/wiki/tests.rst
+++ b/docs/tutorials/wiki/tests.rst
@@ -16,7 +16,7 @@ We write tests for the ``model`` classes and the ``appmaker``. Changing
we'll write a test class for the ``appmaker``.
To do so, we'll retain the ``tutorial.tests.ViewTests`` class that was
-generated as part of the ``zodb`` scaffold. We'll add three test classes: one
+generated as part of the ``zodb`` cookiecutter. 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``.
@@ -24,8 +24,8 @@ Test the views
==============
We'll modify our ``tests.py`` file, adding tests for each view function we
-added previously. As a result, we'll *delete* the ``ViewTests`` class that
-the ``zodb`` scaffold provided, and add four other test classes:
+added previously. As a result, we'll delete the ``ViewTests`` class that
+the ``zodb`` cookiecutter provided, and add four other test classes:
``ViewWikiTests``, ``ViewPageTests``, ``AddPageTests``, and ``EditPageTests``.
These test the ``view_wiki``, ``view_page``, ``add_page``, and ``edit_page``
views.
@@ -52,25 +52,25 @@ Running the tests
=================
We can run these tests by using ``py.test`` similarly to how we did in
-:ref:`running_tests`. Courtesy of the scaffold, our testing dependencies have
+:ref:`running_tests`. Courtesy of the cookiecutter, our testing dependencies have
already been satisfied and ``py.test`` and coverage have already been
configured, so we can jump right to running tests.
On UNIX:
-.. code-block:: text
+.. code-block:: bash
$ $VENV/bin/py.test -q
On Windows:
-.. code-block:: text
+.. code-block:: doscon
- c:\pyramidtut\tutorial> %VENV%\Scripts\py.test -q
+ c:\tutorial> %VENV%\Scripts\py.test -q
The expected result should look like the following:
.. code-block:: text
- ........................
- 24 passed in 2.46 seconds
+ .........................
+ 25 passed in 6.87 seconds