From ee9676a8691dd18b88d3247fd8c1306c5aaa1543 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 24 May 2015 19:15:22 -0700 Subject: - make templates html5 compliant - punctuation, grammar, spelling - fix linenos references - update outputs --- docs/tutorials/wiki2/basiclayout.rst | 10 +-- docs/tutorials/wiki2/definingmodels.rst | 61 ++++++++-------- docs/tutorials/wiki2/definingviews.rst | 46 ++++++------ docs/tutorials/wiki2/design.rst | 4 +- docs/tutorials/wiki2/installation.rst | 85 +++++++++++----------- .../wiki2/src/views/tutorial/templates/edit.pt | 28 ++++--- .../wiki2/src/views/tutorial/templates/view.pt | 24 +++--- docs/tutorials/wiki2/src/views/tutorial/views.py | 1 + 8 files changed, 129 insertions(+), 130 deletions(-) (limited to 'docs/tutorials/wiki2') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 05781c044..90157aa9e 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -4,7 +4,7 @@ Basic Layout The starter files generated by the ``alchemy`` scaffold are very basic, but they provide a good orientation for the high-level patterns common to most -:term:`url dispatch` -based :app:`Pyramid` projects. +:term:`URL dispatch`-based :app:`Pyramid` projects. Application Configuration with ``__init__.py`` @@ -12,7 +12,7 @@ Application Configuration with ``__init__.py`` A directory on disk can be turned into a Python :term:`package` by containing an ``__init__.py`` file. Even if empty, this marks a directory as a Python -package. We use ``__init__.py`` both as a marker indicating the directory +package. We use ``__init__.py``, both as a marker indicating the directory it's contained within is a package, and to contain configuration code. Open ``tutorial/tutorial/__init__.py``. It should already contain @@ -114,7 +114,7 @@ used when the URL is ``/``: :lines: 19 :language: py -Since this route has a ``pattern`` equalling ``/`` it is the route that will +Since this route has a ``pattern`` equaling ``/`` it is the route that will be matched when the URL ``/`` is visited, e.g. ``http://localhost:6543/``. ``main`` next calls the ``scan`` method of the configurator @@ -167,7 +167,7 @@ Note that ``my_view()`` accepts a single argument named ``request``. This is the standard call signature for a Pyramid :term:`view callable`. Remember in our ``__init__.py`` when we executed the -:meth:`pyramid.config.Configurator.scan` method, i.e. ``config.scan()``? The +:meth:`pyramid.config.Configurator.scan` method ``config.scan()``? The purpose of calling the scan method was to find and process this ``@view_config`` decorator in order to create a view configuration within our application. Without being processed by ``scan``, the decorator effectively @@ -175,7 +175,7 @@ does nothing. ``@view_config`` is inert without being detected via a :term:`scan`. The sample ``my_view()`` created by the scaffold uses a ``try:`` and ``except:`` -clause, to detect if there is a problem accessing the project database and +clause to detect if there is a problem accessing the project database and provide an alternate error response. That response will include the text shown at the end of the file, which will be displayed in the browser to inform the user about possible actions to take to solve the problem. diff --git a/docs/tutorials/wiki2/definingmodels.rst b/docs/tutorials/wiki2/definingmodels.rst index e30af12b2..3ce3a7992 100644 --- a/docs/tutorials/wiki2/definingmodels.rst +++ b/docs/tutorials/wiki2/definingmodels.rst @@ -24,9 +24,10 @@ following: .. literalinclude:: src/models/tutorial/models.py :linenos: :language: py - :emphasize-lines: 20-22,25 + :emphasize-lines: 20-22,24,25 -(The highlighted lines are the ones that need to be changed.) +The highlighted lines are the ones that need to be changed, as well as +removing lines that reference ``Index``. The first thing we've done is remove the stock ``MyModel`` class from the generated ``models.py`` file. The ``MyModel`` class is only a @@ -57,8 +58,8 @@ Changing ``scripts/initializedb.py`` We haven't looked at the details of this file yet, but within the ``scripts`` directory of your ``tutorial`` package is a file named ``initializedb.py``. Code -in this file is executed whenever we run the ``initialize_tutorial_db`` command -(as we did in the installation step of this tutorial). +in this file is executed whenever we run the ``initialize_tutorial_db`` command, +as we did in the installation step of this tutorial. Since we've changed our model, we need to make changes to our ``initializedb.py`` script. In particular, we'll replace our import of ``MyModel`` with one of @@ -71,9 +72,11 @@ following: .. literalinclude:: src/models/tutorial/scripts/initializedb.py :linenos: :language: python - :emphasize-lines: 14,36 + :emphasize-lines: 14,31,36 -(Only the highlighted lines need to be changed.) +Only the highlighted lines need to be changed, as well as removing the lines +referencing ``pyramid.scripts.common`` and ``options`` under the ``main`` +function. Installing the Project and re-initializing the Database ------------------------------------------------------- @@ -85,30 +88,28 @@ See :ref:`initialize_db_wiki2` for instructions. Success will look something like this:: - 2011-11-27 01:22:45,277 INFO [sqlalchemy.engine.base.Engine][MainThread] - PRAGMA table_info("pages") - 2011-11-27 01:22:45,277 INFO [sqlalchemy.engine.base.Engine][MainThread] () - 2011-11-27 01:22:45,277 INFO [sqlalchemy.engine.base.Engine][MainThread] - CREATE TABLE pages ( - id INTEGER NOT NULL, - name TEXT, - data TEXT, - PRIMARY KEY (id), - UNIQUE (name) - ) - - - 2011-11-27 01:22:45,278 INFO [sqlalchemy.engine.base.Engine][MainThread] () - 2011-11-27 01:22:45,397 INFO [sqlalchemy.engine.base.Engine][MainThread] - COMMIT - 2011-11-27 01:22:45,400 INFO [sqlalchemy.engine.base.Engine][MainThread] - BEGIN (implicit) - 2011-11-27 01:22:45,401 INFO [sqlalchemy.engine.base.Engine][MainThread] - INSERT INTO pages (name, data) VALUES (?, ?) - 2011-11-27 01:22:45,401 INFO [sqlalchemy.engine.base.Engine][MainThread] - ('FrontPage', 'This is the front page') - 2011-11-27 01:22:45,402 INFO [sqlalchemy.engine.base.Engine][MainThread] - COMMIT + 2015-05-24 15:34:14,542 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 + 2015-05-24 15:34:14,542 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () + 2015-05-24 15:34:14,543 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 + 2015-05-24 15:34:14,543 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () + 2015-05-24 15:34:14,543 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("pages") + 2015-05-24 15:34:14,544 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2015-05-24 15:34:14,544 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] + CREATE TABLE pages ( + id INTEGER NOT NULL, + name TEXT, + data INTEGER, + PRIMARY KEY (id), + UNIQUE (name) + ) + + + 2015-05-24 15:34:14,545 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2015-05-24 15:34:14,546 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + 2015-05-24 15:34:14,548 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit) + 2015-05-24 15:34:14,549 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO pages (name, data) VALUES (?, ?) + 2015-05-24 15:34:14,549 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('FrontPage', 'This is the front page') + 2015-05-24 15:34:14,550 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT Viewing the Application in a Browser ------------------------------------ diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst index 49dbed50f..dd1cb491d 100644 --- a/docs/tutorials/wiki2/definingviews.rst +++ b/docs/tutorials/wiki2/definingviews.rst @@ -11,8 +11,8 @@ The request object has a dictionary as an attribute named ``matchdict``. A substrings of the path in the :term:`request` URL. For instance, if a call to :meth:`pyramid.config.Configurator.add_route` has the pattern ``/{one}/{two}``, and a user visits ``http://example.com/foo/bar``, our pattern would be matched -against ``/foo/bar`` and the ``matchdict`` would look like: ``{'one':'foo', -'two':'bar'}`` +against ``/foo/bar`` and the ``matchdict`` would look like ``{'one':'foo', +'two':'bar'}``. Declaring Dependencies in Our ``setup.py`` File =============================================== @@ -32,7 +32,7 @@ Open ``tutorial/setup.py`` and edit it to look like the following: :language: python :emphasize-lines: 20 -(Only the highlighted line needs to be added.) +Only the highlighted line needs to be added. Running ``setup.py develop`` ============================ @@ -71,9 +71,9 @@ It's time for a major change. Open ``tutorial/tutorial/views.py`` and edit it t .. literalinclude:: src/views/tutorial/views.py :linenos: :language: python - :emphasize-lines: 1-7,12,15-70 + :emphasize-lines: 1-7,14,16-72 -(The highlighted lines are the ones that need to be added or edited.) +The highlighted lines are the ones that need to be added or edited. We got rid of the ``my_view`` view function and its decorator that was added when we originally rendered the ``alchemy`` scaffold. It was only an @@ -93,7 +93,7 @@ afterward. .. note:: There is nothing special about the filename ``views.py``. A project may - have many view callables throughout its codebase in arbitrarily-named + have many view callables throughout its codebase in arbitrarily named files. Files implementing view callables often have ``view`` in their filenames (or may live in a Python subpackage of your application package named ``views``), but this is only by convention. @@ -106,7 +106,7 @@ is made to the root URL of our wiki. It always redirects to a URL which represents the path to our "FrontPage". .. literalinclude:: src/views/tutorial/views.py - :lines: 18-21 + :lines: 20-23 :linenos: :language: python @@ -116,8 +116,8 @@ the :class:`pyramid.interfaces.IResponse` interface like :class:`pyramid.response.Response` does). It uses the :meth:`pyramid.request.Request.route_url` API to construct a -URL to the ``FrontPage`` page (e.g. ``http://localhost:6543/FrontPage``), which -is used as the "location" of the ``HTTPFound`` response, forming an HTTP redirect. +URL to the ``FrontPage`` page (e.g., ``http://localhost:6543/FrontPage``), which +is used as the location of the ``HTTPFound`` response, forming an HTTP redirect. The ``view_page`` view function ------------------------------- @@ -165,25 +165,25 @@ request passed to the ``add_page()`` view will have the values we need to construct URLs and find model objects. .. literalinclude:: src/views/tutorial/views.py - :lines: 45-56 + :lines: 47-58 :linenos: :language: python The ``matchdict`` will have a ``'pagename'`` key that matches the name of the page we'd like to add. If our add view is invoked via, -e.g. ``http://localhost:6543/add_page/SomeName``, the value for +e.g., ``http://localhost:6543/add_page/SomeName``, the value for ``'pagename'`` in the ``matchdict`` will be ``'SomeName'``. -If the view execution *is* a result of a form submission (i.e. the expression -``'form.submitted' in request.params`` is ``True``), we scrape the page body +If the view execution *is* a result of a form submission (i.e., the expression +``'form.submitted' in request.params`` is ``True``), we grab the page body from the form data, create a Page object with this page body and the name taken from ``matchdict['pagename']``, and save it into the database using ``DBSession.add``. We then redirect back to the ``view_page`` view for the newly created page. -If the view execution is *not* a result of a form submission (i.e. the +If the view execution is *not* a result of a form submission (i.e., the expression ``'form.submitted' in request.params`` is ``False``), the view -callable renders a template. To do so, it generates a "save url" which the +callable renders a template. To do so, it generates a ``save_url`` which the template uses as the form post URL during rendering. We're lazy here, so we're going to use the same template (``templates/edit.pt``) for the add view as well as the page edit view. To do so we create a dummy Page object @@ -201,17 +201,17 @@ request passed to the ``edit_page`` view will have a ``'pagename'`` key matching the name of the page the user wants to edit. .. literalinclude:: src/views/tutorial/views.py - :lines: 58-70 + :lines: 60-72 :linenos: :language: python -If the view execution *is* a result of a form submission (i.e. the expression +If the view execution *is* a result of a form submission (i.e., the expression ``'form.submitted' in request.params`` is ``True``), the view grabs the ``body`` element of the request parameters and sets it as the ``data`` attribute of the page object. It then redirects to the ``view_page`` view of the wiki page. -If the view execution is *not* a result of a form submission (i.e. the +If the view execution is *not* a result of a form submission (i.e., the expression ``'form.submitted' in request.params`` is ``False``), the view simply renders the edit form, passing the page object and a ``save_url`` which will be used as the action of the generated form. @@ -239,12 +239,12 @@ 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 (rows 45-47). ``content`` + value provided by the view (lines 43-45). ``content`` contains HTML, so the ``structure`` keyword is used - to prevent escaping it (i.e. changing ">" to ">", etc.) + to prevent escaping it (i.e., changing ">" to ">", etc.) - A link that points at the "edit" URL which invokes the ``edit_page`` view for - the page being viewed (rows 49-51). + the page being viewed (lines 47-49). The ``edit.pt`` Template ------------------------ @@ -254,7 +254,7 @@ content: .. literalinclude:: src/views/tutorial/templates/edit.pt :linenos: - :language: xml + :language: html This template is used by ``add_page()`` and ``edit_page()`` for adding and editing a wiki page. It displays @@ -265,7 +265,7 @@ a page containing a form that includes: - A submit button that has the name ``form.submitted`` (row 48). The form POSTs back to the "save_url" argument supplied -by the view (row 45). The view will use the ``body`` and +by the view (row 43). The view will use the ``body`` and ``form.submitted`` values. .. note:: Our templates use a ``request`` object that diff --git a/docs/tutorials/wiki2/design.rst b/docs/tutorials/wiki2/design.rst index ff7413668..fa291cdc0 100644 --- a/docs/tutorials/wiki2/design.rst +++ b/docs/tutorials/wiki2/design.rst @@ -124,7 +124,7 @@ listed in the following table: | | authenticate. | | | | | | | | | | | | - If authentication | | | | -| | successful, | | | | +| | succeeds, | | | | | | redirect to the | | | | | | page that we | | | | | | came from. | | | | @@ -144,6 +144,6 @@ listed in the following table: when there is no view name. .. [2] Pyramid will return a default 404 Not Found page if the page *PageName* does not exist yet. -.. [3] pyramid.exceptions.Forbidden is reached when a +.. [3] ``pyramid.exceptions.Forbidden`` is reached when a user tries to invoke a view that is not authorized by the authorization policy. diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index e21bf7108..9b0389feb 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -120,7 +120,7 @@ projects. We will use `pcreate`—a script that comes with Pyramid to quickly and easily generate scaffolds usually with a single command—to create the scaffold for our project. -By passing in `alchemy` into the `pcreate` command, the script creates +By passing `alchemy` into the `pcreate` command, the script creates the files needed to use SQLAlchemy. By passing in our application name `tutorial`, the script inserts that application name into all the required files. For example, `pcreate` creates the @@ -258,20 +258,19 @@ On Windows If successful, you will see output something like this:: - . - Name Stmts Miss Cover Missing - ------------------------------------------------ - tutorial 11 7 36% 9-15 - tutorial.models 17 0 100% - tutorial.scripts 0 0 100% - tutorial.tests 24 0 100% - tutorial.views 6 0 100% - ------------------------------------------------ - TOTAL 58 7 88% - ---------------------------------------------------------------------- - Ran 1 test in 0.459s + . + Name Stmts Miss Cover Missing + --------------------------------------------------- + tutorial.py 13 9 31% 13-21 + tutorial/models.py 12 0 100% + tutorial/scripts.py 0 0 100% + tutorial/views.py 11 0 100% + --------------------------------------------------- + TOTAL 36 9 75% + ---------------------------------------------------------------------- + Ran 2 tests in 0.643s - OK + OK Looks like our package doesn't quite have 100% test coverage. @@ -284,7 +283,7 @@ Initializing the Database We need to use the ``initialize_tutorial_db`` :term:`console script` to initialize our database. -Type the following command, make sure you are still in the ``tutorial`` +Type the following command, making sure you are still in the ``tutorial`` directory (the directory with a ``development.ini`` in it): On UNIX @@ -303,28 +302,30 @@ On Windows The output to your console should be something like this:: - 2011-11-26 14:42:25,012 INFO [sqlalchemy.engine.base.Engine][MainThread] - PRAGMA table_info("models") - 2011-11-26 14:42:25,013 INFO [sqlalchemy.engine.base.Engine][MainThread] () - 2011-11-26 14:42:25,013 INFO [sqlalchemy.engine.base.Engine][MainThread] - CREATE TABLE models ( - id INTEGER NOT NULL, - name VARCHAR(255), - value INTEGER, - PRIMARY KEY (id), - UNIQUE (name) - ) - 2011-11-26 14:42:25,013 INFO [sqlalchemy.engine.base.Engine][MainThread] () - 2011-11-26 14:42:25,135 INFO [sqlalchemy.engine.base.Engine][MainThread] - COMMIT - 2011-11-26 14:42:25,137 INFO [sqlalchemy.engine.base.Engine][MainThread] - BEGIN (implicit) - 2011-11-26 14:42:25,138 INFO [sqlalchemy.engine.base.Engine][MainThread] - INSERT INTO models (name, value) VALUES (?, ?) - 2011-11-26 14:42:25,139 INFO [sqlalchemy.engine.base.Engine][MainThread] - (u'one', 1) - 2011-11-26 14:42:25,140 INFO [sqlalchemy.engine.base.Engine][MainThread] - COMMIT + 2015-05-23 16:49:49,609 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 + 2015-05-23 16:49:49,609 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () + 2015-05-23 16:49:49,610 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 + 2015-05-23 16:49:49,610 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () + 2015-05-23 16:49:49,610 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("models") + 2015-05-23 16:49:49,610 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2015-05-23 16:49:49,612 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] + CREATE TABLE models ( + id INTEGER NOT NULL, + name TEXT, + value INTEGER, + PRIMARY KEY (id) + ) + + + 2015-05-23 16:49:49,612 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2015-05-23 16:49:49,613 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + 2015-05-23 16:49:49,613 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] CREATE UNIQUE INDEX my_index ON models (name) + 2015-05-23 16:49:49,613 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () + 2015-05-23 16:49:49,614 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + 2015-05-23 16:49:49,616 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit) + 2015-05-23 16:49:49,617 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO models (name, value) VALUES (?, ?) + 2015-05-23 16:49:49,617 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('one', 1) + 2015-05-23 16:49:49,618 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT Success! You should now have a ``tutorial.sqlite`` file in your current working directory. This will be a SQLite database with a single table defined in it @@ -367,7 +368,7 @@ page. You can read more about the purpose of the icon at :ref:`debug_toolbar`. It allows you to get information about your application while you develop. -Decisions the ``alchemy`` Scaffold Has Made For You +Decisions the ``alchemy`` Scaffold Has Made for You ================================================================= Creating a project using the ``alchemy`` scaffold makes @@ -375,15 +376,15 @@ the following assumptions: - you are willing to use :term:`SQLAlchemy` as a database access tool -- you are willing to use :term:`url dispatch` to map URLs to code. +- you are willing to use :term:`URL dispatch` to map URLs to code - you want to use ``ZopeTransactionExtension`` and ``pyramid_tm`` to scope sessions to requests .. note:: - :app:`Pyramid` supports any persistent storage mechanism (e.g. object - database or filesystem files, etc). It also supports an additional + :app:`Pyramid` supports any persistent storage mechanism (e.g., object + database or filesystem files). It also supports an additional mechanism to map URLs to code (:term:`traversal`). However, for the - purposes of this tutorial, we'll only be using url dispatch and + purposes of this tutorial, we'll only be using URL dispatch and SQLAlchemy. diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt b/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt index 5f962bbf5..9320e0a50 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt @@ -1,22 +1,20 @@ - - + + + ${page.name} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) - - - + + + href="${request.static_url('tutorial:static/favicon.ico')}"> + type="text/css" media="screen"> @@ -25,7 +23,7 @@
pyramid + src="${request.static_url('tutorial:static/pyramid-small.png')}">
@@ -33,9 +31,9 @@
Editing Page Name Goes - Here
+ Here
You can return to the - FrontPage.
+ FrontPage.
@@ -44,8 +42,8 @@
+
+
+ +
+ + + - - -
-
-
- Editing Page Name Goes - Here
- You can return to the - FrontPage.
+
+
- -
-
-
-
-
- +
+
+ +
+ +
+
- - -
-
-
- Editing Page Name - Goes Here
- You can return to the - FrontPage.
-
-
-
-
-
- +
+
+ +
+ +
+
- - -
-
-
- Editing Page Name - Goes Here
- You can return to the - FrontPage.
-
-
-
-
-
- diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt index 64e592ea9..331d52d2a 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt @@ -1,58 +1,74 @@ - - - - Login - Pyramid tutorial wiki (based on TurboGears - 20-Minute Wiki) - - - - - - - - -
-
-
-
- pyramid + + + + + + + + + + + Login - Pyramid tutorial wiki (based on + TurboGears 20-Minute Wiki) + + + + + + + + + + + + +
+
+
+
+ +
+
+
+

+ + Login + + +

+ + +
+ + +
+
+ + +
+
+ +
+ +
+
-
-
-
-
-
- Login
- +
+
- -
-
-
-
-
- -
-
- -
-
- - + + + + + + + diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt index 4e5772de0..02cb8e73b 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt @@ -33,6 +33,9 @@
+

+ Logout +

Page text goes here.
@@ -48,11 +51,6 @@

You can return to the FrontPage.

-

- - Logout - -

diff --git a/docs/tutorials/wiki2/tests.rst b/docs/tutorials/wiki2/tests.rst index 9aca0c5b7..c171a0e6e 100644 --- a/docs/tutorials/wiki2/tests.rst +++ b/docs/tutorials/wiki2/tests.rst @@ -6,8 +6,6 @@ We will now add tests for the models and the views and a few functional tests in the ``tests.py``. Tests ensure that an application works, and that it continues to work after changes are made in the future. - - Testing the Models ================== @@ -37,7 +35,7 @@ can, and so on. Viewing the results of all our edits to ``tests.py`` ==================================================== -Once we're done with the ``tests.py`` module, it will look a lot like: +Open the ``tutorial/tests.py`` module, and edit it as follows: .. literalinclude:: src/tests/tutorial/tests.py :linenos: -- cgit v1.2.3 From ca6ec2fb9f52e0bac9eed622da1cea50b5a45339 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 25 May 2015 11:20:51 -0700 Subject: grammar --- docs/tutorials/wiki2/tests.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/tutorials/wiki2') diff --git a/docs/tutorials/wiki2/tests.rst b/docs/tutorials/wiki2/tests.rst index c171a0e6e..e96fb0bae 100644 --- a/docs/tutorials/wiki2/tests.rst +++ b/docs/tutorials/wiki2/tests.rst @@ -3,8 +3,8 @@ Adding Tests ============ We will now add tests for the models and the views and a few functional -tests in the ``tests.py``. Tests ensure that an application works, and -that it continues to work after changes are made in the future. +tests in ``tests.py``. Tests ensure that an application works, and +that it continues to work when changes are made in the future. Testing the Models ================== @@ -17,12 +17,11 @@ Testing the Views ================= We'll modify our ``tests.py`` file, adding tests for each view -function we added above. As a result, we'll *delete* the +function we added previously. As a result, we'll *delete* the ``ViewTests`` class that the ``alchemy`` scaffold 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 -respectively. +``view_wiki``, ``view_page``, ``add_page``, and ``edit_page`` views. Functional tests ================ @@ -35,7 +34,8 @@ can, and so on. Viewing the results of all our edits to ``tests.py`` ==================================================== -Open the ``tutorial/tests.py`` module, and edit it as follows: +Open the ``tutorial/tests.py`` module, and edit it such that it appears as +follows: .. literalinclude:: src/tests/tutorial/tests.py :linenos: -- cgit v1.2.3 From 2c34a669aea2a8c51e91037689f199e4e543a3c0 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 25 May 2015 11:37:20 -0700 Subject: mention ZODB; punctuation --- docs/tutorials/wiki2/index.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docs/tutorials/wiki2') diff --git a/docs/tutorials/wiki2/index.rst b/docs/tutorials/wiki2/index.rst index 0a614cb23..0a3873dcd 100644 --- a/docs/tutorials/wiki2/index.rst +++ b/docs/tutorials/wiki2/index.rst @@ -3,7 +3,7 @@ SQLAlchemy + URL Dispatch Wiki Tutorial ======================================= -This tutorial introduces a :term:`SQLAlchemy` and :term:`url dispatch` -based +This tutorial introduces a :term:`SQLAlchemy` and :term:`url dispatch`-based :app:`Pyramid` application to a developer familiar with Python. When the tutorial is finished, the developer will have created a basic Wiki application with authentication. @@ -26,4 +26,3 @@ which corresponds to the same location if you have Pyramid sources. tests distributing - -- cgit v1.2.3 From 3e6b601d9bc557b5b698d5fd4d6eb20b151a424f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 25 May 2015 13:53:05 -0700 Subject: cherry pick from 1.5-branch --- docs/tutorials/wiki2/background.rst | 8 ++-- docs/tutorials/wiki2/design.rst | 21 ++++----- docs/tutorials/wiki2/installation.rst | 83 ++++++++++++++++++++++------------- 3 files changed, 69 insertions(+), 43 deletions(-) (limited to 'docs/tutorials/wiki2') diff --git a/docs/tutorials/wiki2/background.rst b/docs/tutorials/wiki2/background.rst index 1f9582903..b8afb8305 100644 --- a/docs/tutorials/wiki2/background.rst +++ b/docs/tutorials/wiki2/background.rst @@ -2,10 +2,12 @@ Background ========== -This tutorial presents a :app:`Pyramid` application that uses technologies -which will be familiar to someone with SQL database experience. It uses +This version of the :app:`Pyramid` wiki tutorial presents a +:app:`Pyramid` application that uses technologies which will be +familiar to someone with SQL database experience. It uses :term:`SQLAlchemy` as a persistence mechanism and :term:`url dispatch` to map -URLs to code. +URLs to code. It can also be followed by people without any prior +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 diff --git a/docs/tutorials/wiki2/design.rst b/docs/tutorials/wiki2/design.rst index fa291cdc0..e9f361e7d 100644 --- a/docs/tutorials/wiki2/design.rst +++ b/docs/tutorials/wiki2/design.rst @@ -9,7 +9,7 @@ tutorial. Overall ------- -We choose to use :term:`reStructuredText` markup in the wiki text. Translation +We choose to use :term:`reStructuredText` markup in the wiki text. Translation from reStructuredText to HTML is provided by the widely used ``docutils`` Python module. We will add this module in the dependency list on the project ``setup.py`` file. @@ -37,8 +37,8 @@ Views ----- There will be three views to handle the normal operations of adding, -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 for adding +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 @@ -53,13 +53,14 @@ Security We'll eventually be adding security to our application. The components we'll use to do this are below. -- USERS, a dictionary mapping users names (the user's :term:`userids - `) to their corresponding passwords. +- USERS, a dictionary mapping :term:`userids ` to their + corresponding passwords. -- GROUPS, a dictionary mapping user names to a list of groups they belong to. +- GROUPS, a dictionary mapping :term:`userids ` to a + list of groups to which they belong. - ``groupfinder``, an *authorization callback* that looks up USERS and - GROUPS. It will be provided in a new *security.py* file. + GROUPS. It will be provided in a new ``security.py`` file. - An :term:`ACL` is attached to the root :term:`resource`. Each row below details an :term:`ACE`: @@ -101,7 +102,7 @@ listed in the following table: | | with existing | | | | | | content. | | | | | | | | | | -| | If the form is | | | | +| | If the form was | | | | | | submitted, redirect | | | | | | to /PageName | | | | +----------------------+-----------------------+-------------+------------+------------+ @@ -111,7 +112,7 @@ listed in the following table: | | the edit form | | | | | | without content. | | | | | | | | | | -| | If the form is | | | | +| | If the form was | | | | | | submitted, | | | | | | redirect to | | | | | | /PageName | | | | @@ -119,7 +120,7 @@ listed in the following table: | /login | Display login form, | login | login.pt | | | | Forbidden [3]_ | | | | | | | | | | -| | If the form is | | | | +| | If the form was | | | | | | submitted, | | | | | | authenticate. | | | | | | | | | | diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index 9b0389feb..1385ab8c7 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -2,22 +2,41 @@ Installation ============ -Before You Begin +Before you begin ================ This tutorial assumes that you have already followed the steps in -:ref:`installing_chapter`, thereby satisfying the following -requirements. +:ref:`installing_chapter`, except **do not create a virtualenv or install +Pyramid**. Thereby you will satisfy the following requirements. * Python interpreter is installed on your operating system * :term:`setuptools` or :term:`distribute` is installed * :term:`virtualenv` is installed -Create and Use a Virtual Python Environment +Create directory to contain the project +--------------------------------------- + +We need a workspace for our project files. + +On UNIX +^^^^^^^ + +.. code-block:: text + + $ mkdir ~/pyramidtut + +On Windows +^^^^^^^^^^ + +.. code-block:: text + + c:\> mkdir pyramidtut + +Create and use a virtual Python environment ------------------------------------------- Next let's create a `virtualenv` workspace for our project. We will -use the `VENV` environment variable instead of absolute path of the +use the `VENV` environment variable instead of the absolute path of the virtual environment. On UNIX @@ -33,8 +52,6 @@ On UNIX On Windows ^^^^^^^^^^ -Set the `VENV` environment variable. - .. code-block:: text c:\> set VENV=c:\pyramidtut @@ -54,7 +71,7 @@ Python 3.2: c:\> c:\Python32\Scripts\virtualenv %VENV% -Install Pyramid Into the Virtual Python Environment +Install Pyramid into the virtual Python environment --------------------------------------------------- On UNIX @@ -69,9 +86,9 @@ On Windows .. code-block:: text - c:\env> %VENV%\Scripts\easy_install pyramid + c:\> %VENV%\Scripts\easy_install pyramid -Install SQLite3 and Its Development Packages +Install SQLite3 and its development packages -------------------------------------------- If you used a package manager to install your Python or if you compiled @@ -87,7 +104,7 @@ the Debian system and apt-get, the command would be the following: $ sudo apt-get install libsqlite3-dev -Change Directory to Your Virtual Python Environment +Change directory to your virtual Python environment --------------------------------------------------- Change directory to the ``pyramidtut`` directory. @@ -108,7 +125,7 @@ On Windows .. _sql_making_a_project: -Making a Project +Making a project ================ Your next step is to create a project. For this tutorial we will use @@ -117,7 +134,7 @@ that uses :term:`SQLAlchemy` and :term:`URL dispatch`. :app:`Pyramid` supplies a variety of scaffolds to generate sample projects. We will use `pcreate`—a script that comes with Pyramid to -quickly and easily generate scaffolds usually with a single command—to +quickly and easily generate scaffolds, usually with a single command—to create the scaffold for our project. By passing `alchemy` into the `pcreate` command, the script creates @@ -126,8 +143,7 @@ the files needed to use SQLAlchemy. By passing in our application name required files. For example, `pcreate` creates the ``initialize_tutorial_db`` in the ``pyramidtut/bin`` directory. -The below instructions assume your current working directory is the -"virtualenv" named "pyramidtut". +The below instructions assume your current working directory is "pyramidtut". On UNIX ------- @@ -141,7 +157,7 @@ On Windows .. code-block:: text - c:\pyramidtut> %VENV%\pcreate -s alchemy tutorial + c:\pyramidtut> %VENV%\Scripts\pcreate -s alchemy tutorial .. note:: If you are using Windows, the ``alchemy`` scaffold may not deal gracefully with installation into a @@ -151,7 +167,7 @@ On Windows .. _installing_project_in_dev_mode: -Installing the Project in Development Mode +Installing the project in development mode ========================================== In order to do development on the project easily, you must "register" @@ -184,8 +200,8 @@ the following:: .. _sql_running_tests: -Running the Tests -================= +Run the tests +============= After you've installed the project in development mode, you may run the tests for the project. @@ -212,8 +228,8 @@ For a successful test run, you should see output that ends like this:: OK -Exposing Test Coverage Information -================================== +Expose test coverage information +================================ You can run the ``nosetests`` command to see test coverage information. This runs the tests in the same way that ``setup.py @@ -274,10 +290,9 @@ If successful, you will see output something like this:: Looks like our package doesn't quite have 100% test coverage. - .. _initialize_db_wiki2: -Initializing the Database +Initializing the database ========================= We need to use the ``initialize_tutorial_db`` :term:`console @@ -333,8 +348,8 @@ directory. This will be a SQLite database with a single table defined in it .. _wiki2-start-the-application: -Starting the Application -======================== +Start the application +===================== Start the application. @@ -352,6 +367,11 @@ On Windows c:\pyramidtut\tutorial> %VENV%\Scripts\pserve development.ini --reload +.. note:: + + Your OS firewall, if any, may pop up a dialog asking for authorization + to allow python to accept incoming network connections. + If successful, you will see something like this on your console:: Starting subprocess with file monitor @@ -360,19 +380,22 @@ If successful, you will see something like this on your console:: This means the server is ready to accept requests. -At this point, when you visit ``http://localhost:6543/`` in your web browser, -you will see the generated application's default page. +Visit the application in a browser +================================== + +In a browser, visit `http://localhost:6543/ `_. You +will see the generated application's default page. One thing you'll notice is the "debug toolbar" icon on right hand side of the page. You can read more about the purpose of the icon at :ref:`debug_toolbar`. It allows you to get information about your application while you develop. -Decisions the ``alchemy`` Scaffold Has Made for You +Decisions the ``alchemy`` scaffold has made for you ================================================================= -Creating a project using the ``alchemy`` scaffold makes -the following assumptions: +Creating a project using the ``alchemy`` scaffold makes the following +assumptions: - you are willing to use :term:`SQLAlchemy` as a database access tool -- cgit v1.2.3 From 34a913dd693695ade475000bfe61eb6e828a1dc8 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 25 May 2015 14:55:00 -0700 Subject: grammar, caps, minor tweaks --- docs/tutorials/wiki2/basiclayout.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docs/tutorials/wiki2') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 90157aa9e..623882516 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -7,13 +7,14 @@ they provide a good orientation for the high-level patterns common to most :term:`URL dispatch`-based :app:`Pyramid` projects. -Application Configuration with ``__init__.py`` +Application configuration with ``__init__.py`` ---------------------------------------------- A directory on disk can be turned into a Python :term:`package` by containing an ``__init__.py`` file. Even if empty, this marks a directory as a Python -package. We use ``__init__.py``, both as a marker indicating the directory -it's contained within is a package, and to contain configuration code. +package. We use ``__init__.py`` both as a marker, indicating the directory +in which it's contained is a package, and to contain application configuration +code. Open ``tutorial/tutorial/__init__.py``. It should already contain the following: @@ -136,7 +137,7 @@ Finally, ``main`` is finished configuring things, so it uses the :lines: 21 :language: py -View Declarations via ``views.py`` +View declarations via ``views.py`` ---------------------------------- The main function of a web framework is mapping each URL pattern to code (a -- cgit v1.2.3 From dd6232d43ca974e95742275312a06863c2bd0744 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 25 May 2015 15:52:53 -0700 Subject: wikis consistency, grammar, wrapping --- docs/tutorials/wiki2/definingmodels.rst | 50 ++++++++++++++++----------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'docs/tutorials/wiki2') diff --git a/docs/tutorials/wiki2/definingmodels.rst b/docs/tutorials/wiki2/definingmodels.rst index fee440fe3..0fabb5f53 100644 --- a/docs/tutorials/wiki2/definingmodels.rst +++ b/docs/tutorials/wiki2/definingmodels.rst @@ -7,18 +7,18 @@ be to define a :term:`domain model` constructor representing a wiki page. We'll do this inside our ``models.py`` file. -Making Edits to ``models.py`` ------------------------------ +Edit ``models.py`` +------------------ .. note:: There is nothing special about the filename ``models.py``. A - project may have many models throughout its codebase in arbitrarily-named + project may have many models throughout its codebase in arbitrarily named files. Files implementing models often have ``model`` in their filenames - (or they may live in a Python subpackage of your application package named - ``models``) , but this is only by convention. + or they may live in a Python subpackage of your application package named + ``models``, but this is only by convention. -Open ``tutorial/tutorial/models.py`` file and edit it to look like the +Open ``tutorial/tutorial/models.py`` file and edit it to look like the following: .. literalinclude:: src/models/tutorial/models.py @@ -45,29 +45,29 @@ this class inherits from an instance of As you can see, our ``Page`` class has a class level attribute ``__tablename__`` which equals the string ``'pages'``. This means that SQLAlchemy will store our wiki data in a SQL table named ``pages``. Our -``Page`` class will also have class-level attributes named ``id``, ``name`` and -``data`` (all instances of :class:`sqlalchemy.schema.Column`). -These will map to columns in the ``pages`` table. -The ``id`` attribute will be the primary key in the table. -The ``name`` attribute will be a text attribute, each value of -which needs to be unique within the column. The ``data`` attribute is a text -attribute that will hold the body of each page. +``Page`` class will also have class-level attributes named ``id``, ``name`` +and ``data`` (all instances of :class:`sqlalchemy.schema.Column`). These will +map to columns in the ``pages`` table. The ``id`` attribute will be the +primary key in the table. The ``name`` attribute will be a text attribute, +each value of which needs to be unique within the column. The ``data`` +attribute is a text attribute that will hold the body of each page. Changing ``scripts/initializedb.py`` ------------------------------------ We haven't looked at the details of this file yet, but within the ``scripts`` -directory of your ``tutorial`` package is a file named ``initializedb.py``. Code -in this file is executed whenever we run the ``initialize_tutorial_db`` command, -as we did in the installation step of this tutorial. +directory of your ``tutorial`` package is a file named ``initializedb.py``. +Code in this file is executed whenever we run the ``initialize_tutorial_db`` +command, as we did in the installation step of this tutorial. -Since we've changed our model, we need to make changes to our ``initializedb.py`` -script. In particular, we'll replace our import of ``MyModel`` with one of -``Page`` and we'll change the very end of the script to create a ``Page`` -rather than a ``MyModel`` and add it to our ``DBSession``. +Since we've changed our model, we need to make changes to our +``initializedb.py`` script. In particular, we'll replace our import of +``MyModel`` with one of ``Page`` and we'll change the very end of the script +to create a ``Page`` rather than a ``MyModel`` and add it to our +``DBSession``. -Open ``tutorial/tutorial/scripts/initializedb.py`` and edit it to look like the -following: +Open ``tutorial/tutorial/scripts/initializedb.py`` and edit it to look like +the following: .. literalinclude:: src/models/tutorial/scripts/initializedb.py :linenos: @@ -82,9 +82,9 @@ Installing the Project and re-initializing the Database ------------------------------------------------------- Because our model has changed, in order to reinitialize the database, we need -to rerun the ``initialize_tutorial_db`` command to pick up the changes you've made -to both the models.py file and to the initializedb.py file. -See :ref:`initialize_db_wiki2` for instructions. +to rerun the ``initialize_tutorial_db`` command to pick up the changes you've +made to both the models.py file and to the initializedb.py file. See +:ref:`initialize_db_wiki2` for instructions. Success will look something like this:: -- cgit v1.2.3 From 1204f0f285daf28e08dbfbae683a0aa8f27bd205 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 25 May 2015 16:01:14 -0700 Subject: update static assets, mytemplate.pt, caps --- docs/tutorials/wiki2/definingmodels.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/tutorials/wiki2') diff --git a/docs/tutorials/wiki2/definingmodels.rst b/docs/tutorials/wiki2/definingmodels.rst index 0fabb5f53..b2d9bf83a 100644 --- a/docs/tutorials/wiki2/definingmodels.rst +++ b/docs/tutorials/wiki2/definingmodels.rst @@ -78,7 +78,7 @@ Only the highlighted lines need to be changed, as well as removing the lines referencing ``pyramid.scripts.common`` and ``options`` under the ``main`` function. -Installing the Project and re-initializing the Database +Installing the project and re-initializing the database ------------------------------------------------------- Because our model has changed, in order to reinitialize the database, we need @@ -111,8 +111,8 @@ Success will look something like this:: 2015-05-24 15:34:14,549 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('FrontPage', 'This is the front page') 2015-05-24 15:34:14,550 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT -Viewing the Application in a Browser ------------------------------------- +View the application in a browser +--------------------------------- We can't. At this point, our system is in a "non-runnable" state; we'll need to change view-related files in the next chapter to be able to start the -- cgit v1.2.3 From a940e1ccaa6c3ca81b1dec6ba2e505af9b792222 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 26 May 2015 13:12:01 -0700 Subject: - clean up and make defininingviews consistent between two wiki tutorials - sort imports to be consistent with scaffold setup.py - update templates, static assets --- docs/tutorials/wiki2/definingviews.rst | 163 +++++++++++++++++---------------- 1 file changed, 83 insertions(+), 80 deletions(-) (limited to 'docs/tutorials/wiki2') diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst index 0981af268..d7f63100d 100644 --- a/docs/tutorials/wiki2/definingviews.rst +++ b/docs/tutorials/wiki2/definingviews.rst @@ -23,26 +23,27 @@ application was generated by the ``pcreate`` command; it doesn't know about our custom application requirements. We need to add a dependency on the ``docutils`` package to our ``tutorial`` -package's ``setup.py`` file by assigning this dependency to the ``requires`` parameter in ``setup()``. +package's ``setup.py`` file by assigning this dependency to the ``requires`` +parameter in the ``setup()`` function. Open ``tutorial/setup.py`` and edit it to look like the following: .. literalinclude:: src/views/setup.py :linenos: - :language: python :emphasize-lines: 20 + :language: python Only the highlighted line needs to be added. Running ``setup.py develop`` ============================ -Since a new software dependency was added, you will need to rerun ``python -setup.py develop`` inside the root of the ``tutorial`` package to obtain and -register the newly added dependency distribution. +Since a new software dependency was added, you will need to run ``python +setup.py develop`` again inside the root of the ``tutorial`` package to obtain +and register the newly added dependency distribution. Make sure your current working directory is the root of the project (the -directory in which setup.py lives) and execute the following command. +directory in which ``setup.py`` lives) and execute the following command. On UNIX: @@ -63,21 +64,24 @@ like:: Finished processing dependencies for tutorial==0.0 -Changing the ``views.py`` File -============================== +Adding view functions in ``views.py`` +===================================== -It's time for a major change. Open ``tutorial/tutorial/views.py`` and edit it to look like the following: +It's time for a major change. Open ``tutorial/tutorial/views.py`` and edit it +to look like the following: .. literalinclude:: src/views/tutorial/views.py :linenos: :language: python :emphasize-lines: 1-7,14,16-72 -The highlighted lines are the ones that need to be added or edited. +The highlighted lines need to be added or edited. + +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 ``alchemy`` scaffold. It was only an -example and isn't relevant to our application. +We got rid of the ``my_view`` view function and its decorator that was added +when we originally rendered the ``alchemy`` scaffold. 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: @@ -87,8 +91,7 @@ module: * ``add_page()`` - Allows the user to add a page. * ``edit_page()`` - Allows the user to edit a page. -We'll describe each one briefly and show the resulting ``views.py`` file -afterward. +We'll describe each one briefly in the following sections. .. note:: @@ -101,9 +104,7 @@ afterward. The ``view_wiki`` view function ------------------------------- -``view_wiki()`` is the :term:`default view` that gets called when a request -is made to the root URL of our wiki. It always redirects to -a URL which represents the path to our "FrontPage". +Following is the code for the ``view_wiki`` view function and its decorator: .. literalinclude:: src/views/tutorial/views.py :lines: 20-24 @@ -111,23 +112,23 @@ a URL which represents the path to our "FrontPage". :linenos: :language: python -``view_wiki()`` returns an instance of the -:class:`pyramid.httpexceptions.HTTPFound` class (instances of which implement -the :class:`pyramid.interfaces.IResponse` interface like -:class:`pyramid.response.Response` does). +``view_wiki()`` is the :term:`default view` that gets called when a request is +made to the root URL of our wiki. It always redirects to an URL which +represents the path to our "FrontPage". -It uses the :meth:`pyramid.request.Request.route_url` API to construct a -URL to the ``FrontPage`` page (e.g., ``http://localhost:6543/FrontPage``), which -is used as the location of the ``HTTPFound`` response, forming an HTTP redirect. +The ``view_wiki`` view callable always redirects to the URL of a Page resource +named "FrontPage". To do so, it returns an instance of the +:class:`pyramid.httpexceptions.HTTPFound` class (instances of which implement +the :class:`pyramid.interfaces.IResponse` interface, like +:class:`pyramid.response.Response` does). It uses the +:meth:`pyramid.request.Request.route_url` API to construct an URL to the +``FrontPage`` page (i.e., ``http://localhost:6543/FrontPage``), and uses it as +the "location" of the ``HTTPFound`` response, forming an HTTP redirect. The ``view_page`` view function ------------------------------- -``view_page()`` is used to display a single page of our -wiki. It renders the :term:`reStructuredText` body of a page (stored as -the ``data`` attribute of a ``Page`` model object) as HTML. Then it substitutes an -HTML anchor for each *WikiWord* reference in the rendered HTML using a -compiled regular expression. +Here is the code for the ``view_page`` view function and its decorator: .. literalinclude:: src/views/tutorial/views.py :lines: 25-45 @@ -135,7 +136,12 @@ compiled regular expression. :linenos: :language: python -The ``check()`` function is used as the first argument to +``view_page()`` is used to display a single page of our wiki. It renders the +:term:`reStructuredText` body of a page (stored as the ``data`` attribute of a +``Page`` model object) as HTML. Then it substitutes an HTML anchor for each +*WikiWord* reference in the rendered HTML using a compiled regular expression. + +The curried function named ``check`` is used as the first argument to ``wikiwords.sub``, indicating that it should be called to provide a value for each WikiWord match found in the content. If the wiki already contains a page with the matched WikiWord name, ``check()`` generates a view @@ -158,6 +164,14 @@ renderer used will be the ``templates/view.pt`` template, as indicated in the The ``add_page`` view function ------------------------------ +Here is the code for the ``add_page`` view function and its decorator: + +.. literalinclude:: src/views/tutorial/views.py + :lines: 47-58 + :lineno-start: 47 + :linenos: + :language: python + ``add_page()`` is invoked when a user clicks on a *WikiWord* which isn't yet represented as a page in the system. The ``check`` function within the ``view_page`` view generates URLs to this view. @@ -166,12 +180,6 @@ when we want to add a page object. The ``matchdict`` attribute of the request passed to the ``add_page()`` view will have the values we need to construct URLs and find model objects. -.. literalinclude:: src/views/tutorial/views.py - :lines: 47-58 - :lineno-start: 47 - :linenos: - :language: python - The ``matchdict`` will have a ``'pagename'`` key that matches the name of the page we'd like to add. If our add view is invoked via, e.g., ``http://localhost:6543/add_page/SomeName``, the value for @@ -197,11 +205,7 @@ with this view to a response. The ``edit_page`` view function ------------------------------- -``edit_page()`` is invoked when a user clicks the "Edit this -Page" button on the view form. It renders an edit form but it also acts as -the handler for the form it renders. The ``matchdict`` attribute of the -request passed to the ``edit_page`` view will have a ``'pagename'`` key -matching the name of the page the user wants to edit. +Here is the code for the ``edit_page`` view function and its decorator: .. literalinclude:: src/views/tutorial/views.py :lines: 60-72 @@ -209,6 +213,12 @@ matching the name of the page the user wants to edit. :linenos: :language: python +``edit_page()`` is invoked when a user clicks the "Edit this +Page" button on the view form. It renders an edit form but it also acts as +the handler for the form it renders. The ``matchdict`` attribute of the +request passed to the ``edit_page`` view will have a ``'pagename'`` key +matching the name of the page the user wants to edit. + If the view execution *is* a result of a form submission (i.e., the expression ``'form.submitted' in request.params`` is ``True``), the view grabs the ``body`` element of the request parameters and sets it as the ``data`` @@ -220,16 +230,16 @@ expression ``'form.submitted' in request.params`` is ``False``), the view simply renders the edit form, passing the page object and a ``save_url`` which will be used as the action of the generated form. -Adding Templates +Adding templates ================ The ``view_page``, ``add_page`` and ``edit_page`` views that we've added -reference a :term:`template`. Each template is a :term:`Chameleon` :term:`ZPT` -template. These templates will live in the ``templates`` directory of our -tutorial package. Chameleon templates must have a ``.pt`` extension to be -recognized as such. +reference a :term:`template`. Each template is a :term:`Chameleon` +:term:`ZPT` template. These templates will live in the ``templates`` +directory of our tutorial package. Chameleon templates must have a ``.pt`` +extension to be recognized as such. -The ``view.pt`` Template +The ``view.pt`` template ------------------------ Create ``tutorial/tutorial/templates/view.pt`` and add the following @@ -242,15 +252,13 @@ content: 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`` keyword is used - to prevent escaping it (i.e., changing ">" to ">", etc.) -- A link that points - at the "edit" URL which invokes the ``edit_page`` view for - the page being viewed (lines 40-42). +- A ``div`` element that is replaced with the ``content`` value provided by + the view (lines 36-38). ``content`` contains HTML, so the ``structure`` + keyword is used to prevent escaping it (i.e., changing ">" to ">", etc.) +- A link that points at the "edit" URL which invokes the ``edit_page`` view + for the page being viewed (lines 40-42). -The ``edit.pt`` Template +The ``edit.pt`` template ------------------------ Create ``tutorial/tutorial/templates/edit.pt`` and add the following @@ -260,24 +268,21 @@ content: :linenos: :language: html -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: +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). -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. +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. -.. note:: Our templates use a ``request`` object that - none of our tutorial views return in their dictionary. - ``request`` is one of several - names that are available "by default" in a template when a template - renderer is used. See :ref:`renderer_system_values` for - information about other names that are available by default - when a template is used as a renderer. +.. note:: Our templates use a ``request`` object that none of our tutorial + views return in their dictionary. ``request`` is one of several names that + are available "by default" in a template when a template renderer is used. + See :ref:`renderer_system_values` for information about other names that + are available by default when a template is used as a renderer. Static Assets ------------- @@ -347,21 +352,19 @@ We can finally examine our application in a browser (See :ref:`wiki2-start-the-application`). Launch a browser and visit each of the following URLs, checking that the result is as expected: -- http://localhost:6543 in a browser invokes the - ``view_wiki`` view. This always redirects to the ``view_page`` view - of the FrontPage page object. +- ``http://localhost:6543/`` invokes the ``view_wiki`` view. This always + redirects to the ``view_page`` view of the ``FrontPage`` page object. -- http://localhost:6543/FrontPage in a browser invokes - the ``view_page`` view of the front page object. +- http://localhost:6543/FrontPage invokes the ``view_page`` view of the front + page object. -- http://localhost:6543/FrontPage/edit_page in a browser - invokes the edit view for the front page object. +- http://localhost:6543/FrontPage/edit_page invokes the edit view for the + front page object. -- http://localhost:6543/add_page/SomePageName in a - browser invokes the add view for a page. +- http://localhost:6543/add_page/SomePageName invokes the add view for a page. - To generate an error, visit http://localhost:6543/foobars/edit_page which - will generate a ``NoResultFound: No row was found for one()`` error. - You'll see an interactive traceback facility provided - by :term:`pyramid_debugtoolbar`. + will generate a ``NoResultFound: No row was found for one()`` error. You'll + see an interactive traceback facility provided by + :term:`pyramid_debugtoolbar`. -- cgit v1.2.3 From 5f375c7603c0e240a60b884bf0ef39352c25c879 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 27 May 2015 02:44:38 -0700 Subject: - clean up and make consistent across both wikis authorization.rst - update templates and static assets to new theme --- docs/tutorials/wiki2/authorization.rst | 289 ++++++++++----------- .../src/authorization/tutorial/templates/login.pt | 2 +- 2 files changed, 137 insertions(+), 154 deletions(-) (limited to 'docs/tutorials/wiki2') diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst index 1f7af5654..125579e7f 100644 --- a/docs/tutorials/wiki2/authorization.rst +++ b/docs/tutorials/wiki2/authorization.rst @@ -1,27 +1,25 @@ .. _wiki2_adding_authorization: ==================== -Adding Authorization +Adding authorization ==================== :app:`Pyramid` provides facilities for :term:`authentication` and -:term:`authorization`. We'll make use of both features to provide security -to our application. Our application currently allows anyone with access to -the server to view, edit, and add pages to our wiki. We'll change that -to allow only people who are members of a *group* named ``group:editors`` -to add and edit wiki pages but we'll continue allowing -anyone with access to the server to view pages. - -We will also add a login page and a logout link on all the -pages. The login page will be shown when a user is denied -access to any of the views that require permission, instead of -a default "403 Forbidden" page. +::term:`authorization`. We'll make use of both features to provide security +:to our application. Our application currently allows anyone with access to +:the server to view, edit, and add pages to our wiki. We'll change that to +:allow only people who are members of a *group* named ``group:editors`` to add +:and edit wiki pages but we'll continue allowing anyone with access to the +:server to view pages. + +We will also add a login page and a logout link on all the pages. The login +page will be shown when a user is denied access to any of the views that +require permission, instead of a default "403 Forbidden" page. We will implement the access control with the following steps: * Add users and groups (``security.py``, a new module). -* Add an :term:`ACL` (``models.py`` and - ``__init__.py``). +* Add an :term:`ACL` (``models.py`` and ``__init__.py``). * Add an :term:`authentication policy` and an :term:`authorization policy` (``__init__.py``). * Add :term:`permission` declarations to the ``edit_page`` and ``add_page`` @@ -32,12 +30,13 @@ Then we will add the login and logout feature: * Add routes for /login and /logout (``__init__.py``). * Add ``login`` and ``logout`` views (``views.py``). * Add a login template (``login.pt``). -* Make the existing views return a ``logged_in`` flag to the renderer (``views.py``). +* Make the existing views return a ``logged_in`` flag to the renderer + (``views.py``). * Add a "Logout" link to be shown when logged in and viewing or editing a page (``view.pt``, ``edit.pt``). -Access Control +Access control -------------- Add users and groups @@ -53,21 +52,18 @@ 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 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``. +- If the 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``. For example, ``groupfinder('editor', request )`` returns ``['group:editor']``, -``groupfinder('viewer', request)`` returns [], and ``groupfinder('admin', request)`` -returns ``None``. We will use ``groupfinder()`` as an :term:`authentication policy` -"callback" that will provide the :term:`principal` or principals -for a user. +``groupfinder('viewer', request)`` returns ``[]``, and ``groupfinder('admin', +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 database, but here we use "dummy" -data to represent user and groups sources. +In a production system, user and group data will most often come from a +database, but here we use "dummy" data to represent user and groups sources. Add an ACL ~~~~~~~~~~ @@ -88,26 +84,24 @@ Add the following class definition at the end: :lineno-start: 33 :language: python -We import :data:`~pyramid.security.Allow`, an action that -means that permission is allowed, and -:data:`~pyramid.security.Everyone`, a special :term:`principal` -that is associated to all requests. Both are used in the +We import :data:`~pyramid.security.Allow`, an action that means that +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 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. +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. -The ``RootFactory`` class that contains the ACL is a :term:`root factory`. -We need to associate it to our :app:`Pyramid` application, so the ACL is -provided to each view in the :term:`context` of the request, as -the ``context`` attribute. +The ``RootFactory`` class that contains the ACL is a :term:`root factory`. We +need to associate it to our :app:`Pyramid` application, so the ACL is provided +to each view in the :term:`context` of the request as the ``context`` +attribute. -Open ``tutorial/tutorial/__init__.py`` and add a ``root_factory`` -parameter to our :term:`Configurator` constructor, that points to -the class we created above: +Open ``tutorial/tutorial/__init__.py`` and add a ``root_factory`` parameter to +our :term:`Configurator` constructor, that points to the class we created +above: .. literalinclude:: src/authorization/tutorial/__init__.py :lines: 24-25 @@ -118,18 +112,15 @@ the class we created above: Only the highlighted line needs to be added. -We are now providing the ACL to the application. See -:ref:`assigning_acls` for more information about what an -:term:`ACL` represents. - -.. note:: +We are now providing the ACL to the application. See :ref:`assigning_acls` +for more information about what an :term:`ACL` represents. - Although we don't use the functionality here, the ``factory`` used - to create route contexts may differ per-route as opposed to globally. See - the ``factory`` argument to - :meth:`pyramid.config.Configurator.add_route` for more info. +.. note:: Although we don't use the functionality here, the ``factory`` used + to create route contexts may differ per-route as opposed to globally. See + the ``factory`` argument to :meth:`pyramid.config.Configurator.add_route` + for more info. -Add Authentication and Authorization Policies +Add authentication and authorization policies ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Open ``tutorial/tutorial/__init__.py`` and add the highlighted import @@ -152,12 +143,12 @@ Now add those policies to the configuration: Only the highlighted lines need to be added. -We are enabling an ``AuthTktAuthenticationPolicy``, which is based in an -auth ticket that may be included in the request. -We are also enabling an ``ACLAuthorizationPolicy``, which uses an ACL to -determine the *allow* or *deny* outcome for a view. +We are enabling an ``AuthTktAuthenticationPolicy``, which is based in an auth +ticket that may be included in the request. We are also enabling an +``ACLAuthorizationPolicy``, which uses an ACL to determine the *allow* or +*deny* outcome for a view. -Note that the :class:`~pyramid.authentication.AuthTktAuthenticationPolicy` +Note that the :class:`pyramid.authentication.AuthTktAuthenticationPolicy` constructor accepts two arguments: ``secret`` and ``callback``. ``secret`` is a string representing an encryption key used by the "authentication ticket" machinery represented by this policy: it is required. The ``callback`` is the @@ -178,13 +169,14 @@ to the ``@view_config`` decorators for ``add_page()`` and ``edit_page()``: :emphasize-lines: 1-2 :language: python -Only the highlighted lines need to be added or edited. +Only the highlighted lines, along with their preceding commas, need to be +edited and added. -The result is that only users who possess the ``edit`` -permission at the time of the request may invoke those two views. +The result is that only users who possess the ``edit`` permission at the time +of the request may invoke those two views. -Add a ``permission='view'`` parameter to the ``@view_config`` -decorator for ``view_wiki()`` and ``view_page()`` as follows: +Add a ``permission='view'`` parameter to the ``@view_config`` decorator for +``view_wiki()`` and ``view_page()`` as follows: .. literalinclude:: src/authorization/tutorial/views.py :lines: 30-31 @@ -196,20 +188,21 @@ decorator for ``view_wiki()`` and ``view_page()`` as follows: :emphasize-lines: 1-2 :language: python -Only the highlighted lines need to be added or edited. +Only the highlighted lines, along with their preceding commas, need to be +edited and added. This allows anyone to invoke these two views. -We are done with the changes needed to control access. The -changes that follow will add the login and logout feature. +We are done with the changes needed to control access. The changes that +follow will add the login and logout feature. -Login, Logout +Login, logout ------------- Add routes for /login and /logout ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Go back to ``tutorial/tutorial/__init__.py`` and add these two -routes as highlighted: +Go back to ``tutorial/tutorial/__init__.py`` and add these two routes as +highlighted: .. literalinclude:: src/authorization/tutorial/__init__.py :lines: 30-33 @@ -225,23 +218,23 @@ routes as highlighted: This is because ``view_page``'s route definition uses a catch-all "replacement marker" ``/{pagename}`` (see :ref:`route_pattern_syntax`) - which will catch any route that was not already caught by any - route listed above it in ``__init__.py``. Hence, for ``login`` and - ``logout`` views to have the opportunity of being matched - (or "caught"), they must be above ``/{pagename}``. + which will catch any route that was not already caught by any route listed + above it in ``__init__.py``. Hence, for ``login`` and ``logout`` views to + have the opportunity of being matched (or "caught"), they must be above + ``/{pagename}``. -Add Login and Logout Views +Add login and logout views ~~~~~~~~~~~~~~~~~~~~~~~~~~ -We'll add a ``login`` view which renders a login form and processes -the post from the login form, checking credentials. +We'll add a ``login`` view which renders a login form and processes the post +from the login form, checking credentials. -We'll also add a ``logout`` view callable to our application and -provide a link to it. This view will clear the credentials of the -logged in user and redirect back to the front page. +We'll also add a ``logout`` view callable to our application and provide a +link to it. This view will clear the credentials of the logged in user and +redirect back to the front page. -Add the following import statements to the -head of ``tutorial/tutorial/views.py``: +Add the following import statements to the head of +``tutorial/tutorial/views.py``: .. literalinclude:: src/authorization/tutorial/views.py :lines: 9-19 @@ -250,11 +243,10 @@ head of ``tutorial/tutorial/views.py``: All the highlighted lines need to be added or edited. -:meth:`~pyramid.view.forbidden_view_config` will be used -to customize the default 403 Forbidden page. -:meth:`~pyramid.security.remember` and -:meth:`~pyramid.security.forget` help to create and -expire an auth ticket cookie. +:meth:`~pyramid.view.forbidden_view_config` will be used to customize the +default 403 Forbidden page. :meth:`~pyramid.security.remember` and +:meth:`~pyramid.security.forget` help to create and expire an auth ticket +cookie. Now add the ``login`` and ``logout`` views at the end of the file: @@ -262,41 +254,38 @@ Now add the ``login`` and ``logout`` views at the end of the file: :lines: 91-123 :language: python -``login()`` is decorated with two decorators: +``login()`` has two decorators: -- a ``@view_config`` decorator which associates it with the - ``login`` route and makes it visible when we visit ``/login``, -- a ``@forbidden_view_config`` decorator which turns it into - an :term:`forbidden view`. ``login()`` will be invoked - when a users tries to execute a view callable that - they are not allowed to. For example, if a user has not logged in - and tries to add or edit a Wiki page, he will be shown the - login form before being allowed to continue on. +- a ``@view_config`` decorator which associates it with the ``login`` route + and makes it visible when we visit ``/login``, +- a ``@forbidden_view_config`` decorator which turns it into a + :term:`forbidden view`. ``login()`` will be invoked when a user tries to + execute a view callable for which they lack authorization. For example, if + a user has not logged in and tries to add or edit a Wiki page, they will be + shown the login form before being allowed to continue. -The order of these two :term:`view configuration` decorators -is unimportant. +The order of these two :term:`view configuration` decorators is unimportant. -``logout()`` is decorated with a ``@view_config`` decorator -which associates it with the ``logout`` route. It will be -invoked when we visit ``/logout``. +``logout()`` is decorated with a ``@view_config`` decorator which associates +it with the ``logout`` route. It will be invoked when we visit ``/logout``. Add the ``login.pt`` Template ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Create ``tutorial/tutorial/templates/login.pt`` with the following -content: +Create ``tutorial/tutorial/templates/login.pt`` with the following content: .. literalinclude:: src/authorization/tutorial/templates/login.pt - :language: xml + :language: html -The above template is referred to within the login view we just -added to ``views.py``. +The above template is referenced in the login view that we just added in +``views.py``. Return a ``logged_in`` flag to the renderer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Add a ``logged_in`` parameter to the return value of -``view_page()``, ``edit_page()``, and ``add_page()`` as follows: +Open ``tutorial/tutorial/views.py`` again. Add a ``logged_in`` parameter to +the return value of ``view_page()``, ``edit_page()``, and ``add_page()`` as +follows: .. literalinclude:: src/authorization/tutorial/views.py :lines: 57-58 @@ -315,8 +304,8 @@ Add a ``logged_in`` parameter to the return value of Only the highlighted lines need to be added or edited. -The :meth:`~pyramid.request.Request.authenticated_userid` property will be -``None`` if the user is not authenticated. +The :meth:`pyramid.request.Request.authenticated_userid` will be ``None`` if +the user is not authenticated, or a userid if the user is authenticated. Add a "Logout" link when logged in ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -330,16 +319,15 @@ indicated by the highlighted lines. :emphasize-lines: 3-5 :language: html -The attribute ``tal:condition="logged_in"`` will make the element be -included when ``logged_in`` is any user id. The link will invoke -the logout view. The above element will not be included if ``logged_in`` -is ``None``, such as when a user is not authenticated. +The attribute ``tal:condition="logged_in"`` will make the element be included +when ``logged_in`` is any user id. The link will invoke the logout view. The +above element will not be included if ``logged_in`` is ``None``, such as when +a user is not authenticated. Reviewing our changes --------------------- -Our ``tutorial/tutorial/__init__.py`` will look something like this -when we're done: +Our ``tutorial/tutorial/__init__.py`` will look like this when we're done: .. literalinclude:: src/authorization/tutorial/__init__.py :linenos: @@ -348,8 +336,7 @@ when we're done: Only the highlighted lines need to be added or edited. -Our ``tutorial/tutorial/models.py`` will look something like this -when we're done: +Our ``tutorial/tutorial/models.py`` will look like this when we're done: .. literalinclude:: src/authorization/tutorial/models.py :linenos: @@ -358,8 +345,7 @@ when we're done: Only the highlighted lines need to be added or edited. -Our ``tutorial/tutorial/views.py`` will look something like this -when we're done: +Our ``tutorial/tutorial/views.py`` will look like this when we're done: .. literalinclude:: src/authorization/tutorial/views.py :linenos: @@ -368,8 +354,8 @@ when we're done: Only the highlighted lines need to be added or edited. -Our ``tutorial/tutorial/templates/edit.pt`` template will look -something like this when we're done: +Our ``tutorial/tutorial/templates/edit.pt`` template will look like this when +we're done: .. literalinclude:: src/authorization/tutorial/templates/edit.pt :linenos: @@ -378,8 +364,8 @@ something like this when we're done: Only the highlighted lines need to be added or edited. -Our ``tutorial/tutorial/templates/view.pt`` template will look -something like this when we're done: +Our ``tutorial/tutorial/templates/view.pt`` template will look like this when +we're done: .. literalinclude:: src/authorization/tutorial/templates/view.pt :linenos: @@ -392,32 +378,29 @@ Viewing the Application in a Browser ------------------------------------ We can finally examine our application in a browser (See -:ref:`wiki2-start-the-application`). Launch a browser and visit -each of the following URLs, check that the result is as expected: - -- http://localhost:6543/ invokes the - ``view_wiki`` view. This always redirects to the ``view_page`` view - of the FrontPage page object. It is executable by any user. - -- http://localhost:6543/FrontPage invokes - the ``view_page`` view of the FrontPage page object. - -- http://localhost:6543/FrontPage/edit_page - invokes the edit view for the FrontPage object. It is executable by - only the ``editor`` user. If a different user (or the anonymous - user) invokes it, a login form will be displayed. Supplying the - credentials with the username ``editor``, password ``editor`` will - display the edit page form. - -- http://localhost:6543/add_page/SomePageName - invokes the add view for a page. It is executable by only - the ``editor`` user. If a different user (or the anonymous user) - invokes it, a login form will be displayed. Supplying the - credentials with the username ``editor``, password ``editor`` will - display the edit page form. - -- After logging in (as a result of hitting an edit or add page - and submitting the login form with the ``editor`` - credentials), we'll see a Logout link in the upper right hand - corner. When we click it, we're logged out, and redirected - back to the front page. +:ref:`wiki2-start-the-application`). Launch a browser and visit each of the +following URLs, checking that the result is as expected: + +- http://localhost:6543/ invokes the ``view_wiki`` view. This always + redirects to the ``view_page`` view of the ``FrontPage`` page object. It + is executable by any user. + +- http://localhost:6543/FrontPage invokes the ``view_page`` view of the + ``FrontPage`` page object. + +- http://localhost:6543/FrontPage/edit_page invokes the edit view for the + FrontPage object. It is executable by only the ``editor`` user. If a + different user (or the anonymous user) invokes it, a login form will be + displayed. Supplying the credentials with the username ``editor``, password + ``editor`` will display the edit page form. + +- http://localhost:6543/add_page/SomePageName invokes the add view for a page. + It is executable by only the ``editor`` user. If a different user (or the + anonymous user) invokes it, a login form will be displayed. Supplying the + credentials with the username ``editor``, password ``editor`` will display + the edit page form. + +- After logging in (as a result of hitting an edit or add page and submitting + the login form with the ``editor`` credentials), we'll see a Logout link in + the upper right hand corner. When we click it, we're logged out, and + redirected back to the front page. diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt index 331d52d2a..4a938e9bb 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt @@ -36,7 +36,7 @@

Login - +

-- cgit v1.2.3 From 6901d74698da7b8457f92f0771fe03015acb9261 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 27 May 2015 03:38:39 -0700 Subject: - clean up and make consistent across wiki tutorials - update templates and static assets for new design --- docs/tutorials/wiki2/authorization.rst | 2 +- docs/tutorials/wiki2/definingviews.rst | 5 ++--- docs/tutorials/wiki2/tests.rst | 41 +++++++++++++++++----------------- 3 files changed, 23 insertions(+), 25 deletions(-) (limited to 'docs/tutorials/wiki2') diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst index 125579e7f..d2ad7a9ca 100644 --- a/docs/tutorials/wiki2/authorization.rst +++ b/docs/tutorials/wiki2/authorization.rst @@ -374,7 +374,7 @@ we're done: Only the highlighted lines need to be added or edited. -Viewing the Application in a Browser +Viewing the application in a browser ------------------------------------ We can finally examine our application in a browser (See diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst index d7f63100d..0b495445a 100644 --- a/docs/tutorials/wiki2/definingviews.rst +++ b/docs/tutorials/wiki2/definingviews.rst @@ -345,14 +345,14 @@ something like: The highlighted lines are the ones that need to be added or edited. -Viewing the Application in a Browser +Viewing the application in a browser ==================================== We can finally examine our application in a browser (See :ref:`wiki2-start-the-application`). Launch a browser and visit each of the following URLs, checking that the result is as expected: -- ``http://localhost:6543/`` invokes the ``view_wiki`` view. This always +- http://localhost:6543/ invokes the ``view_wiki`` view. This always redirects to the ``view_page`` view of the ``FrontPage`` page object. - http://localhost:6543/FrontPage invokes the ``view_page`` view of the front @@ -367,4 +367,3 @@ each of the following URLs, checking that the result is as expected: will generate a ``NoResultFound: No row was found for one()`` error. You'll see an interactive traceback facility provided by :term:`pyramid_debugtoolbar`. - diff --git a/docs/tutorials/wiki2/tests.rst b/docs/tutorials/wiki2/tests.rst index e96fb0bae..9db95334a 100644 --- a/docs/tutorials/wiki2/tests.rst +++ b/docs/tutorials/wiki2/tests.rst @@ -2,26 +2,25 @@ Adding Tests ============ -We will now add tests for the models and the views and a few functional -tests in ``tests.py``. Tests ensure that an application works, and -that it continues to work when changes are made in the future. +We will now add tests for the models and the views and a few functional tests +in ``tests.py``. Tests ensure that an application works, and that it +continues to work when changes are made in the future. -Testing the Models -================== +Test the models +=============== -To test the model class ``Page`` we'll add a new ``PageModelTests`` -class to our ``tests.py`` file that was generated as part of the -``alchemy`` scaffold. +To test the model class ``Page`` we'll add a new ``PageModelTests`` class to +our ``tests.py`` file that was generated as part of the ``alchemy`` scaffold. -Testing the Views -================= +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 ``alchemy`` scaffold 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. +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 ``alchemy`` scaffold 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. Functional tests ================ @@ -31,8 +30,8 @@ tested in the unit tests, like logging in, logging out, checking that the ``viewer`` user cannot add or edit pages, but the ``editor`` user can, and so on. -Viewing the results of all our edits to ``tests.py`` -==================================================== +View the results of all our edits to ``tests.py`` +================================================= Open the ``tutorial/tests.py`` module, and edit it such that it appears as follows: @@ -41,7 +40,7 @@ follows: :linenos: :language: python -Running the Tests +Running the tests ================= We can run these tests by using ``setup.py test`` in the same way we did in @@ -55,7 +54,7 @@ Change the ``requires`` list in ``setup.py`` to include ``WebTest``. :lines: 11-22 :emphasize-lines: 11 -After we've added a dependency on WebTest in ``setup.py``, we need to rerun +After we've added a dependency on WebTest in ``setup.py``, we need to run ``setup.py develop`` to get WebTest installed into our virtualenv. Assuming our shell's current working directory is the "tutorial" distribution directory: @@ -87,7 +86,7 @@ On Windows: c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py test -q -The expected result ends something like: +The expected result should look like the following: .. code-block:: text -- cgit v1.2.3 From 4a8e9a385336ad1ebcd89801587c4242804d110a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 27 May 2015 03:48:07 -0700 Subject: clean up and make consistent across wikis --- docs/tutorials/wiki2/distributing.rst | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'docs/tutorials/wiki2') diff --git a/docs/tutorials/wiki2/distributing.rst b/docs/tutorials/wiki2/distributing.rst index 3b048a141..fee50a1cf 100644 --- a/docs/tutorials/wiki2/distributing.rst +++ b/docs/tutorials/wiki2/distributing.rst @@ -2,11 +2,11 @@ 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 virtualenv representing a :app:`Pyramid` environment. +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 virtualenv representing +a :app:`Pyramid` environment. On UNIX: @@ -25,18 +25,16 @@ The output of such a command will be something like: .. code-block:: text running sdist - # ... more output ... + # .. more output .. creating dist tar -cf dist/tutorial-0.0.tar tutorial-0.0 gzip -f9 dist/tutorial-0.0.tar removing 'tutorial-0.0' (and everything under it) -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 ``easy_install`` command directly at it. -Or you can upload it to `PyPI `_ and share it -with the rest of the world, where it can be downloaded via -``easy_install`` remotely like any other package people download from -PyPI. - +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 +``easy_install`` command directly at it. Or you can upload it to `PyPI +`_ and share it with the rest of the world, where it +can be downloaded via ``easy_install`` remotely like any other package people +download from PyPI. -- cgit v1.2.3 From b5096d71dc30839474f390b488440cc589da5879 Mon Sep 17 00:00:00 2001 From: orangieboot Date: Thu, 11 Jun 2015 21:56:31 +0100 Subject: Update authorization.rst Removed extra colons --- docs/tutorials/wiki2/authorization.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/tutorials/wiki2') diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst index d2ad7a9ca..1d810b05b 100644 --- a/docs/tutorials/wiki2/authorization.rst +++ b/docs/tutorials/wiki2/authorization.rst @@ -5,12 +5,12 @@ Adding authorization ==================== :app:`Pyramid` provides facilities for :term:`authentication` and -::term:`authorization`. We'll make use of both features to provide security -:to our application. Our application currently allows anyone with access to -:the server to view, edit, and add pages to our wiki. We'll change that to -:allow only people who are members of a *group* named ``group:editors`` to add -:and edit wiki pages but we'll continue allowing anyone with access to the -:server to view pages. +:term:`authorization`. We'll make use of both features to provide security +to our application. Our application currently allows anyone with access to +the server to view, edit, and add pages to our wiki. We'll change that to +allow only people who are members of a *group* named ``group:editors`` to add +and edit wiki pages but we'll continue allowing anyone with access to the +server to view pages. We will also add a login page and a logout link on all the pages. The login page will be shown when a user is denied access to any of the views that -- cgit v1.2.3 From 91dee884e9e4831e73a5d0a5c6a00e1e0f1397d9 Mon Sep 17 00:00:00 2001 From: nharringtonwasatch Date: Thu, 1 Oct 2015 13:52:12 -0400 Subject: wiki2 documentation precisely matches the scaffolding output --- docs/tutorials/wiki2/basiclayout.rst | 3 +++ docs/tutorials/wiki2/src/basiclayout/tutorial/models.py | 3 +++ 2 files changed, 6 insertions(+) (limited to 'docs/tutorials/wiki2') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 623882516..08132e8cd 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -247,5 +247,8 @@ The ``MyModel`` class has a ``__tablename__`` attribute. This informs SQLAlchemy which table to use to store the data representing instances of this class. +The Index import and the Index object creation is not required for this +tutorial, and will be removed in the next step. + That's about all there is to it regarding models, views, and initialization code in our stock application. diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py index 0cdd4bbc3..11ddccadb 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py @@ -2,6 +2,7 @@ from sqlalchemy import ( Column, Integer, Text, + Index, ) from sqlalchemy.ext.declarative import declarative_base @@ -22,3 +23,5 @@ class MyModel(Base): id = Column(Integer, primary_key=True) name = Column(Text, unique=True) value = Column(Integer) + +Index('my_index', MyModel.name, unique=True, mysql_length=255) -- cgit v1.2.3 From 301d7e7b7f9477e3d6dc5185707ebdd5b27c0b06 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Tue, 6 Oct 2015 19:52:05 -0600 Subject: Include the right line number from the .py file This was including a blank line. This mistake was caught when attempting to build a PDF file using latexpdf due to LaTeX not allowing certain sections to be blank. --- docs/tutorials/wiki2/basiclayout.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 08132e8cd..80ae4b34e 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -204,7 +204,7 @@ Let's examine this in detail. First, we need some imports to support later code: Next we set up a SQLAlchemy ``DBSession`` object: .. literalinclude:: src/basiclayout/tutorial/models.py - :lines: 16 + :lines: 17 :language: py ``scoped_session`` and ``sessionmaker`` are standard SQLAlchemy helpers. -- cgit v1.2.3