summaryrefslogtreecommitdiff
path: root/docs/tutorials/bfgwiki2/definingviews.rst
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-06-01 00:15:14 +0000
committerChris McDonough <chrism@agendaless.com>2009-06-01 00:15:14 +0000
commit6117c04a79d29b710391d95c5cce63358c5490fe (patch)
tree86ada0eee517b2a2ae53c51604d444e1183b30d0 /docs/tutorials/bfgwiki2/definingviews.rst
parentc2dbab3e024be02c4246746f3d7d9dc5da9219d8 (diff)
downloadpyramid-6117c04a79d29b710391d95c5cce63358c5490fe.tar.gz
pyramid-6117c04a79d29b710391d95c5cce63358c5490fe.tar.bz2
pyramid-6117c04a79d29b710391d95c5cce63358c5490fe.zip
Keep useful stuff.
Diffstat (limited to 'docs/tutorials/bfgwiki2/definingviews.rst')
-rw-r--r--docs/tutorials/bfgwiki2/definingviews.rst364
1 files changed, 0 insertions, 364 deletions
diff --git a/docs/tutorials/bfgwiki2/definingviews.rst b/docs/tutorials/bfgwiki2/definingviews.rst
deleted file mode 100644
index bf47c37ad..000000000
--- a/docs/tutorials/bfgwiki2/definingviews.rst
+++ /dev/null
@@ -1,364 +0,0 @@
-==============
-Defining Views
-==============
-
-Views in BFG are typically simple Python functions that accept two
-parameters: :term:`context`, and :term:`request`. A view is assumed
-to return a :term:`response` object.
-
-Adding View Functions
-=====================
-
-We're going to add four :term:`view` functions to our ``views.py``
-module. One view (named ``view_wiki``) will display the wiki itself
-(it will answer on the root URL), another named ``view_page`` will
-display an individual page, another named ``add_page`` will allow a
-page to be added, and a final view named ``edit_page`` will allow a
-page to be edited.
-
-.. note::
-
- There is nothing automagically special about the filename
- ``views.py``. A project may have many views throughout its codebase
- in arbitrarily-named files. Files implementing views 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 default view of a
-``Wiki`` model object. It always redirects to the ``Page`` object
-named "FrontPage". It returns an instance of the
-``webob.exc.HTTPFound`` class (instances of which implement the WebOb
-:term:`response` interface), and the ``repoze.bfg.model_url`` API.
-``model_url`` constructs a URL to the ``FrontPage`` page
-(e.g. ``http://localhost:6543/FrontPage``), and uses it as the
-"location" of the HTTPFound response, forming an HTTP redirect.
-
-The ``view_page`` view function
--------------------------------
-
-The ``view_page`` function will respond as the default view of a
-``Page`` object. The ``view_page`` function renders the
-:term:`ReStructuredText` body of a page (stored as the ``data``
-attribute of the context, which will be 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 (our
-page's ``__parent__``) 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 subsitution 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 call the
-``repoze.bfg.chameleon_zpt.render_template_to_response`` function with
-a number of arguments. The first argument is the *relative* path to a
-:term:`Chameleon` ZPT template. It is relative to the directory of
-the file in which we're creating the ``view_page`` function. The
-``render_template_to_response`` function also accepts ``request``,
-``page``, ``content``, and ``edit_url`` as keyword arguments. As a
-result, the template will be able to use these names to perform
-various rendering tasks.
-
-The result of ``render_template_to_response`` is returned to
-:mod:`repoze.bfg`. Unsurprisingly, it is a response object.
-
-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 ``context`` of the
-``add_page`` view is always a Wiki object (*not* a Page object).
-
-The request :term:`subpath` in BFG is the sequence of names that are
-found *after* the view name in the URL segments given to BFG as the
-result of a request. If our add view is invoked via,
-e.g. ``http://localhost:6543/add_page/SomeName``, the :term:`subpath`
-will be ``['SomeName']``.
-
-The add view takes the zeroth element of the subpath (the wiki page
-name), and aliases it to the name attribute in order to know the name
-of the page we're trying to add.
-
-If the view rendering is *not* a result of a form submission (if the
-expression ``'form.submitted' in request.params`` is False), the view
-renders a template. To do so, it generates a "save url" which the
-template use as the form post URL during rendering. We're lazy here,
-so we're trying to use the same template (``templates/edit.pt``) for
-the add view as well as the page edit view, 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 we'll render the template to a
-response.
-
-If the view rendering *is* a result of a form submission (if the
-expression ``'form.submitted' in request.params`` is True), we scrape
-the page body from the form data, create a Page object using the name
-in the subpath and the page body, and save it into "our context" (the
-wiki) using the ``__setitem__`` method of the context. We then
-redirect back to the ``view_page`` view (the default view for a page)
-for the newly created page.
-
-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 ``context``
-of the ``edit_page`` view will *always* be a Page object (never a Wiki
-object).
-
-If the view rendering 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 rendering *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`` attribute of the page context. It then redirects to the
-default view of the context (the 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 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
-
-
-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:
-
-.. literalinclude:: src/views/tutorial/templates/static/style.css
- :linenos:
- :language: css
-
-This CSS file will be accessed via
-e.g. ``http://localhost:6543/static/style.css`` by virtue of the
-``static_view`` view we've defined in the ``views.py`` 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.
-
-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
-``ViewTests`` test in the file, 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.
-
-Once we're done with the ``tests.py`` module, it will look a lot like
-the below:
-
-.. literalinclude:: src/views/tutorial/tests.py
- :linenos:
- :language: python
-
-Running the Tests
-=================
-
-We can run these tests by using ``setup.py test`` in the same way we
-did in :ref:`running_tests`. Assuming our shell's current working
-directory is the "tutorial" distribution directory:
-
-On UNIX:
-
-.. code-block:: bash
-
- $ ../bin/python setup.py test -q
-
-On Windows:
-
-.. code-block:: bash
-
-
- c:\bigfntut\tutorial> ..\Scripts\python setup.py test -q
-
-The expected result looks something like:
-
-.. code-block:: bash
-
- .........
- ----------------------------------------------------------------------
- Ran 9 tests in 0.203s
-
- OK
-
-Mapping Views to URLs in ``configure.zcml``
-===========================================
-
-The ``configure.zcml`` file contains ``view`` declarations which serve
-to map URLs (via :term:`traversal`) to view functions. You'll need to
-add five ``view`` declarations to ``configure.zcml``.
-
-#. Add a declaration which maps the "Wiki" class in our ``models.py``
- file to the view named ``static_view`` in our ``views.py`` file with
- the view name ``static``.
-
-#. Add a declaration which maps the "Wiki" class in our ``models.py``
- file to the view named ``view_wiki`` in our ``views.py`` file with
- no view name. This is the default view for a Wiki.
-
-#. Add a declaration which maps the "Page" class in our ``models.py``
- file to the view named ``view_page`` in our ``views.py`` file with
- no view name. This is the default view for a Page.
-
-#. Add a declaration which maps the "Wiki" class in our ``models.py``
- file to the view named ``add_page`` in our ``views.py`` file with
- the view name ``add_page``. This is the add view for a new Page.
-
-#. Add a declaration which maps the "Page" class in our ``models.py``
- file to the view named ``edit_page`` in our ``views.py`` file with
- the view name ``edit_page``. This is the edit view for a 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
-
-Examining ``tutorial.ini``
-==========================
-
-Let's take a look at our ``tutorial.ini`` file. The contents of the
-file are as follows:
-
-.. literalinclude:: src/models/tutorial.ini
- :linenos:
- :language: ini
-
-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.zodbconn#closer" is at the "top" of the pipeline. This is
-a piece of middleware which closes the ZODB connection opened by the
-PersistentApplicationFinder at the end of the request.
-
-"egg:repoze.tm#tm" is the second piece of middleware in the pipeline.
-This commits a transaction near the end of the request unless there's
-an exception raised.
-
-Adding an Element to the Pipeline
----------------------------------
-
-Let's add a piece of middleware to the WSGI pipeline.
-"egg:Paste#evalerror" middleware which displays debuggable errors in
-the browser while you're developing (not recommeded for deployment).
-Let's insert evalerror into the pipeline right below
-"egg:repoze.zodbconn#closer", 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/ <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/
- <http://localhost:6543/FrontPage/>`_ in a browser invokes the
- ``view_page`` view of the front page page object. This is because
- it's the *default view* (a view without a ``name``) for Page objects.
-
-- Visiting `http://localhost:6543/FrontPage/edit_page
- <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
- <http://localhost:6543/add_page/SomePageName>`_ in a browser invokes
- the add view for a page.
-
-- To generate an error, do `http://localhost:6543/add_page
- <http://localhost:6543/add_page>`_. IndexError for
- ``request.subpath[0]``. You'll see an interactive traceback
- facility provided by evalerror.
-
-
-
-
-