summaryrefslogtreecommitdiff
path: root/docs/tutorials/wiki/basiclayout.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tutorials/wiki/basiclayout.rst')
-rw-r--r--docs/tutorials/wiki/basiclayout.rst109
1 files changed, 62 insertions, 47 deletions
diff --git a/docs/tutorials/wiki/basiclayout.rst b/docs/tutorials/wiki/basiclayout.rst
index cdf52b73e..49ee6902e 100644
--- a/docs/tutorials/wiki/basiclayout.rst
+++ b/docs/tutorials/wiki/basiclayout.rst
@@ -1,44 +1,60 @@
+.. _wiki_basic_layout:
+
============
Basic Layout
============
-The starter files generated by the ``zodb`` scaffold are basic, but
-they provide a good orientation for the high-level patterns common to most
-:term:`traversal` -based :app:`Pyramid` (and :term:`ZODB` -based) projects.
+The starter files generated by selecting the ``zodb`` backend in the
+cookiecutter are very basic, but they provide a good orientation for the
+high-level patterns common to most :term:`traversal`-based (and
+:term:`ZODB`-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. Our application uses ``__init__.py`` both as a package marker and
-to contain application 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.
When you run the application using the ``pserve`` command using the
-``development.ini`` generated config file, the application configuration
-points at a Setuptools *entry point* described as ``egg:tutorial``. In our
-application, because the application's ``setup.py`` file says so, this entry
-point happens to be the ``main`` function within the file named
-``__init__.py``:
+``development.ini`` generated configuration file, the application
+configuration points at a :term:`Setuptools` :term:`entry point` described as
+``egg:tutorial``. In our application, because the application's ``setup.py``
+file says so, this entry point happens to be the ``main`` function within the
+file named ``__init__.py``.
+
+Open ``tutorial/__init__.py``. It should already contain the following:
- .. literalinclude:: src/basiclayout/tutorial/__init__.py
- :linenos:
- :language: py
+.. literalinclude:: src/basiclayout/tutorial/__init__.py
+ :linenos:
+ :language: py
#. *Lines 1-3*. Perform some dependency imports.
-#. *Lines 6-8*. Define a root factory for our Pyramid application.
+#. *Lines 6-8*. Define a :term:`root factory` for our Pyramid application.
+
+#. *Line 11*. ``__init__.py`` defines a function named ``main``.
+
+#. *Line 14*. Use an explicit transaction manager for apps so that they do not implicitly create new transactions when touching the manager outside of the ``pyramid_tm`` lifecycle.
-#. *Line 14*. We construct a :term:`Configurator` with a :term:`root
- factory` and the settings keywords parsed by :term:`PasteDeploy`. The root
- factory is named ``root_factory``.
+#. *Line 15*. Construct a :term:`Configurator` as a :term:`context manager` with the settings keyword parsed by :term:`PasteDeploy`.
-#. *Line 15*. Include support for the :term:`Chameleon` template rendering
+#. *Line 16*. Include support for the :term:`Chameleon` template rendering
bindings, allowing us to use the ``.pt`` templates.
-#. *Line 16*. Register a "static view" which answers requests whose URL path
- start with ``/static`` using the
+#. *Line 17*. Include support for ``pyramid_tm``, allowing Pyramid requests to join the active transaction as provided by the `transaction <https://pypi.org/project/transaction/>`_ package.
+
+#. *Line 18*. Include support for ``pyramid_retry`` to retry a request when transient exceptions occur.
+
+#. *Line 19*. Include support for ``pyramid_zodbconn``, providing integration between :term:`ZODB` and a Pyramid application.
+
+#. *Line 20*. Set a root factory using our function named ``root_factory``.
+
+#. *Line 21*. Register a "static view", which answers requests whose URL
+ paths start with ``/static``, using the
:meth:`pyramid.config.Configurator.add_static_view` method. This
statement registers a view that will serve up static assets, such as CSS
and image files, for us, in this case, at
@@ -47,23 +63,23 @@ point happens to be the ``main`` function within the file named
will be ``/static``. The second argument of this tag is the "path",
which is a relative :term:`asset specification`, so it finds the resources
it should serve within the ``static`` directory inside the ``tutorial``
- package. Alternatively the scaffold could have used an *absolute* asset
+ package. Alternatively the cookiecutter could have used an *absolute* asset
specification as the path (``tutorial:static``).
-#. *Line 17*. Perform a :term:`scan`. A scan will find :term:`configuration
+#. *Line 22*. Perform a :term:`scan`. A scan will find :term:`configuration
decoration`, such as view configuration decorators (e.g., ``@view_config``)
in the source code of the ``tutorial`` package and will take actions based
on these decorators. We don't pass any arguments to
:meth:`~pyramid.config.Configurator.scan`, which implies that the scan
should take place in the current package (in this case, ``tutorial``).
- The scaffold could have equivalently said ``config.scan('tutorial')``, but
+ The cookiecutter could have equivalently said ``config.scan('tutorial')``, but
it chose to omit the package name argument.
-#. *Line 18*. Use the
+#. *Line 23*. Use the
:meth:`pyramid.config.Configurator.make_wsgi_app` method
to return a :term:`WSGI` application.
-Resources and Models with ``models.py``
+Resources and models with ``models.py``
---------------------------------------
:app:`Pyramid` uses the word :term:`resource` to describe objects arranged
@@ -72,47 +88,46 @@ hierarchically in a :term:`resource tree`. This tree is consulted by
tree represents the site structure, but it *also* represents the
:term:`domain model` of the application, because each resource is a node
stored persistently in a :term:`ZODB` database. The ``models.py`` file is
-where the ``zodb`` scaffold put the classes that implement our
+where the ``zodb`` cookiecutter put the classes that implement our
resource objects, each of which also happens to be a domain model object.
Here is the source for ``models.py``:
- .. literalinclude:: src/basiclayout/tutorial/models.py
- :linenos:
- :language: py
+.. literalinclude:: src/basiclayout/tutorial/models.py
+ :linenos:
+ :language: python
#. *Lines 4-5*. The ``MyModel`` :term:`resource` class is implemented here.
Instances of this class are capable of being persisted in :term:`ZODB`
because the class inherits from the
:class:`persistent.mapping.PersistentMapping` class. The ``__parent__``
and ``__name__`` are important parts of the :term:`traversal` protocol.
- By default, have these as ``None`` indicating that this is the
+ By default, set these to ``None`` to indicate that this is the
:term:`root` object.
-#. *Lines 8-14*. ``appmaker`` is used to return the *application
+#. *Lines 8-12*. ``appmaker`` is used to return the *application
root* object. It is called on *every request* to the
:app:`Pyramid` application. It also performs bootstrapping by
*creating* an application root (inside the ZODB root object) if one
- does not already exist. It is used by the "root_factory" we've defined
+ does not already exist. It is used by the ``root_factory`` we've defined
in our ``__init__.py``.
- We do so by first seeing if the database has the persistent
- application root. If not, we make an instance, store it, and
- commit the transaction. We then return the application root
- object.
+ Bootstrapping is done by first seeing if the database has the persistent
+ application root. If not, we make an instance, store it, and commit the
+ transaction. We then return the application root object.
Views With ``views.py``
-----------------------
-Our scaffold generated a default ``views.py`` on our behalf. It
+Our cookiecutter generated a default ``views.py`` on our behalf. It
contains a single view, which is used to render the page shown when you visit
the URL ``http://localhost:6543/``.
Here is the source for ``views.py``:
- .. literalinclude:: src/basiclayout/tutorial/views.py
- :linenos:
- :language: py
+.. literalinclude:: src/basiclayout/tutorial/views.py
+ :linenos:
+ :language: python
Let's try to understand the components in this module:
@@ -150,7 +165,7 @@ Let's try to understand the components in this module:
#. *Lines 6-7*. We define a :term:`view callable` named ``my_view``, which
we decorated in the step above. This view callable is a *function* we
- write generated by the ``zodb`` scaffold that is given a
+ write generated by the ``zodb`` cookiecutter that is given a
``request`` and which returns a dictionary. The ``mytemplate.pt``
:term:`renderer` named by the asset specification in the step above will
convert this dictionary to a :term:`response` on our behalf.
@@ -162,15 +177,15 @@ Let's try to understand the components in this module:
Configuration in ``development.ini``
------------------------------------
-The ``development.ini`` (in the tutorial :term:`project` directory, as
-opposed to the tutorial :term:`package` directory) looks like this:
+The ``development.ini`` (in the ``tutorial`` :term:`project` directory, as
+opposed to the ``tutorial`` :term:`package` directory) looks like this:
.. literalinclude:: src/basiclayout/development.ini
- :language: ini
+ :language: ini
Note the existence of a ``[app:main]`` section which specifies our WSGI
application. Our ZODB database settings are specified as the
``zodbconn.uri`` setting within this section. This value, and the other
-values within this section are passed as ``**settings`` to the ``main``
+values within this section, are passed as ``**settings`` to the ``main``
function we defined in ``__init__.py`` when the server is started via
``pserve``.