summaryrefslogtreecommitdiff
path: root/docs/tutorials/bfgwiki2/definingviews.rst
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2010-10-25 17:58:23 -0400
committerChris McDonough <chrism@plope.com>2010-10-25 17:58:23 -0400
commitc426c49cd433997aac10045052d77d9c749680b2 (patch)
tree4dc3c7664ad9492b80771eb9c55fa0d2bfe22162 /docs/tutorials/bfgwiki2/definingviews.rst
parente26700528995b1807c5e55a4295a6f788a5603de (diff)
downloadpyramid-c426c49cd433997aac10045052d77d9c749680b2.tar.gz
pyramid-c426c49cd433997aac10045052d77d9c749680b2.tar.bz2
pyramid-c426c49cd433997aac10045052d77d9c749680b2.zip
remove bfgwiki2 old dir
Diffstat (limited to 'docs/tutorials/bfgwiki2/definingviews.rst')
-rw-r--r--docs/tutorials/bfgwiki2/definingviews.rst402
1 files changed, 0 insertions, 402 deletions
diff --git a/docs/tutorials/bfgwiki2/definingviews.rst b/docs/tutorials/bfgwiki2/definingviews.rst
deleted file mode 100644
index c33795883..000000000
--- a/docs/tutorials/bfgwiki2/definingviews.rst
+++ /dev/null
@@ -1,402 +0,0 @@
-==============
-Defining Views
-==============
-
-A :term:`view callable` in a :term:`url dispatch` -based
-:mod:`repoze.bfg` application is typically a simple Python function
-that accepts a single parameter named :term:`request`. A view
-callable is assumed to return a :term:`response` object.
-
-.. note:: A :mod:`repoze.bfg` view can also be defined as callable
- which accepts *two* arguments: a :term:`context` and a
- :term:`request`. You'll see this two-argument pattern used in
- other :mod:`repoze.bfg` tutorials and applications. Either calling
- convention will work in any :mod:`repoze.bfg` application; the
- calling conventions can be used interchangeably as necessary. In
- :term:`url dispatch` based applications, however, the context
- object is rarely used in the view body itself, so within this
- tutorial we define views as callables that accept only a request to
- avoid the visual "noise". If you do need the ``context`` within a
- view function that only takes the request as a single argument, you
- can obtain it via ``request.context``.
-
-The request passed to every view that is called as the result of a
-route match has an attribute named ``matchdict`` that contains the
-elements placed into the URL by the ``pattern`` of a ``route``
-statement. For instance, if a route statement in ``configure.zcml``
-had the pattern ``:one/:two``, and the URL at
-``http://example.com/foo/bar`` was invoked, matching this pattern, the
-matchdict dictionary attached to the request passed to the view would
-have a ``one`` key with the value ``foo`` and a ``two`` key with the
-value ``bar``.
-
-The source code for this tutorial stage can be browsed at
-`docs.repoze.org <http://docs.repoze.org/bfgwiki2-1.3/views>`_.
-
-Declaring Dependencies in Our ``setup.py`` File
-===============================================
-
-The view code in our application will depend on a package which is not
-a dependency of the original "tutorial" application. The original
-"tutorial" application was generated by the ``paster create`` 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
-``install_requires`` parameter in the ``setup`` function.
-
-Our resulting ``setup.py`` should look like so:
-
-.. literalinclude:: src/views/setup.py
- :linenos:
- :language: python
-
-.. note:: After these new dependencies are 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 package.
-
-Adding View Functions
-=====================
-
-We'll get rid of our ``my_view`` view function in our ``views.py``
-file. It's only an example and isn't relevant to our application.
-
-Then we're going to add four :term:`view callable` functions to our
-``views.py`` module. One view callable (named ``view_wiki``) will
-display the wiki itself (it will answer on the root URL), another
-named ``view_page`` will display an individual page, another named
-``add_page`` will allow a page to be added, and a final view callable
-named ``edit_page`` will allow a page to be edited. We'll describe
-each one briefly and show the resulting ``views.py`` file afterward.
-
-.. note::
-
- There is nothing special about the filename ``views.py``. A project
- may 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.
-
-The ``view_wiki`` view function
--------------------------------
-
-The ``view_wiki`` function will respond as the :term:`default view` of
-a ``Wiki`` model object. It always redirects to a URL which
-represents the path to our "FrontPage". It returns an instance of the
-:class:`webob.exc.HTTPFound` class (instances of which implement the
-WebOb :term:`response` interface), It will use the
-:func:`repoze.bfg.url.route_url` API to construct a URL to the
-``FrontPage`` page (e.g. ``http://localhost:6543/FrontPage``), and
-will use it as the "location" of the HTTPFound response, forming an
-HTTP redirect.
-
-The ``view_page`` view function
--------------------------------
-
-The ``view_page`` function will respond as the :term:`default view` of
-a ``Page`` object. The ``view_page`` function renders the
-:term:`ReStructuredText` body of a page (stored as the ``data``
-attribute of a Page 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, the ``check``
-function generates a view link to be used as the substitution value
-and returns it. If the wiki does not already contain a page with with
-the matched WikiWord name, the function generates an "add" link as the
-substitution value and returns it.
-
-As a result, the ``content`` variable is now a fully formed bit of
-HTML containing various view and add links for WikiWords based on the
-content of our current page object.
-
-We then generate an edit URL (because it's easier to do here than in
-the template), and we return a dictionary with a number of arguments.
-The fact that this view returns a dictionary (as opposed to a
-:term:`response` object) is a cue to :mod:`repoze.bfg` that it should
-try to use a :term:`renderer` associated with the view configuration
-to render a template. In our case, the template which will be
-rendered will be the ``templates/view.pt`` template, as per the
-configuration put into effect in ``configure.zcml``.
-
-The ``add_page`` view function
-------------------------------
-
-The ``add_page`` function will be invoked when a user clicks on a
-*WikiWord* which isn't yet represented as a page in the system. The
-``check`` function within the ``view_page`` view generates URLs to
-this view. It also acts as a handler for the form that is generated
-when we want to add a page object. The ``matchdict`` attribute of the
-request passed to the ``add_page`` view will have the values we need
-to construct URLs and find model objects.
-
-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 ``pagename``
-value in the matchdict will be ``SomeName``.
-
-If the view execution is *not* a result of a form submission (if 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 template use as the form post URL during rendering. We're
-lazy here, so we're trying to use the same template
-(``templates/edit.pt``) for the add view as well as the page edit
-view, so we create a dummy Page object in order to satisfy the edit
-form's desire to have *some* page object exposed as ``page``, and
-:mod:`repoze.bfg` will render the template associated with this view
-to a response.
-
-If the view execution *is* a result of a form submission (if the
-expression ``'form.submitted' in request.params`` is ``True``), we
-scrape the page body from the form data, create a Page object using
-the name in the matchdict ``pagename``, and obtain the page body from
-the request, and save it into the database using ``session.add``. We
-then redirect back to the ``view_page`` view (the :term:`default view`
-for a Page) for the newly created page.
-
-The ``edit_page`` view function
--------------------------------
-
-The ``edit_page`` function will be invoked when a user clicks the
-"Edit this Page" button on the view form. It renders an edit form but
-it also acts as the handler for the form it renders. The
-``matchdict`` attribute of the request passed to the ``add_page`` view
-will have a ``pagename`` key matching the name of the page the user
-wants to edit.
-
-If the view execution is *not* a result of a form submission (if the
-expression ``'form.submitted' in request.params`` is ``False``), the
-view simply renders the edit form, passing the request, the page
-object, and a save_url which will be used as the action of the
-generated form.
-
-If the view execution *is* a result of a form submission (if the
-expression ``'form.submitted' in request.params`` is ``True``), the
-view grabs the ``body`` element of the request parameter and sets it
-as the ``data`` key in the matchdict. It then redirects to the
-default view of the wiki page, which will always be the ``view_page``
-view.
-
-Viewing the Result of Our Edits to ``views.py``
-===============================================
-
-The result of all of our edits to ``views.py`` will leave it looking
-like this:
-
-.. literalinclude:: src/views/tutorial/views.py
- :linenos:
- :language: python
-
-Adding Templates
-================
-
-The views we've added all reference a :term:`template`. Each template
-is a :term:`Chameleon` template. The default templating system in
-:mod:`repoze.bfg` is a variant of :term:`ZPT` provided by
-:term:`Chameleon`. These templates will live in the ``templates``
-directory of our tutorial package.
-
-The ``view.pt`` Template
-------------------------
-
-The ``view.pt`` template is used for viewing a single wiki page. It
-is used by the ``view_page`` view function. It should have a div that
-is "structure replaced" with the ``content`` value provided by the
-view. It should also have a link on the rendered page that points at
-the "edit" URL (the URL which invokes the ``edit_page`` view for the
-page being viewed).
-
-Once we're done with the ``view.pt`` template, it will look a lot like
-the below:
-
-.. literalinclude:: src/views/tutorial/templates/view.pt
- :linenos:
- :language: xml
-
-.. note:: The names available for our use in a template are always
- those that are present in the dictionary returned by the view
- callable. But our templates make use of a ``request`` object that
- none of our tutorial views return in their dictionary. This value
- appears as if "by magic". However, ``request`` is one of several
- names that are available "by default" in a template when a template
- renderer is used. See :ref:`chameleon_template_renderers` for more
- information about other names that are available by default in a
- template when a Chameleon template is used as a renderer.
-
-The ``edit.pt`` Template
-------------------------
-
-The ``edit.pt`` template is used for adding and editing a wiki page.
-It is used by the ``add_page`` and ``edit_page`` view functions. It
-should display a page containing a form that POSTs back to the
-"save_url" argument supplied by the view. The form should have a
-"body" textarea field (the page data), and a submit button that has
-the name "form.submitted". The textarea in the form should be filled
-with any existing page data when it is rendered.
-
-Once we're done with the ``edit.pt`` template, it will look a lot like
-the below:
-
-.. literalinclude:: src/views/tutorial/templates/edit.pt
- :linenos:
- :language: xml
-
-Static Resources
-----------------
-
-Our templates name a single static resource named ``style.css``. We
-need to create this and place it in a file named ``style.css`` within
-our package's ``templates/static`` directory. This file is a little
-too long to replicate within the body of this guide, however it is
-available `online
-<http://docs.repoze.org/bfgwiki2-1.2/views/tutorial/templates/static/style.css>`_.
-
-This CSS file will be accessed via
-e.g. ``http://localhost:6543/static/style.css`` by virtue of the
-``<static>`` directive we've defined in the ``configure.zcml`` file.
-Any number and type of static resources can be placed in this
-directory (or subdirectories) and are just referred to by URL within
-templates.
-
-Mapping Views to URLs in ``configure.zcml``
-===========================================
-
-The ``configure.zcml`` file contains ``route`` declarations (and a
-lone ``view`` declaration) which serve to map URLs via :term:`url
-dispatch` to view functions. First, we’ll get rid of the existing
-``route`` created by the template using the name ``home``. It’s only
-an example and isn’t relevant to our application.
-
-We then need to add four ``route`` declarations to ``configure.zcml``.
-Note that the *ordering* of these declarations is very important.
-``route`` declarations are matched in the order they're found in the
-``configure.zcml`` file.
-
-#. Add a declaration which maps the empty pattern (signifying the root
- URL) to the view named ``view_wiki`` in our ``views.py`` file with
- the name ``view_wiki``. This is the :term:`default view` for the
- wiki.
-
-#. Add a declaration which maps the pattern ``:pagename`` to the
- view named ``view_page`` in our ``views.py`` file with the view
- name ``view_page``. This is the regular view for a page.
-
-#. Add a declaration which maps the pattern
- ``:pagename/edit_page`` to the view named ``edit_page`` in our
- ``views.py`` file with the name ``edit_page``. This is the edit view
- for a page.
-
-#. Add a declaration which maps the pattern
- ``add_page/:pagename`` to the view named ``add_page`` in our
- ``views.py`` file with the name ``add_page``. This is the add view
- for a new page.
-
-As a result of our edits, the ``configure.zcml`` file should look
-something like so:
-
-.. literalinclude:: src/views/tutorial/configure.zcml
- :linenos:
- :language: xml
-
-The WSGI Pipeline
------------------
-
-Within ``tutorial.ini``, note the existence of a ``[pipeline:main]``
-section which specifies our WSGI pipeline. This "pipeline" will be
-served up as our WSGI application. As far as the WSGI server is
-concerned the pipeline *is* our application. Simpler configurations
-don't use a pipeline: instead they expose a single WSGI application as
-"main". Our setup is more complicated, so we use a pipeline.
-
-``egg:repoze.tm2#tm`` is at the "top" of the pipeline. This is a
-piece of middleware which commits a transaction if no exception
-occurs; if an exception occurs, the transaction will be aborted. This
-is the piece of software that allows us to forget about needing to do
-manual commits and aborts of our database connection in view code.
-
-Adding an Element to the Pipeline
----------------------------------
-
-Let's add a piece of middleware to the WSGI pipeline. We'll add
-``egg:Paste#evalerror`` middleware which displays debuggable errors in
-the browser while you're developing (this is *not* recommended for
-deployment as it is a security risk). Let's insert evalerror into the
-pipeline right above ``egg:repoze.tm2#tm``, making our resulting
-``tutorial.ini`` file look like so:
-
-.. literalinclude:: src/views/tutorial.ini
- :linenos:
- :language: ini
-
-Viewing the Application in a Browser
-====================================
-
-Once we've set up the WSGI pipeline properly, we can finally examine
-our application in a browser. The views we'll try are as follows:
-
-- Visiting ``http://localhost:6543`` in a browser invokes the
- ``view_wiki`` view. This always redirects to the ``view_page`` view
- of the FrontPage page object.
-
-- Visiting ``http://localhost:6543/FrontPage`` in a browser invokes
- the ``view_page`` view of the front page page object.
-
-- Visiting ``http://localhost:6543/FrontPage/edit_page`` in a browser
- invokes the edit view for the front page object.
-
-- Visiting ``http://localhost:6543/add_page/SomePageName`` in a
- browser invokes the add view for a page.
-
-Try generating an error within the body of a view by adding code to
-the top of it that generates an exception (e.g. ``raise
-Exception('Forced Exception')``). Then visit the error-raising view
-in a browser. You should see an interactive exception handler in the
-browser which allows you to examine values in a post-mortem mode.
-
-Adding Tests
-============
-
-Since we've added a good bit of imperative code here, it's useful to
-define tests for the views we've created. We'll change our tests.py
-module to look like this:
-
-.. literalinclude:: src/views/tutorial/tests.py
- :linenos:
- :language: python
-
-We can then run the tests using something like:
-
-.. code-block:: text
- :linenos:
-
- $ python setup.py test -q
-
-The expected output is something like:
-
-.. code-block:: text
- :linenos:
-
- running test
- running egg_info
- writing requirements to tutorial.egg-info/requires.txt
- writing tutorial.egg-info/PKG-INFO
- writing top-level names to tutorial.egg-info/top_level.txt
- writing dependency_links to tutorial.egg-info/dependency_links.txt
- writing entry points to tutorial.egg-info/entry_points.txt
- unrecognized .svn/entries format in
- reading manifest file 'tutorial.egg-info/SOURCES.txt'
- writing manifest file 'tutorial.egg-info/SOURCES.txt'
- running build_ext
- ......
- ----------------------------------------------------------------------
- Ran 6 tests in 0.181s
-
- OK
-
-
-
-