============
Basic Layout
============

The starter files generated by the ``pyramid_routesalchemy`` scaffold are
basic, but they provide a good orientation for the high-level patterns common
to most :term:`url dispatch` -based :app:`Pyramid` projects.

The source code for this tutorial stage can be browsed at
`http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki2/src/basiclayout/
<http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki2/src/basiclayout/>`_.

App Startup 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 package marker and to contain
configuration code.

The generated ``development.ini`` file is read by ``paster`` which looks for
the application module in the ``use`` variable of the ``app:tutorial``
section. The *entry point* is defined in the Setuptools configuration of this
module, specifically in the ``setup.py`` file. For this tutorial, the *entry
point* is defined as ``tutorial:main`` and points to a function named ``main``.

First we need some imports to support later code:

   .. literalinclude:: src/basiclayout/tutorial/__init__.py
      :end-before: main
      :linenos:
      :language: py

Next we define the main function and create a SQLAlchemy database engine from
the ``sqlalchemy.`` prefixed settings in the ``development.ini`` file's
``[app:tutorial]`` section.  This will be a URI (something like
``sqlite://``):

   .. literalinclude:: src/basiclayout/tutorial/__init__.py
      :lines: 6-9
      :linenos:
      :language: py

We then initialize our SQL database using SQLAlchemy, passing
it the engine:

   .. literalinclude:: src/basiclayout/tutorial/__init__.py
      :lines: 10
      :language: py

The next step is to construct a :term:`Configurator`:

   .. literalinclude:: src/basiclayout/tutorial/__init__.py
      :lines: 11
      :language: py

``settings`` is passed to the Configurator as a keyword argument with the
dictionary values passed by PasteDeploy as the ``**settings`` argument.  This
will be a dictionary of settings parsed from the ``.ini`` file, which
contains deployment-related values such as ``reload_templates``,
``db_string``, etc.

We now can call :meth:`pyramid.config.Configurator.add_static_view` with the
arguments ``static`` (the name), and ``tutorial:static`` (the path):

   .. literalinclude:: src/basiclayout/tutorial/__init__.py
      :lines: 12
      :language: py

This registers a static resource view which will match any URL that starts with
``/static/``.  This will serve up static resources for us from within the
``static`` directory of our ``tutorial`` package, in this case,
via ``http://localhost:6543/static/`` and below.  With this declaration,
we're saying that any URL that starts with ``/static`` should go to the
static view; any remainder of its path (e.g. the ``/foo`` in
``/static/foo``) will be used to compose a path to a static file resource,
such as a CSS file.

Using the configurator we can also register a :term:`route configuration`
via the :meth:`pyramid.config.Configurator.add_route` method that will be
used when the URL is ``/``:

   .. literalinclude:: src/basiclayout/tutorial/__init__.py
      :lines: 13
      :language: py

Since this route has a ``pattern`` equalling ``/`` it is the route that will
be matched when the URL ``/`` is visted, e.g. ``http://localhost:6543/``.

Mapping the ``home`` route to code is done by registering a view. You will
use :meth:`pyramid.config.Configurator.add_view` in :term:`URL dispatch` to
register views for the routes, mapping your patterns to code:

   .. literalinclude:: src/basiclayout/tutorial/__init__.py
      :lines: 14-15
      :language: py

The first positional ``add_view`` argument ``tutorial.views.my_view`` is the
dotted name to a *function* we write (generated by the
``pyramid_routesalchemy`` scaffold) that is given a ``request`` object and
which returns a response or a dictionary.  This view also names a
``renderer``, which is a template which lives in the ``templates``
subdirectory of the package.  When the ``tutorial.views.my_view`` view
returns a dictionary, a :term:`renderer` will use this template to create a
response.

Finally, we use the :meth:`pyramid.config.Configurator.make_wsgi_app`
method to return a :term:`WSGI` application:

   .. literalinclude:: src/basiclayout/tutorial/__init__.py
      :lines: 16
      :language: py

Our final ``__init__.py`` file will look like this:

   .. literalinclude:: src/basiclayout/tutorial/__init__.py
      :linenos:
      :language: py

Content Models with ``models.py``
---------------------------------

In a SQLAlchemy-based application, a *model* object is an object
composed by querying the SQL database which backs an application.
SQLAlchemy is an "object relational mapper" (an ORM).  The
``models.py`` file is where the ``pyramid_routesalchemy`` scaffold
put the classes that implement our models.

Let's take a look. First, we need some imports to support later code.

   .. literalinclude:: src/basiclayout/tutorial/models.py
      :end-before: DBSession
      :linenos:
      :language: py

Next we set up a SQLAlchemy "DBSession" object:

   .. literalinclude:: src/basiclayout/tutorial/models.py
      :lines: 15-16
      :linenos:
      :language: py

We also need to create a declarative ``Base`` object to use as a
base class for our model:

   .. literalinclude:: src/basiclayout/tutorial/models.py
      :lines: 17
      :language: py

To give a simple example of a  model class, we define one named ``MyModel``:

   .. literalinclude:: src/basiclayout/tutorial/models.py
      :pyobject: MyModel
      :linenos:
      :language: py

Our sample model has an ``__init__`` that takes a two arguments (``name``,
and ``value``).  It stores these values as ``self.name`` and ``self.value``
within the ``__init__`` function itself.  The ``MyModel`` class also has a
``__tablename__`` attribute.  This informs SQLAlchemy which table to use to
store the data representing instances of this class.

Next we define a function named ``populate`` which adds a single
model instance into our SQL storage and commits a transaction:

   .. literalinclude:: src/basiclayout/tutorial/models.py
      :pyobject: populate
      :linenos:
      :language: py

The function doesn't do a lot in this case, but it's there to illustrate
how an application requiring many objects to be set up could work.

Lastly we have a function named ``initialize_sql`` which receives a SQL
database engine and binds it to our SQLAlchemy DBSession object.  It also
calls the ``populate`` function, to do initial database population. This
is the initialization function that is called from __init__.py above.

   .. literalinclude:: src/basiclayout/tutorial/models.py
      :pyobject: initialize_sql
      :linenos:
      :language: py

Here is the complete source for ``models.py``:

   .. literalinclude:: src/basiclayout/tutorial/models.py
      :linenos:
      :language: py

