
Adding Wiki Pages
===================

Controller
------------

.. highlight:: python

Controllers are the code that figures out which page to display, what
data to grab from the model, how to process it, and finally hands off
that processed data to a template.

``quickstart`` has already created some basic controller code for us at
`wiki20/controllers/root.py`.  Here's what it looks like now:

.. literalinclude:: ../../project_code/wiki_root/snapshots/1/wiki20/controllers/root.py
   :linenos:

**8:** We must import the ``Page`` class  from our
model. At the end of the ``import`` block, add the line::

        from wiki20.model.page import Page

**12:** Change ``@expose('wiki20.templates.index')`` to::

       @expose('wiki20.templates.page')

so that the data returned by the ``index`` controller will now be
rendered by ``wiki20/templates/page.html``.
This requires us to create a new template named `page.html` in the
`wiki20/templates` directory; we'll do this in the next section.

**13:** We add a parameter to the ``index()`` method to specify the 
particular page we want to see by changing ``def index(self):`` to::

       def index(self, pagename="FrontPage"):

This tells the ``index()`` method to accept a parameter called
``pagename`` with a default value of ``"FrontPage"``.

**14:** Now let's get that page from our data model.  Put this line in the body
of ``index``::

       page = DBSession.query(Page).filter_by(pagename=pagename).one()

This line asks the SQLAlchemy database session object to run a query
for records of the ``page`` table with ``pagename`` column equal to the value of the
``pagename`` parameter passed to our controller method.
A ``.query`` call generally returns a list of matching objects. 
We only want one page, so we add the ``.one()`` method to assure 
only one returned result.

**15:** Finally, we need to return a dictionary containing the ``page`` we just looked
up.  When we say::

      return dict(wikipage=page)

the returned ``dict`` will create a template variable called ``wikipage`` that
will evaluate to the ``page`` object that we looked up.

Here's the whole file after incorporating the above modifications:

.. literalinclude::  ../../project_code/wiki_root/snapshots/2/wiki20/controllers/root.py
   :linenos:

Now our ``index()`` method fetches a record from the database (creating
an instance of our mapped ``Page`` class along the way), and returns it
to the template within a dictionary.

.. _adding_views:


View (Template)
------------------

.. highlight:: html

``quickstart`` created some html templates for us in the
`wiki20/templates` directory: `master.html` and
`index.html`.  Back in our simple controller, the quickstart-generate
code used ``@expose()`` to hand off a dictionary of data to a template called
``'wiki20.templates.index'``, corresponding to the file
`wiki20/templates/index.html`.


.. literalinclude:: ../../project_code/wiki_root/snapshots/2/wiki20/templates/index.html
   :linenos:

Copy the contents of `index.html` into a new file called `page.html` in the
same directory.

.. code-block::  bash

      $ cd wiki20/templates
      $ cp index.html page.html

Now modify it for our purposes:

.. literalinclude:: ../../project_code/wiki_root/snapshots/1/wiki20/templates/page.html
   :linenos:

This is a basic XHTML page with three substitutions:

**11:** in the ``<title>`` tag, we substitute the name of the page, using
the ``pagename`` value of ``page``.  (Remember, ``wikipage`` is an instance
of our mapped ``Page`` class, which was passed in a dictionary by our
controller.)

**17** in the second ``<div>`` element, we substitute the page
name again with Genshi's ``py:replace``:

     .. code:: wiki_root/snapshots/2/wiki20/templates/page.html
        :section: PageName

**21:** In the third ``<div>``, we put in the contents of our ``wikipage``:

     .. code:: wiki_root/snapshots/2/wiki20/templates/page.html
        :section: PageContent

When you refresh the output web page you should see "initial data" displayed on the page.


