summaryrefslogtreecommitdiff
path: root/docs/tutorials/bfgwiki2/basiclayout.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tutorials/bfgwiki2/basiclayout.rst')
-rw-r--r--docs/tutorials/bfgwiki2/basiclayout.rst104
1 files changed, 104 insertions, 0 deletions
diff --git a/docs/tutorials/bfgwiki2/basiclayout.rst b/docs/tutorials/bfgwiki2/basiclayout.rst
new file mode 100644
index 000000000..1ec10094e
--- /dev/null
+++ b/docs/tutorials/bfgwiki2/basiclayout.rst
@@ -0,0 +1,104 @@
+============
+Basic Layout
+============
+
+The starter files generated by the ``bfg_zodb`` template are basic,
+but they provide a good orientation for the high-level patterns common
+to most :term:`traversal` -based BFG (and BFG with ZODB) projects.
+
+``__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.
+
+Configuration With ``configure.zcml``
+--------------------------------------
+
+BFG uses a markup language syntactically the same as Zope's
+implementation of :term:`ZCML`, but using a different default XML
+namespace. Our sample ZCML file looks like the following:
+
+ .. literalinclude:: src/basiclayout/tutorial/configure.zcml
+ :linenos:
+ :language: xml
+
+#. *Line 1*. The root ``<configure>`` element, in a *BFG* namespace.
+
+#. *Line 3*. Boilerplate, the comment explains.
+
+#. *Lines 6-9*. Register a ``<view>`` that is bound to a class.
+ ``.views.my_view`` is a *function* we write (generated by the
+ ``bfg_zodb`` template) that is given a ``context`` and a
+ ``request`` and returns a response.
+
+ Since this ``<view>`` doesn't have a ``name`` attribute, it is the
+ "default" view for that class.
+
+#. *Lines 11-15*. Register a view on the ``MyModels`` class that
+ answers URL segments of ``static``. This is a view that will serve
+ up static resources for us, in this case, at
+ ``http://localhost:6543/static/`` and below.
+
+Content Models with ``models.py``
+---------------------------------
+
+BFG often uses the word *model* when talking about content resources
+arranged in a hierarchical *model graph*. The ``models.py`` file is
+where the ``bfg_zodb`` Paster template put the classes that implement
+our models.
+
+Here is the source for ``models.py``:
+
+ .. literalinclude:: src/basiclayout/tutorial/models.py
+ :linenos:
+ :language: py
+
+#. *Lines 3-4*. The ``MyModel`` class we referred to in the ZCML is
+ implemented here. It is persistent (via PersistentMapping). The
+ ``__parent__`` and ``__name__`` are important parts of the
+ traversal protocol. By default, have these as ``None`` indicating
+ that this is the :term:`root` object.
+
+#. *Lines 6-12*. ``appmaker`` is used to return the *application
+ root* object. It is called on *every request* to the BFG
+ application (it is essentially a :term:`root factory`). It also
+ performs bootstrapping by *creating* an application root (inside
+ the ZODB root object) if one does not already exist.
+
+ 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.
+
+App Startup with ``run.py``
+---------------------------
+
+How does a BFG application start up? When you run under ``paster``
+using the ``tutorial.ini`` generated config file, the application area
+points at an entry point. Our entry point happens to be in ``run.py``
+and its ``app`` function:
+
+ .. literalinclude:: src/basiclayout/tutorial/run.py
+ :linenos:
+ :language: py
+
+#. *Line 11*. After importing our application, get the ``appmaker``
+ function described above.
+
+#. *Line 12*. Get the ZODB configuration from the ``tutorial.ini``
+ file's ``[app:main]`` section. This will be a URI (something like
+ ``file:///path/to/Data.fs``).
+
+#. Line *16*. We create a :term:`root factory` using the
+ ``PersistentApplicationFinder`` helper class, passing it the
+ ZODB URI and our appmaker.
+
+#. Line *17*. We use the ``repoze.bfg.router.make_app`` to return a
+ :term:`WSGI` application. The ``make_app`` function takes the root
+ factory (``get_root``), the *package* representing our application,
+ and the keywords parsed by PasteDeploy.
+
+We'll later change ``run.py`` when we add :term:`authorization` to our
+wiki application.