summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt10
-rw-r--r--TODO.txt10
-rw-r--r--docs/authorintro.rst27
-rw-r--r--docs/conf.py2
-rw-r--r--docs/copyright.rst18
-rw-r--r--docs/glossary.rst10
-rw-r--r--docs/index.rst3
-rw-r--r--docs/latexindex.rst3
-rw-r--r--docs/narr/MyProject/setup.py9
-rw-r--r--docs/narr/configuration.rst47
-rw-r--r--docs/narr/contextfinding.rst34
-rw-r--r--docs/narr/environment.rst13
-rw-r--r--docs/narr/events.rst1
-rw-r--r--docs/narr/extending.rst8
-rw-r--r--docs/narr/firstapp.rst112
-rw-r--r--docs/narr/hooks.rst8
-rw-r--r--docs/narr/hybrid.rst217
-rw-r--r--docs/narr/install.rst22
-rw-r--r--docs/narr/introduction.rst91
-rw-r--r--docs/narr/models.rst9
-rw-r--r--docs/narr/project.rst235
-rw-r--r--docs/narr/resources.rst1
-rw-r--r--docs/narr/router.rst1
-rw-r--r--docs/narr/security.rst29
-rw-r--r--docs/narr/startup.rst2
-rw-r--r--docs/narr/static.rst5
-rw-r--r--docs/narr/templates.rst50
-rw-r--r--docs/narr/threadlocals.rst8
-rw-r--r--docs/narr/traversal.rst38
-rw-r--r--docs/narr/unittesting.rst10
-rw-r--r--docs/narr/urldispatch.rst75
-rw-r--r--docs/narr/vhosting.rst8
-rw-r--r--docs/narr/views.rst90
-rw-r--r--docs/narr/webob.rst28
-rw-r--r--docs/tutorials/bfgwiki/authorization.rst4
-rw-r--r--docs/tutorials/bfgwiki/basiclayout.rst14
-rw-r--r--docs/tutorials/bfgwiki/installation.rst2
-rw-r--r--docs/tutorials/bfgwiki2/authorization.rst14
-rw-r--r--docs/tutorials/bfgwiki2/basiclayout.rst12
-rw-r--r--docs/tutorials/bfgwiki2/definingmodels.rst9
-rw-r--r--docs/tutorials/bfgwiki2/installation.rst2
-rw-r--r--docs/whatsnew-1.1.rst4
-rw-r--r--repoze/bfg/authorization.py2
-rw-r--r--repoze/bfg/paster.py1
-rw-r--r--repoze/bfg/traversal.py6
-rw-r--r--repoze/bfg/url.py4
-rw-r--r--repoze/bfg/view.py8
-rw-r--r--setup.py2
48 files changed, 669 insertions, 649 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index fea4f596e..a824e8929 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,5 @@
-Next release
-============
+1.2b1 (2010-01-17)
+==================
Bug Fixes
---------
@@ -11,6 +11,12 @@ Bug Fixes
environment. The ``__del__`` strategy was fragile and caused
problems in the wild. Thanks to Daniel Holth for testing.
+Features
+--------
+
+- Read logging configuration from PasteDeploy config file ``loggers``
+ section (and related) when ``paster bfgshell`` is invoked.
+
Documentation
-------------
diff --git a/TODO.txt b/TODO.txt
index 7f8589860..ca772259b 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -2,17 +2,9 @@
- Named notfound views.
-- Expand/review:
-
- [ ] View Configuration Parameters
-
- [ ] View Lookup and Invocation
+- Supply X-Vhm-Host support.
- Review tutorials.
-- Review index.
-
-- Review API docs.
-
- Basic WSGI documentation (pipeline / app / server).
diff --git a/docs/authorintro.rst b/docs/authorintro.rst
index 27a0152b9..356a26fb8 100644
--- a/docs/authorintro.rst
+++ b/docs/authorintro.rst
@@ -10,6 +10,9 @@ the book content, I'll provide some context regarding the genesis of
I hope you enjoy both this book and the software it documents. I've
had a blast writing both.
+.. index::
+ single: book audience
+
Audience
========
@@ -86,6 +89,7 @@ This book is divided into four major parts:
single: repoze.zope2
single: Zope 3
single: Zope 2
+ single: repoze.bfg genesis
The Genesis of :mod:`repoze.bfg`
================================
@@ -134,6 +138,22 @@ none. It combines all the "good parts" from other web frameworks into
a cohesive whole that is reliable, down-to-earth, flexible, speedy,
and well-documented.
+.. index::
+ single: Bicking, Ian
+ single: Everitt, Paul
+ single: Seaver, Tres
+ single: Sawyers, Andrew
+ single: Borch, Malthe
+ single: de la Guardia, Carlos
+ single: Brandl, Georg
+ single: Oram, Simon
+ single: Hardwick, Nat
+ single: Fulton, Jim
+ single: Moroz, Tom
+ single: Koym, Todd
+ single: van Rossum, Guido
+ single: Peters, Tim
+
Thanks
======
@@ -145,9 +165,10 @@ Thanks to the following people for providing expertise, resources, and
software. Without the help of these folks, neither this book nor the
software which it details would exist: Paul Everitt, Tres Seaver,
Andrew Sawyers, Malthe Borch, Carlos de la Guardia, Georg Brandl,
-Simon Oram of Electrosoup, Ian Bicking of the Open Planning Project,
-Jim Fulton of Zope Corporation, Tom Moroz of the Open Society
-Institute, and Todd Koym of Environmental Health Sciences.
+Simon Oram and Nat Hardwick of Electrosoup, Ian Bicking of the Open
+Planning Project, Jim Fulton of Zope Corporation, Tom Moroz of the
+Open Society Institute, and Todd Koym of Environmental Health
+Sciences.
Thanks to Guido van Rossum and Tim Peters for Python.
diff --git a/docs/conf.py b/docs/conf.py
index 64182333e..de22f0290 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -53,7 +53,7 @@ copyright = '2008-2010, Agendaless Consulting'
# other places throughout the built documents.
#
# The short X.Y version.
-version = '1.2a11'
+version = '1.2b1'
# The full version, including alpha/beta/rc tags.
release = version
diff --git a/docs/copyright.rst b/docs/copyright.rst
index 3a4960cfb..6ecd5af0f 100644
--- a/docs/copyright.rst
+++ b/docs/copyright.rst
@@ -1,7 +1,7 @@
Copyright, Trademarks, and Attributions
=======================================
-*The repoze.bfg Web Application Framework*
+*The repoze.bfg Web Application Framework, Version 1.2*
by Chris McDonough
@@ -13,7 +13,7 @@ ISBN-10: 0615345379
ISBN-13: 978-0-615-34537-6
-First print publishing: 2010
+First print publishing: January, 2010
All rights reserved. This material may be copied or distributed only
subject to the terms and conditions set forth in the `Creative Commons
@@ -48,19 +48,19 @@ with respect to the use of the information contained herein.
Attributions
------------
+Foreword:
+ Paul Everitt
+
Technical Reviewer:
Andrew Sawyers
Cover Designer:
- `Electrosoup <http://www.electrosoup.co.uk>`_.
+ Nat Hardwick of `Electrosoup <http://www.electrosoup.co.uk>`_.
Used with permission:
The :ref:`webob_chapter` chapter is adapted, with permission, from
documentation originally written by Ian Bicking.
-Foreword:
- Paul Everitt
-
Contacting The Publisher
------------------------
@@ -79,3 +79,9 @@ http://bfg.repoze.org.
The source code for the examples used in this book are available
within the :mod:`repoze.bfg` software distribution, always available
via http://bfg.repoze.org.
+
+Errata
+------
+
+Errata for this book will be placed at http://bfg.repoze.org/book_errata.
+
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 7c55dc2f5..b8ac383e3 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -219,10 +219,8 @@ Glossary
given the :term:`authentication` information in the request.
authentication
- The act of determining that the credentials a user presents during
- a particular request are "good". :mod:`repoze.bfg` uses the
- :term:`authentication` data supplied by the upstream component as
- one input during :term:`authorization`. Authentication in
+ The act of determining that the credentials a user presents
+ during a particular request are "good". Authentication in
:mod:`repoze.bfg` is performed via an :term:`authentication
policy`.
@@ -444,7 +442,7 @@ Glossary
repoze.lemonade
Zope2 CMF-like `data structures and helper facilities
<http://docs.repoze.org/lemonade>`_ for CA-and-ZODB-based
- applications useful within bfg applications.
+ applications useful within :mod:`repoze.bfg` applications.
repoze.catalog
An indexing and search facility (fielded and full-text) based on
@@ -593,7 +591,7 @@ Glossary
The :term:`view callable` invoked by :mod:`repoze.bfg` when the
developer explicitly raises a
``repoze.bfg.exceptions.Forbidden`` exception from within
- :term:`view` code or :term:`root factory` code, or when the the
+ :term:`view` code or :term:`root factory` code, or when the
:term:`view configuration` and :term:`authorization policy` found
for a request disallows a particular view invocation.
:mod:`repoze.bfg` provides a default implementation of a
diff --git a/docs/index.rst b/docs/index.rst
index 3f5f81cfd..9e64f9d29 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -44,6 +44,9 @@ Narrative documentation in chapter form explaining how to use
narr/project
narr/startup
narr/contextfinding
+ narr/traversal
+ narr/urldispatch
+ narr/hybrid
narr/views
narr/static
narr/webob
diff --git a/docs/latexindex.rst b/docs/latexindex.rst
index e40e57734..4220aff35 100644
--- a/docs/latexindex.rst
+++ b/docs/latexindex.rst
@@ -33,6 +33,9 @@ Narrative Documentation
narr/firstapp
narr/project
narr/contextfinding
+ narr/traversal
+ narr/urldispatch
+ narr/hybrid
narr/views
narr/static
narr/webob
diff --git a/docs/narr/MyProject/setup.py b/docs/narr/MyProject/setup.py
index 739541a04..3ed044868 100644
--- a/docs/narr/MyProject/setup.py
+++ b/docs/narr/MyProject/setup.py
@@ -7,22 +7,19 @@ README = open(os.path.join(here, 'README.txt')).read()
CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()
setup(name='MyProject',
- version='0.1',
+ version='0.0',
description='MyProject',
long_description=README + '\n\n' + CHANGES,
classifiers=[
- "Development Status :: 3 - Alpha",
- "Intended Audience :: Developers",
"Programming Language :: Python",
+ "Framework :: BFG",
"Topic :: Internet :: WWW/HTTP",
- "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
- "Topic :: Internet :: WWW/HTTP :: WSGI",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
],
author='',
author_email='',
url='',
- keywords='web wsgi bfg zope',
+ keywords='web wsgi bfg',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst
index e864af9aa..435ec7a83 100644
--- a/docs/narr/configuration.rst
+++ b/docs/narr/configuration.rst
@@ -10,15 +10,15 @@ Each deployment of an application written using :mod:`repoze.bfg`
implies a specific *configuration* of the framework itself. For
example, an application which serves up MP3s for user consumption
might plug code into the framework that manages songs, while an
-application that application might plug in code that manages
-accounting information. :mod:`repoze.bfg` refers to the way in which
-code is plugged in to it for a specific application as
+application that manages corporate data might plug in code that
+manages accounting information. :mod:`repoze.bfg` refers to the way
+in which code is plugged in to it for a specific application as
"configuration".
Most people understand "configuration" as coarse settings that inform
the high-level operation of a specific application deployment. For
instance, it's easy to think of the values implied by a ``.ini`` file
-which is parsed at application startup time as "configuration".
+parsed at application startup time as "configuration".
:mod:`repoze.bfg` extends this pattern to application development,
using the term "configuration" to express standardized ways that code
gets plugged into a deployment of the framework itself. When you plug
@@ -32,7 +32,7 @@ and *declarative* configuration. We'll examine both modes in the
sections which follow.
.. index::
- pair: imperative; configuration
+ single: imperative configuration
.. _imperative_configuration:
@@ -77,14 +77,14 @@ power of Python, including conditionals, can be employed in this mode
of configuration.
.. index::
- pair: declarative; configuration
+ single: declarative configuration
.. _declarative_configuration:
Declarative Configuration
-------------------------
-A :mod:`repoze.bfg` application can be alternatively be configured
+A :mod:`repoze.bfg` application can be alternately be configured
"declaratively", if so desired. Declarative configuration relies on
*declarations* made external to the code in a configuration file
format named :term:`ZCML` (Zope Configuration Markup Language), an XML
@@ -214,19 +214,14 @@ benefit being that applications configured declaratively can be
*overridden* and *extended* by third parties without requiring the
third party to change application code. If you want to build a
framework or an extensible application, using declarative
-configuration is a good idea. Declarative configuration has an
-obvious downside: you can't use plain-old-Python syntax you probably
-already know and understand to configure your application; instead you
-need to use :term:`ZCML`.
-
-.. note::
-
- See :ref:`extending_chapter` for a discussion of extending and
- overriding :mod:`repoze.bfg` applications.
+configuration is a good idea.
+Declarative configuration has an obvious downside: you can't use
+plain-old-Python syntax you probably already know and understand to
+configure your application; instead you need to use :term:`ZCML`.
.. index::
- pair: ZCML; conflict detection
+ single: ZCML conflict detection
ZCML Conflict Detection
~~~~~~~~~~~~~~~~~~~~~~~
@@ -261,9 +256,9 @@ might have conflicted.
.. index::
single: bfg_view
- pair: ZCML directive; view
- single: configuration decorations
- pair: code; scanning
+ single: ZCML view directive
+ single: configuration decoration
+ single: code scanning
.. _decorations_and_code_scanning:
@@ -273,12 +268,12 @@ Configuration Decorations and Code Scanning
An alternate mode of declarative configuration lends more *locality of
reference* to a :term:`configuration declaration`. It's sometimes
painful to have all configuration done in ZCML, or even in imperative
-code, because you may need to have two files open at once; the file
-that represents the configuration, and the file that contains the
-implementation objects (such as :term:`view callable` functions) that
-the configuration references. To avoid this, :mod:`repoze.bfg` allows
-you to insert :term:`configuration decoration` statements very close
-to code that is referred to by the declaration itself. For example:
+code, because you may need to have two files open at once to see the
+"big picture": the file that represents the configuration, and the
+file that contains the implementation objects referenced by the
+configuration. To avoid this, :mod:`repoze.bfg` allows you to insert
+:term:`configuration decoration` statements very close to code that is
+referred to by the declaration itself. For example:
.. code-block:: python
:linenos:
diff --git a/docs/narr/contextfinding.rst b/docs/narr/contextfinding.rst
index a31d0dc19..65ffe4860 100644
--- a/docs/narr/contextfinding.rst
+++ b/docs/narr/contextfinding.rst
@@ -1,10 +1,10 @@
.. index::
- pair: finding; context
+ single: context finding
.. _contextfinding_chapter:
-Context Finding
----------------
+Context Finding and View Lookup
+-------------------------------
In order for a web application to perform any useful action, the web
framework must provide a mechanism to find and invoke code written by
@@ -21,8 +21,8 @@ finding` and :term:`view lookup`.
request.
- Using the context and view name provided by :term:`context finding`,
- the :mod:`repoze.bfg` view lookup subsystem is provided with a
- :term:`request`, a :term:`context` and a :term:`view name`. It is
+ the :mod:`repoze.bfg` :term:`view lookup` subsystem is provided with
+ a :term:`request`, a :term:`context` and a :term:`view name`. It is
then responsible for finding and invoking a :term:`view callable`.
A view callable is a specific bit of code written and registered by
the application developer which receives the :term:`request` and
@@ -50,22 +50,17 @@ requesting user.
:term:`authorization`, which is not well-supported in frameworks
that do not provide a notion of a context.
-This chapter documents :term:`context finding`. There are two
-separate :term:`context finding` subsystems in :mod:`repoze.bfg`:
-:term:`traversal` and :term:`URL dispatch`. The subsystems are
-documented within this chapter. They can be used separately or they
-can be combined.
+There are two separate :term:`context finding` subsystems in
+:mod:`repoze.bfg`: :term:`traversal` and :term:`URL dispatch`. The
+subsystems are documented within this chapter. They can be used
+separately or they can be combined. Three chapters which follow
+describe :term:`context finding`: :ref:`traversal_chapter`,
+:ref:`urldispatch_chapter` and :ref:`hybrid_chapter`.
There is only one :term:`view lookup` subsystem present in
:mod:`repoze.bfg`. Where appropriate, within this chapter, we
-describe how view lookup interacts with context finding.
-
-.. toctree::
- :maxdepth: 2
-
- traversal
- urldispatch
- hybrid
+describe how view lookup interacts with context finding. One chapter
+which follows describes :term:`view lookup`: :ref:`views_chapter`.
Should I Use Traversal or URL Dispatch for Context Finding?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -100,7 +95,7 @@ just aren't possible. Essentially, URL-dispatch based systems just
don't deal very well with URLs that represent arbitrary-depth
hierarchies.
-But :term:`traversal`, *does* work well for URLs that represent
+But :term:`traversal` *does* work well for URLs that represent
arbitrary-depth hierarchies. Since the path segments that compose a
URL are addressed separately, it becomes very easy to form URLs that
represent arbitrary depth hierarchies in a system that uses traversal.
@@ -120,3 +115,4 @@ advantages over using URL-based dispatch.
Since :mod:`repoze.bfg` provides support for both approaches, you can
use either exclusively or combine them as you see fit.
+
diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst
index 0ad2de4be..16bc46325 100644
--- a/docs/narr/environment.rst
+++ b/docs/narr/environment.rst
@@ -7,11 +7,11 @@
single: debug_notfound
single: debug_all
single: reload_all
- pair: debug; settings
- pair: reload; settings
- pair: environment; variables
- pair: ini file; settings
- pair: PasteDeploy; settings
+ single: debug settings
+ single: reload settings
+ single: environment variables
+ single: ini file settings
+ single: PasteDeploy settings
.. _environment_chapter:
@@ -167,7 +167,8 @@ effect settings that do not start with ``reload_*`` such as
``debug_notfound``.
.. index::
- pair: reload_templates; reload_resources
+ single: reload_templates
+ single: reload_resources
Understanding the Distinction Between ``reload_templates`` and ``reload_resources``
-----------------------------------------------------------------------------------
diff --git a/docs/narr/events.rst b/docs/narr/events.rst
index a0142f187..b37583f4f 100644
--- a/docs/narr/events.rst
+++ b/docs/narr/events.rst
@@ -1,6 +1,5 @@
.. index::
single: event
- single: events
single: subscriber
single: INewRequest
single: INewResponse
diff --git a/docs/narr/extending.rst b/docs/narr/extending.rst
index 67f111bb4..e06488470 100644
--- a/docs/narr/extending.rst
+++ b/docs/narr/extending.rst
@@ -10,7 +10,7 @@ The behavior of a :mod:`repoze.bfg` application that obeys certain
constraints can be *overridden* or *extended* without modification.
.. index::
- triple: building; extensible; application
+ single: extensible application
Rules for Building An Extensible Application
--------------------------------------------
@@ -44,7 +44,7 @@ repoze bfg using the :term:`pkg_resources` API such as static files
and templates.
.. index::
- pair: ZCML; granularity
+ single: ZCML granularity
ZCML Granularity
~~~~~~~~~~~~~~~~
@@ -76,7 +76,7 @@ own package, if necessary. However, doing so is considerate, and
allows for the best reusability.
.. index::
- pair: extending existing; application
+ single: extending an existing application
Extending an Existing Application
---------------------------------
@@ -237,7 +237,7 @@ such ``<resource>`` declarations to your override package's
``configure.zcml`` to perform overrides.
.. index::
- pair: ZCML; inclusion
+ single: ZCML inclusion
Dealing With ZCML Inclusions
----------------------------
diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst
index 158cb2a56..138e92706 100644
--- a/docs/narr/firstapp.rst
+++ b/docs/narr/firstapp.rst
@@ -4,7 +4,7 @@ Creating Your First :mod:`repoze.bfg` Application
=================================================
We will walk through the creation of a tiny :mod:`repoze.bfg`
-application in this chapter. After we're done with creating it, we'll
+application in this chapter. After we're finished creating it, we'll
explain in more detail how the application works.
.. note::
@@ -76,8 +76,8 @@ The above script defines the following set of imports:
Like many other Python web frameworks, :mod:`repoze.bfg` uses the
:term:`WSGI` protocol to connect an application and a web server
together. The :mod:`paste.httpserver` server is used in this example
-as a WSGI server for convenience, as ``Paste`` is a dependency of
-:mod:`repoze.bfg` itself.
+as a WSGI server for convenience, as the ``paste`` package is a
+dependency of :mod:`repoze.bfg` itself.
The script also imports the ``Configurator`` class from the
``repoze.bfg.configuration`` module. This class is used to configure
@@ -100,11 +100,11 @@ one named ``hello_world`` and one named ``goodbye_world``.
def goodbye_world(request):
return Response('Goodbye world!')
-These functions don't really do anything very interesting. Both
-functions accept a single argument (``request``). The ``hello_world``
-function does nothing but return a response instance with the body
-``Hello world!``. The ``goodbye_world`` function returns a response
-instance with the body ``Goodbye world!``.
+These functions don't do anything very taxing. Both functions accept
+a single argument (``request``). The ``hello_world`` function does
+nothing but return a response instance with the body ``Hello world!``.
+The ``goodbye_world`` function returns a response instance with the
+body ``Goodbye world!``.
Each of these functions is known as a :term:`view callable`. View
callables in a :mod:`repoze.bfg` application accept a single argument,
@@ -120,16 +120,17 @@ request object is a representation of an HTTP request sent to
A view callable is required to return a :term:`response` object
because a response object has all the information necessary to
formulate an actual HTTP response; this object is then converted to
-text and sent back to the requesting browser. To return a response,
-each view callable creates an instance of the :class:`webob.Response`
-class. In the ``hello_world`` function, the string ``'Hello world!'``
-is passed to the ``Response`` constructor as the *body* of the
-response. In the ``goodbye_world`` function, the string ``'Goodbye
-world!'`` is passed.
+text by the upstream :term:`WSGI` server and sent back to the
+requesting browser. To return a response, each view callable creates
+an instance of the :class:`webob.Response` class. In the
+``hello_world`` function, the string ``'Hello world!'`` is passed to
+the ``Response`` constructor as the *body* of the response. In the
+``goodbye_world`` function, the string ``'Goodbye world!'`` is passed.
.. index::
- pair: imperative; configuration
+ single: imperative configuration
single: Configurator
+ single: helloworld (imperative)
.. _helloworld_imperative_appconfig:
@@ -164,17 +165,21 @@ Configurator Construction
if __name__ == '__main__':
config = Configurator()
-The ``if __name__ == '__main__':`` line above represents a Python
-idiom: the code inside this if clause is not invoked unless the script
-is run directly from the command line via, for example, ``python
-helloworld.py`` where the file named ``helloworld.py`` contains the
-entire script body. ``helloworld.py`` in this case is a Python
-*module*. Using the ``if`` clause is necessary (or at least "best
-practice") because code in any Python module may be imported by
-another Python module. By using this idiom, the script is indicating
-that it does not want the code within the ``if`` statement to execute
-if this module is imported; the code within the ``if`` block should
-only be run during a direct script execution.
+The ``if __name__ == '__main__':`` line in the code sample above
+represents a Python idiom: the code inside this if clause is not
+invoked unless the script containing this code is run directly from
+the command line. For example, if the file named ``helloworld.py``
+contains the entire script body, the code within the ``if`` statement
+will only be invoked when ``python helloworld.py`` is executed from
+the operating system command line.
+
+``helloworld.py`` in this case is a Python *module*. Using the ``if``
+clause is necessary -- or at least best practice -- because code in
+any Python module may be imported by another Python module. By using
+this idiom, the script is indicating that it does not want the code
+within the ``if`` statement to execute if this module is imported; the
+code within the ``if`` block should only be run during a direct script
+execution.
The ``config = Configurator()`` line above creates an instance of the
:class:`repoze.bfg.configuration.Configurator` class. The resulting
@@ -192,14 +197,14 @@ Beginning Configuration
config.begin()
The :meth:`repoze.bfg.configuration.Configurator.begin` method tells
-the the system that application configuration has begun. In
-particular, this causes the :term:`application registry` associated
-with this configurator to become the "current" application registry,
-meaning that code which attempts to use the application registry
-:term:`thread local` will obtain the registry associated with the
-configurator. This is an explicit step because it's sometimes
-convenient to use a configurator without causing the registry
-associated with the configurator to become "current".
+the system that application configuration has begun. In particular,
+this causes the :term:`application registry` associated with this
+configurator to become the "current" application registry, meaning
+that code which attempts to use the application registry :term:`thread
+local` will obtain the registry associated with the configurator.
+This is an explicit step because it's sometimes convenient to use a
+configurator without causing the registry associated with the
+configurator to become "current".
.. note::
@@ -282,13 +287,13 @@ Ending Configuration
config.end()
The :meth:`repoze.bfg.configuration.Configurator.end` method tells the
-the system that application configuration has ended. It is the
-inverse of :meth:`repoze.bfg.configuration.Configurator.begin`. In
-particular, this causes the :term:`application registry` associated
-with this configurator to no longer be the "current" application
-registry, meaning that code which attempts to use the application
-registry :term:`thread local` will no longer obtain the registry
-associated with the configurator.
+system that application configuration has ended. It is the inverse of
+:meth:`repoze.bfg.configuration.Configurator.begin`. In particular,
+this causes the :term:`application registry` associated with this
+configurator to no longer be the "current" application registry,
+meaning that code which attempts to use the application registry
+:term:`thread local` will no longer obtain the registry associated
+with the configurator.
.. note::
@@ -297,8 +302,7 @@ associated with the configurator.
.. index::
single: make_wsgi_app
- pair: WSGI; application
- triple: WSGI; application; creation
+ single: WSGI application
WSGI Application Creation
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -316,14 +320,17 @@ call to ``make_wsgi_app`` implies that all configuration is finished
various other configuration settings have been performed). The
``make_wsgi_app`` method returns a :term:`WSGI` application object
that can be used by any WSGI server to present an application to a
-requestor.
+requestor. :term:`WSGI` is a protocol that allows servers to talk to
+Python applications. We don't discuss :term:`WSGI` in any depth
+within this book, however, you can learn more about it by visiting
+`wsgi.org <http://wsgi.org>`_.
The :mod:`repoze.bfg` application object, in particular, is an
instance of a class representing a :mod:`repoze.bfg` :term:`router`.
It has a reference to the :term:`application registry` which resulted
from method calls to the configurator used to configure it. The
-router consults the registry to obey the policy choices made by a
-single application. These policy choices were informed by method
+:term:`router` consults the registry to obey the policy choices made
+by a single application. These policy choices were informed by method
calls to the :term:`Configurator` made earlier; in our case, the only
policy choices made were implied by two calls to its ``add_view``
method.
@@ -360,8 +367,7 @@ that it's configured imperatively because the full power of Python is
available to us as we perform configuration tasks.
.. index::
- pair: helloworld; declarative
- single: helloworld
+ single: helloworld (declarative)
.. _helloworld_declarative:
@@ -516,15 +522,15 @@ The ``configure.zcml`` ZCML file contains this bit of XML within the
<include package="repoze.bfg.includes" />
-This singleton (self-closing) tag instructs ZCML to load a ZCML file
+This self-closing tag instructs :mod:`repoze.bfg` to load a ZCML file
from the Python package with the :term:`dotted Python name`
-:mod:`repoze.bfg.includes`, as specified by its ``package`` attribute.
+``repoze.bfg.includes``, as specified by its ``package`` attribute.
This particular ``<include>`` declaration is required because it
actually allows subsequent declaration tags (such as ``<view>``, which
we'll see shortly) to be recognized. The ``<include>`` tag
-effectively just includes another ZCML file; this causes its
-declarations to be executed. In this case, we want to load the
-declarations from the file named ``configure.zcml`` within the
+effectively just includes another ZCML file, causing its declarations
+to be executed. In this case, we want to load the declarations from
+the file named ``configure.zcml`` within the
:mod:`repoze.bfg.includes` Python package. We know we want to load
the ``configure.zcml`` from this package because ``configure.zcml`` is
the default value for another attribute of the ``<include>`` tag named
diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst
index 720fe8af9..1bc3289fc 100644
--- a/docs/narr/hooks.rst
+++ b/docs/narr/hooks.rst
@@ -7,7 +7,7 @@ Using Hooks
:mod:`repoze.bfg` framework in various ways.
.. index::
- pair: not found view; changing
+ single: not found view
.. _changing_the_notfound_view:
@@ -74,7 +74,7 @@ Here's some sample code that implements a minimal NotFound view:
is false.
.. index::
- pair: forbidden view; changing
+ single: forbidden view
.. _changing_the_forbidden_view:
@@ -155,7 +155,7 @@ Here's some sample code that implements a minimal forbidden view:
return a response with a ``403 Forbidden`` status code.
.. index::
- pair: traverser; changing
+ single: traverser
.. _changing_the_traverser:
@@ -252,7 +252,7 @@ wild" within `repoze.bfg.traversalwrapper
`repoze.bfg.metatg <http://svn.repoze.org/repoze.bfg.metatg/trunk/>`_.
.. index::
- pair: url generator; changing
+ single: url generator
Changing How :mod:`repoze.bfg.url.model_url` Generates a URL
------------------------------------------------------------
diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst
index 92e6428b5..7d4768cf6 100644
--- a/docs/narr/hybrid.rst
+++ b/docs/narr/hybrid.rst
@@ -3,14 +3,15 @@
Combining Traversal and URL Dispatch
====================================
-:mod:`repoze.bfg` makes an honest attempt to unify the (largely
-incompatible) concepts of :term:`traversal` and :term:`url dispatch`.
+:mod:`repoze.bfg` makes an honest attempt to unify the largely
+incompatible concepts of :term:`traversal` and :term:`url dispatch`.
-When you write *most* :mod:`repoze.bfg` applications, you'll be using
-either one or the other concept, but not both, to resolve URLs to
-:term:`view` callables. However, to solve some problems, it's useful
-to use both traversal *and* URL dispatch within the same application.
-:mod:`repoze.bfg` makes this possible via *hybrid* applications.
+When you write most :mod:`repoze.bfg` applications, you'll be using
+either one or the other subsystem, but not both, to perform
+:term:`context finding`. However, to solve specific problems, it's
+useful to use *both* traversal *and* URL dispatch within the same
+application. :mod:`repoze.bfg` makes this possible via *hybrid*
+applications.
.. warning::
@@ -106,9 +107,9 @@ this:
"Under the hood", the above view statements register a view using the
following context/request/name :term:`triad`:
-- The :term:`context` interface ``None``
+- the :term:`context` interface ``None``
-- the the :class:`repoze.bfg.interfaces.IRequest` :term:`request type`
+- the :class:`repoze.bfg.interfaces.IRequest` :term:`request type`
interface
- a :term:`view name` matching the ``name=`` argument.
@@ -123,29 +124,10 @@ The ``.views.foobar`` view callable above will be called when the URL
Hybrid Applications
-------------------
-We've seen that *either* traversal or url dispatch can be used to
-create a :mod:`repoze.bfg` application. However, it is possible to
-combine the competing concepts of traversal and url dispatch to
-resolve URLs to code within the same application.
-
-Understanding how hybrid mode works requires a little "inside
-baseball" knowledge of how :mod:`repoze.bfg` works. No matter whether
-:term:`traversal` or :term:`URL dispatch` is used, :mod:`repoze.bfg`
-uses the :term:`Zope Component Architecture` under the hood to
-dispatch a request to a :term:`view callable`. In Zope Component
-Architecture-speak, a view callable is a "multi adapter" registered
-for a :term:`context` type and a :term:`request` type as well as a
-particular :term:`view name`, also known as a :term:`triad`. When a
-request is generated and a :term:`router` performs its logic, it
-locates these three values. These three values are fed to the
-:term:`application registry` as a query to find "the best" view
-callable.
-
-.. note:: To understand this process more deeply, it may be useful to
- read :ref:`router_chapter`.
-
-A hybrid-mode application is one which performs :term:`traversal`
-*after* a :term:`route` has already matched.
+Clearl *either* traversal or url dispatch can be used to create a
+:mod:`repoze.bfg` application. However, it is possible to combine the
+competing concepts of traversal and url dispatch to resolve URLs to
+code within the same application.
To "turn on" hybrid mode, use a :term:`route configuration` that
includes a ``path`` argument that contains a special dynamic part:
@@ -191,32 +173,28 @@ factory looks like so:
return root
We've defined a bogus graph here that can be traversed, and a
-root_factory method that returns the root of the graph. Because the
-Traversable object we've defined has a ``__getitem__`` method that
-does something nominally useful, using traversal against the root
-implied by a route statement becomes a not-completely-insane thing to
-do. So for this route:
-
-.. code-block:: xml
-
- <route
- path=":foo/:bar/*traverse"
- name="home"
- view=".views.home"
- />
-
-Under this circumstance, traversal is performed *after* the route
-matches. If the root factory returns a traversable object, the
-"capture value" implied by the ``*traverse`` element in the path
-pattern will be used to traverse the graph. For example, if the URL
-requested by a user was ``http://example.com/one/two/a/b/c``, and the
-above route was matched (some other route might match before this one
-does), the traversal path used against the root would be ``a/b/c``.
-:mod:`repoze.bfg` will attempt to traverse a graph through the edges
-``a``, ``b``, and ``c``. In our above example, that would imply that
-the *context* of the view would be the ``Traversable`` object we've
-named ``c`` in our bogus graph, using the ``.views.home`` view as the
-view callable.
+``root_factory`` method that returns the root of the graph that we can
+pass to our :class:`repoze.bfg.configuration.Configurator`.
+
+Because the ``Traversable`` object we've defined has a ``__getitem__``
+method that does something nominally useful, using traversal against
+the root implied by a route statement becomes a not-completely-insane
+thing to do.
+
+Under the circumstance implied by ``:foo/:bar/*traverse``, traversal
+is performed *after* the route matches. If the root factory returns a
+traversable object, the "capture value" implied by the ``*traverse``
+element in the path pattern will be used to traverse the graph,
+starting from the root object returned from the root factory.
+
+For example, if the URL requested by a user was
+``http://example.com/one/two/a/b/c``, and the above route was matched
+(some other route might match before this one does), the traversal
+path used against the root would be ``a/b/c``. :mod:`repoze.bfg` will
+attempt to traverse a graph through the edges ``a``, ``b``, and ``c``.
+In our above example, that would imply that the *context* of the view
+would be the ``Traversable`` object we've named ``c`` in our bogus
+graph, using the ``.views.home`` view as the view callable.
We can also define extra views that match a route:
@@ -248,24 +226,26 @@ view callable will be called instead of the *default* view callable
(the one implied by the route with the name ``home``).
.. index::
- pair: subpath; route
+ single: route subpath
+ single: subpath (route)
.. _star_subpath:
Using ``*subpath`` in a Route Path
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-There are certain (extremely rare) cases when you'd like to influence
+There are certain extremely rare cases when you'd like to influence
the traversal :term:`subpath` when a route matches without actually
performing traversal. For instance, the
:func:`repoze.bfg.wsgi.wsgiapp2` decorator and the
:class:`repoze.bfg.view.static` helper attempt to compute
``PATH_INFO`` from the request's subpath, so it's useful to be able to
-influence this value. When ``*subpath`` exists in a path pattern, no
-path is actually traversed, but the traversal algorithm will return a
-:term:`subpath` list implied by the capture value of ``*subpath``.
-You'll see this pattern most commonly in route declarations that look
-like this:
+influence this value.
+
+When ``*subpath`` exists in a path pattern, no path is actually
+traversed, but the traversal algorithm will return a :term:`subpath`
+list implied by the capture value of ``*subpath``. You'll see this
+pattern most commonly in route declarations that look like this:
.. code-block:: xml
@@ -283,12 +263,12 @@ Corner Cases
------------
A number of corner case "gotchas" exist when using a hybrid
-application. Let's see what they are.
+application. We'll detail them here.
.. _globalviews_corner_case:
-"Global" Views Match Any Route When A More Specific View Doesn't
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+"Global" View Configurations May Match When A Route-Specific View Configuration Doesn't
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Note that views that don't mention a ``route_name`` will *also* match
when *any* route matches. For example, the "bazbuz" view below will
@@ -338,59 +318,56 @@ to be "bazbuz", the ``.views.bazbuz2`` view will be used.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This corner case is only interesting if you are using a hybrid
-application and you believe the "wrong" view is being called for a
-given request.
-
-A view is registered for a ``route`` either as its default view via
-the ``view=`` attribute of a ``route`` declaration in ZCML, via a
-standalone ``<view>`` declaration, or via the ``@bfg_route`` decorator
-which has a ``route_name`` that matches the route's name. At startup
-time, when such a registration is encountered, the view is registered
-for the ``context`` type ``None`` (meaning *any* context) and a
-*special* request type which is dynamically generated. This request
-type also derives from a "base" request type, which is what allows it
-to match against views defined without a route name (see
-:ref:`globalviews_corner_case`).
-
-When a request URL matches a ``<route>`` path, the special request
-type interface mentioned in the previous paragraph is attached to the
-``request`` object as it is created. The *root* found by the router
-is based on either the route's ``factory`` (or the default root
-factory if no ``factory`` is mentioned in the ``<route>``
-declaration). This root is eventually resolved to a ``context`` via
+application and you believe the wrong view callable is being found for
+a given request.
+
+A view is registered for a route either via :term:`route
+configuration` by passing a ``view`` argument, or via :term:`view
+configuration` by passing a ``route_name`` that matches the route's
+name.
+
+At startup time, when such a registration is encountered, the view is
+registered for the ``context`` type ``None`` -- meaning *any* context
+-- and a *special* request type which is dynamically generated. This
+request type also derives from a "base" request type, which is what
+allows it to match against views defined without a route name as per
+see :ref:`globalviews_corner_case`.
+
+When a request URL matches a route configuration path, the special
+request type interface mentioned in the previous paragraph is attached
+to the ``request`` object as it is created. The *root* found by the
+router is based on either the route's ``factory`` or the default root
+factory if no ``factory`` is mentioned in the route configuration.
+This root is eventually resolved to a ``context`` via
:term:`traversal`. This ``context`` will either have some particular
-interface, or it won't, depending on the result of traversal.
-
-Given how view dispatch works, since the registration made "under the
-hood" for views that match a route use the (very weakly binding)
-``None`` value as the context value's interface, if the context that
-is found has a specific interface, and a global view statement is
-registered against this interface as its context interface, it's
-likely that the *global* view will match *before* the view that is
-attached to the route unless the ``view_context`` attribute is used on
-the ``route`` registration to match the "correct" interface first
-(because then both the request type and the context type are "more
-specific" for the view registration).
-
-What it all boils down to is: if a request that matches a route
+:term:`interface`, or it won't, depending on the result of traversal.
+
+The view configuration registration made "under the hood" for view
+callables that match a route use the very weakly binding ``None``
+value as the context value's interface. Given how :term:`view lookup`
+works, if the context that is found has a specific interface, and a
+global view configuration statement is registered using this interface
+as its ``context``, it's likely that the *global* view calable will
+match *before* the view callable that is attached to the route. This
+behavior can be subverted if the ``view_context`` attribute is used on
+the route registration, because then both the request type and the
+context type can be made "more specific" for the view registration
+related to the route.
+
+What it all boils down to is this: if a request that matches a route
resolves to a view you don't expect it to, use the ``view_context``
-attribute of the ``route`` statement (*or* the ``context`` attribute
-of the ZCML statement that also has a ``route_name`` *or* the
-equivalent ``context`` parameter to the
-:class:`repoze.bfg.view.bfg_view` decorator that also has a
-``route_name`` parameter) to name the specific context interface you
-want the route-related view to match.
-
-Yes, that was as painful for me to write as it was for you to read.
+attribute of route configuration *or* the ``context`` attribute of
+:term:`view configuration` which names a ``route_name`` to name the
+specific context interface you want the route-related view to match.
-Registering a Default View for a Route That has a ``view`` attribute
+Registering a Default View for a Route That Has a ``view`` Attribute
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-It is an error to provide *both* a ``view`` attribute on a ZCML
-``<route>`` declaration *and* a ZCML ``<view>`` declaration that
-serves as a "default view" (a view with no ``name`` attribute or the
-empty ``name`` attribute). For example, this pair of route/view
-statements will generate a "conflict" error at startup time.
+It is an error to provide *both* a ``view`` argument to a :term:`route
+configuration` *and* a :term:`view configuration` which names a
+``route_name`` that has no ``name`` value or the empty ``name`` value.
+For example, this pair of route/view ZCML declarations will generate a
+"conflict" error at startup time.
.. code-block:: xml
@@ -422,7 +399,6 @@ Can also be spelled like so:
.. code-block:: xml
-
<route
path=":foo/:bar/*traverse"
name="home"
@@ -433,10 +409,11 @@ Can also be spelled like so:
view=".views.home"
/>
-The two spellings are logically equivalent.
+The two spellings are logically equivalent. In fact, the former is
+just a syntactical shortcut for the latter.
-Binding Extra Views Against a ``<route>`` Statement that Doesn't Have a ``*traverse`` Element In Its Path
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Binding Extra Views Against a Route Configuration that Doesn't Have a ``*traverse`` Element In Its Path
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Here's another corner case that just makes no sense.
diff --git a/docs/narr/install.rst b/docs/narr/install.rst
index 7021a9af2..a1cba3d7c 100644
--- a/docs/narr/install.rst
+++ b/docs/narr/install.rst
@@ -4,7 +4,7 @@ Installing :mod:`repoze.bfg`
============================
.. index::
- pair: install; preparation
+ single: install preparation
Before You Install
------------------
@@ -111,8 +111,18 @@ executable and accept the defaults during the installation process.
You may also need to download and install the `Python for Windows
extensions <http://sourceforge.net/projects/pywin32/files/>`_.
+.. warning::
+
+ After you install Python on Windows, you may need to add the
+ ``C:\Python26`` directory to your environment's ``Path`` in order
+ to make it possible to invoke Python from a command prompt by
+ typing ``python``. To do so, right click ``My Computer``, select
+ ``Properties`` --> ``Advanced Tab`` --> ``Environment Variables``
+ and add that directory to the end of the ``Path`` environment
+ variable.
+
.. index::
- pair: installing; UNIX
+ single: installing on UNIX
.. _installing_unix:
@@ -174,7 +184,7 @@ the script. To remediate this, you may need to do:
$ sudo python ez_setup.py
.. index::
- pair: installing; virtualenv
+ single: virtualenv
Installing the ``virtualenv`` Package
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -197,7 +207,7 @@ to install it as your system's administrative user. For example:
$ sudo easy_install virtualenv
.. index::
- pair: creating; virtualenv
+ single: virtualenv
Creating the Virtual Python Environment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -244,7 +254,7 @@ This command will take longer than the previous ones to complete, as it
downloads and installs a number of dependencies.
.. index::
- pair: installing; Windows
+ single: installing on Windows
.. _installing_windows:
@@ -299,7 +309,7 @@ Installing :mod:`repoze.bfg` on a Windows System
http://dist.repoze.org/bfg/current/simple repoze.bfg
.. index::
- pair: installing; Google App Engine
+ single: installing on Google App Engine
Installing :mod:`repoze.bfg` on Google App Engine
-------------------------------------------------
diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst
index 4e39a353e..3410e6868 100644
--- a/docs/narr/introduction.rst
+++ b/docs/narr/introduction.rst
@@ -9,17 +9,23 @@
:mod:`repoze.bfg` Introduction
==============================
-Most of the logic in a web application is completely
-application-specific. For example, the content of a web page served
-by one web application might be a representation of the contents of an
-accounting ledger, while the content of of a web page served by
-another might be a listing of songs. These applications probably
-won't serve the same set of customers. However, both a ledger-serving
-application and a song-serving application might be written using
-:mod:`repoze.bfg` because it is a very general open source Python web
-*framework*. As a framework, the primary job of :mod:`repoze.bfg` is
-to make it easier for a developer to create arbitrary web
-applications.
+If they are judged only by differences in user interface, most web
+applications seem to have very little in common with each other. For
+example, a web page served by one web application might be a
+representation of the contents of an accounting ledger, while a web
+page served by another application might be a listing of songs. These
+applications probably won't serve the same set of customers. However,
+although they're not very similar on the surface, both a
+ledger-serving application and a song-serving application could be
+successfully be written using :mod:`repoze.bfg`.
+
+:mod:`repoze.bfg` is a very general open source Python web
+*framework*. As a framework, its primary job is to make it easier for
+a developer to create an arbitrary web application. The type of
+application being created isn't really important; it could be a
+spreadsheet, a corporate intranet, or an "oh-so-Web-2.0" social
+networking platform. :mod:`repoze.bfg` is general enough that it can
+be used in a wide variety of circumstances.
.. sidebar:: Frameworks vs. Libraries
@@ -75,9 +81,8 @@ Speed
need, the less pain you'll have.
Familiarity
- As web developers, we've become accustomed to working in very
- particular ways over the years. This framework is a canonization of
- practices that "fit our brains".
+ The :mod:`repoze.bfg` framework is a canonization of practices that
+ "fit the brains" of its authors.
Trustability
:mod:`repoze.bfg` is developed conservatively and tested
@@ -96,7 +101,7 @@ This book usually refers to the framework by its full package name,
.. index::
single: Repoze
single: Agendaless Consulting
- pair: repoze; namespace package
+ single: repoze namespace package
What Is Repoze?
---------------
@@ -130,13 +135,15 @@ and can be used separately.
concepts and features from each, combining them into a unique web
framework.
-Features such as :term:`traversal` and easy extensibility trace their
-origins back to :term:`Zope`. Like Zope applications,
-:mod:`repoze.bfg` applications can be easily extended. If you obey
-certain constraints, the application you produce can be reused,
-modified, re-integrated, or extended by third-party developers without
-modification to the original application itself: no fork of the
-application is required.
+Many features of :mod:`repoze.bfg` trace their origins back to
+:term:`Zope`. Like Zope applications, :mod:`repoze.bfg` applications
+can be configured via a set of declarative configuration files. Like
+Zope applications, :mod:`repoze.bfg` applications can be easily
+extended: if you obey certain constraints, the application you produce
+can be reused, modified, re-integrated, or extended by third-party
+developers without forking the original application. The concepts of
+:term:`traversal` and declarative security in :mod:`repoze.bfg` were
+pioneered first in Zope.
The :mod:`repoze.bfg` concept of :term:`URL dispatch` is inspired by
the :term:`Routes` system used by :term:`Pylons`. Like Pylons,
@@ -147,24 +154,10 @@ mechanism to map URLs to :term:`view` code, along with a set of
conventions for calling those views. You are free to use third-party
components that fit your needs in your applications.
-Insofar as the term `model-view-controller
-<http://en.wikipedia.org/wiki/Model–view–controller>`_ has been
-claimed to represent a class of web frameworks, :mod:`repoze.bfg`
-generally fits into this class. The concepts of :term:`view` and
-:term:`model` are used by :mod:`repoze.bfg` as they would be by
-Django.
-
-.. sidebar:: You Say BFG is MVC, But Where's The Controller?
-
- The :mod:`repoze.bfg` authors believe that the MVC pattern just
- doesn't really fit the web very well. In a :mod:`repoze.bfg`
- application, there are models, which store data, and views, which
- present the data stored in models. However, no facility provided
- by the framework actually maps to the concept of a "controller".
- So :mod:`repoze.bfg` is actually an "MV" framework rather than an
- "MVC" framework. "MVC", however, is close enough as a general
- classification moniker for purposes of comparison with other web
- frameworks.
+The concepts of :term:`view` and :term:`model` are used by
+:mod:`repoze.bfg` mostly as they would be by Django.
+:mod:`repoze.bfg` has a documentation culture more like Django's than
+like Zope's.
Like :term:`Pylons`, but unlike :term:`Zope`, a :mod:`repoze.bfg`
application developer may use completely imperative code to perform
@@ -186,3 +179,21 @@ you want to store your application's data in a relational database.
:mod:`repoze.bfg` makes no such assumption; it allows you to use a
relational database but doesn't encourage or discourage the decision.
+Other Python web frameworks advertise themselves as members of a class
+of web frameworks named `model-view-controller
+<http://en.wikipedia.org/wiki/Model–view–controller>`_ frameworks.
+Insofar as this term has been claimed to represent a class of web
+frameworks, :mod:`repoze.bfg` also generally fits into this class.
+
+.. sidebar:: You Say BFG is MVC, But Where's The Controller?
+
+ The :mod:`repoze.bfg` authors believe that the MVC pattern just
+ doesn't really fit the web very well. In a :mod:`repoze.bfg`
+ application, there are models, which store data, and views, which
+ present the data stored in models. However, no facility provided
+ by the framework actually maps to the concept of a "controller".
+ So :mod:`repoze.bfg` is actually an "MV" framework rather than an
+ "MVC" framework. "MVC", however, is close enough as a general
+ classification moniker for purposes of comparison with other web
+ frameworks.
+
diff --git a/docs/narr/models.rst b/docs/narr/models.rst
index 32b9632e1..c85db63bf 100644
--- a/docs/narr/models.rst
+++ b/docs/narr/models.rst
@@ -49,7 +49,7 @@ mutating that data.
different to avoid confusion.
.. index::
- pair: model; constructor
+ single: model constructor
Defining a Model Constructor
----------------------------
@@ -75,7 +75,7 @@ callable, and which returns a model instance. In the above example,
the ``BlogEntry`` class can be "called", returning a model instance.
.. index::
- pair: model; interfaces
+ single: model interfaces
.. _models_which_implement_interfaces:
@@ -297,7 +297,8 @@ and so on.
slash or empty tuple element).
.. index::
- pair: model; API functions
+ single: model API functions
+ single: url generation (traversal)
:mod:`repoze.bfg` API Functions That Act Against Models
-------------------------------------------------------
@@ -308,7 +309,7 @@ more information about how a model instance becomes the context.
The APIs provided by :ref:`traversal_module` are used against model
instances. These functions can be used to find the "path" of a model,
-find the URL of a model, the root model in an object graph, and so on.
+the root model in an object graph, or generate a URL to a model.
The APIs provided by :ref:`location_module` are used against model
instances. These can be used to walk down an object graph, or
diff --git a/docs/narr/project.rst b/docs/narr/project.rst
index a294fbc4f..56580451c 100644
--- a/docs/narr/project.rst
+++ b/docs/narr/project.rst
@@ -17,10 +17,10 @@ templates".
.. index::
single: paster templates
- single: bfg_starter
- single: bfg_zodb
- single: bfg_alchemy
- single: bfg_routesalchemy
+ single: bfg_starter paster template
+ single: bfg_zodb paster template
+ single: bfg_alchemy paster template
+ single: bfg_routesalchemy paster template
.. _additional_paster_templates:
@@ -39,30 +39,35 @@ differ from each other on two axes:
The included templates are these:
``bfg_starter``
+
URL mapping via :term:`traversal` and no persistence mechanism.
``bfg_zodb``
+
URL mapping via :term:`traversal` and persistence via :term:`ZODB`
``bfg_routesalchemy``
+
URL mapping via :term:`URL dispatch` and persistence via
:term:`SQLAlchemy`
``bfg_alchemy``
+
URL mapping via :term:`traversal` and persistence va
:term:`SQLAlchemy`
-All existing project templates use :term:`ZCML` instead of
-:term:`imperative configuration`. All existing project templates also
-make the assumption that you want your code to live in a Python
-:term:`package`. Even if your application is extremely simple, it is
-useful to place code that drives the application within a package,
-because a package is more easily extended with new code and an
-application that lives inside a package can be distributed more easily
-than one which does not live within a package.
+Each of these project templates uses :term:`ZCML` instead of
+:term:`imperative configuration`. Each also makes the assumption that
+you want your code to live in a Python :term:`package`. Even if your
+application is extremely simple, it is useful to place code that
+drives the application within a package, because a package is more
+easily extended with new code. An application that lives inside a
+package can also be distributed more easily than one which does not
+live within a package.
.. index::
- pair: project; creating
+ single: creating a project
+ single: project
.. _creating_a_project:
@@ -88,6 +93,8 @@ invokes the creation of a project from a template. To use a different
template, such as ``bfg_routesalchemy``, you'd just change the last
argument. For example:
+.. code-block:: text
+
$ bin/paster create -t bfg_routesalchemy
``paster create`` will ask you a single question: the *name* of the
@@ -115,17 +122,17 @@ project we name ``MyProject``:
name during ``paster create`` by adding the project name to the
command line, e.g. ``paster create -t bfg_starter MyProject``.
-As a result of invoking the ``paster create`` command above, a project
-is created in a directory named ``MyProject``. That directory is a
+As a result of invoking the ``paster create`` command, a project is
+created in a directory named ``MyProject``. That directory is a
:term:`setuptools` :term:`project` directory from which a setuptools
:term:`distribution` can be created. The ``setup.py`` file in that
directory can be used to distribute your application, or install your
application for deployment or development.
A sample :term:`PasteDeploy` ``.ini`` file named ``MyProject.ini``
-will also be created in the project directory. You will use the
-``paster serve`` command against this ``.ini`` file to run your
-application.
+will also be created in the project directory. You will use this
+``.ini`` file to configure a server, to run your application, and to
+and debug your application.
The ``MyProject`` project directory contains an additional
subdirectory named ``myproject`` (note the case difference)
@@ -161,10 +168,11 @@ Elided output from a run of this command is shown below:
This will install the :term:`distribution` representing your
application's into the interpreter's library set so it can be found
-and run by :term:`PasteDeploy` via ``paster serve``.
+and run by :term:`PasteDeploy` via the command ``paster serve``.
.. index::
- pair: running; tests
+ single: running tests
+ single: tests (running)
Running The Tests For Your Application
--------------------------------------
@@ -257,7 +265,7 @@ standard Python interpreter shell unconditionally.
.. code-block:: text
[chrism@vitaminf bfgshellenv]$ ../bin/paster --plugin=repoze.bfg bfgshell \
- MyProject.ini main
+ --disable-ipython MyProject.ini main
You should always use a section name argument that refers to the
actual ``app`` section within the Paste configuration file that points
@@ -292,7 +300,8 @@ against the above ``.ini`` file, an error will likely occur. Use the
most specific reference to the application within the ``.ini`` file
possible as the section name argument.
-Press "Ctrl-D" to exit the interactive shell.
+Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on
+Windows).
.. index::
single: running an application
@@ -321,8 +330,8 @@ Here's sample output from a run of ``paster serve``:
Starting server in PID 16601.
serving on 0.0.0.0:6543 view at http://127.0.0.1:6543
-By default, generated :mod:`repoze.bfg` applications will listen on
-TCP port 6543.
+By default, :mod:`repoze.bfg` applications generated from a ``paster``
+template will listen on TCP port 6543.
During development, it's often useful to run ``paster serve`` using
its ``--reload`` option. When ``--reload`` is passed to ``paster
@@ -345,47 +354,46 @@ For more detailed information about the startup process, see
variables and configuration file settings that influence startup and
runtime behavior, see :ref:`environment_chapter`.
-.. topic:: Disusing ``paster serve`` and Using Alternate Servers
-
- The code generated by :mod:`repoze.bfg` ``paster`` templates
- assumes that you will be using the ``paster serve`` command to
- start your application while you do development. However, ``paster
- serve`` is by no means the only way to start up and serve a
- :mod:`repoze.bfg` application. As we saw in
- :ref:`configuration_narr`, ``paster serve`` needn't be invoked at
- all to run a :mod:`repoze.bfg` application. The use of ``paster
- serve`` to run a :mod:`repoze.bfg` application is purely
- conventional based on the output of its ``paster`` templates.
-
- Any :term:`WSGI` server is capable of running a :mod:`repoze.bfg`
- application. Some WSGI servers don't require the
- :term:`PasteDeploy` framework's ``paster serve`` command to do
- server process management at all. Each :term:`WSGI` server has its
- own documentation about how it creates a process to run an
- application, and there are many of them, so we cannot provide the
- details for each here. But the concepts are largely the same,
- whatever server you happen to use.
-
- One popular production alternative to a ``paster``-invoked server
- is :term:`mod_wsgi`. can also use :term:`mod_wsgi` to serve your
- :mod:`repoze.bfg` application using the Apache web server rather
- than any "pure-Python" server that is started as a result of
- ``paster serve``. See :ref:`modwsgi_tutorial` for details.
- However, it is usually easier to *develop* an application using a
- ``paster serve`` -invoked webserver, as exception and debugging
- output will be sent to the console.
+Using an Alternate WSGI Server
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The code generated by :mod:`repoze.bfg` ``paster`` templates assumes
+that you will be using the ``paster serve`` command to start your
+application while you do development. However, ``paster serve`` is by
+no means the only way to start up and serve a :mod:`repoze.bfg`
+application. As we saw in :ref:`configuration_narr`, ``paster serve``
+needn't be invoked at all to run a :mod:`repoze.bfg` application. The
+use of ``paster serve`` to run a :mod:`repoze.bfg` application is
+purely conventional based on the output of its ``paster`` templates.
+
+Any :term:`WSGI` server is capable of running a :mod:`repoze.bfg`
+application. Some WSGI servers don't require the :term:`PasteDeploy`
+framework's ``paster serve`` command to do server process management
+at all. Each :term:`WSGI` server has its own documentation about how
+it creates a process to run an application, and there are many of
+them, so we cannot provide the details for each here. But the
+concepts are largely the same, whatever server you happen to use.
+
+One popular production alternative to a ``paster``-invoked server is
+:term:`mod_wsgi`. can also use :term:`mod_wsgi` to serve your
+:mod:`repoze.bfg` application using the Apache web server rather than
+any "pure-Python" server that is started as a result of ``paster
+serve``. See :ref:`modwsgi_tutorial` for details. However, it is
+usually easier to *develop* an application using a ``paster serve``
+-invoked webserver, as exception and debugging output will be sent to
+the console.
Viewing the Application
-----------------------
Once your application is running via ``paster serve``, you may visit
``http://localhost:6543/`` in your browser. You will see something in
-your browser like what is displayed below:
+your browser like what is displayed in the following image:
.. image:: project.png
-That's the page shown by default when you visit an unmodified ``paster
-create`` -generated ``bfg_starter`` application.
+This is the page shown by default when you visit an unmodified
+``paster create`` -generated ``bfg_starter`` application in a browser.
.. index::
single: project structure
@@ -482,8 +490,7 @@ The ``use`` setting is required in the ``[app:main]`` section. The
``use`` setting points at a :term:`setuptools` :term:`entry point`
named ``MyProject#app`` (the ``egg:`` prefix in ``egg:MyProject#app``
indicates that this is an entry point *URI* specifier, where the
-"scheme" is "egg"; there are no other schemes currently, so the
-``egg:`` prefix is arguably not very useful).
+"scheme" is "egg").
.. sidebar:: ``setuptools`` Entry Points and PasteDeploy ``.ini`` Files
@@ -496,19 +503,18 @@ indicates that this is an entry point *URI* specifier, where the
named ``app`` (the entry point name) which has a value
``myproject.run:app``. The *key* ``app`` is what our
``egg:MyProject#app`` value of the ``use`` section in our config
- file is pointing at. The value represents a Python "dotted-name"
- path, which refers to a callable in our ``myproject`` package's
- ``run.py`` module.
-
- In English, this entry point can thus be referred to as a "Paste
- application factory in the ``MyProject`` project which has the
- entry point named ``app`` where the entry point refers to a ``app``
- function in the ``mypackage.run`` module". If indeed if you open
- up the ``run.py`` module generated within the ``myproject``
- package, you'll see a ``app`` function. This is the function
- called :term:`PasteDeploy` when the ``paster serve`` command is
- invoked against our application. It accepts a global configuration
- object and *returns* an instance of our application.
+ file is pointing at. The value represents a :term:`dotted Python
+ name` path, which refers to a callable in our ``myproject``
+ package's ``run.py`` module. In English, this entry point can thus
+ be referred to as a "Paste application factory in the ``MyProject``
+ project which has the entry point named ``app`` where the entry
+ point refers to a ``app`` function in the ``mypackage.run``
+ module". If indeed if you open up the ``run.py`` module generated
+ within the ``myproject`` package, you'll see a ``app`` function.
+ This is the function called :term:`PasteDeploy` when the ``paster
+ serve`` command is invoked against our application. It accepts a
+ global configuration object and *returns* an instance of our
+ application.
The ``use`` setting is the only setting required in the ``[app:main]``
section unless you've changed the callable referred to by the
@@ -534,9 +540,9 @@ application. See :ref:`environment_chapter` for more information
about these settings.
The ``[server:main]`` section of the configuration file configures a
-WSGI server which listens on port 6543. It is configured to listen on
-all interfaces (``0.0.0.0``). The ``Paste#http`` server will create a
-new thread for each request.
+WSGI server which listens on TCP port 6543. It is configured to
+listen on all interfaces (``0.0.0.0``). The ``Paste#http`` server
+will create a new thread for each request.
.. note::
@@ -547,7 +553,8 @@ new thread for each request.
See the :term:`PasteDeploy` documentation for more information about
other types of things you can put into this ``.ini`` file, such as
-other applications, :term:`middleware` and alternate servers.
+other applications, :term:`middleware` and alternate :term:`WSGI`
+server implementations.
.. index::
single: setup.py
@@ -564,8 +571,8 @@ distributing your application.
``setup.py`` is the defacto standard which Python developers use to
distribute their reusable code. You can read more about
- ``setup.py`` files and their usage in the :term:`Setuptools`
- documentation.
+ ``setup.py`` files and their usage in the `Setuptools documentation
+ <http://peak.telecommunity.com/DevCenter/setuptools>`_.
Our generated ``setup.py`` looks like this:
@@ -595,14 +602,15 @@ that should point at your application project's URL (if any).
be found when packaging the application. ``include_package_data``
will include non-Python files when the application is packaged if
those files are checked into version control. ``zip_safe`` indicates
-that this package is not safe to ship as a zipped egg (it will unpack
-as a directory, which is more convenient). ``install_requires`` and
-``tests_require`` indicate that this package depends on the
-``repoze.bfg`` package. ``test_suite`` points at the package for our
-application, which means all tests found in the package will be
-installed. We examined ``entry_points`` in our discussion of the
-``MyProject.ini`` file; this file defines the ``app`` entry point that
-represents our project's application.
+that this package is not safe to use as a zipped egg; instead it will
+always unpack as a directory, which is more convenient.
+``install_requires`` and ``tests_require`` indicate that this package
+depends on the ``repoze.bfg`` package. ``test_suite`` points at the
+package for our application, which means all tests found in the
+package will be run when ``setup.py test`` is invoked. We examined
+``entry_points`` in our discussion of the ``MyProject.ini`` file; this
+file defines the ``app`` entry point that represents our project's
+application.
Usually you only need to think about the contents of the ``setup.py``
file when distributing your application to other people, or when
@@ -670,7 +678,7 @@ particular way.
``configure.zcml``
~~~~~~~~~~~~~~~~~~
-The ``configure.zcml`` contains configuration statements that inform
+The ``configure.zcml`` contains configuration statements that populate
the :term:`application registry`. It looks like so:
.. literalinclude:: MyProject/myproject/configure.zcml
@@ -682,13 +690,12 @@ the :term:`application registry`. It looks like so:
namespace. Add-on packages may require other namespaces.
#. Line 4 initializes :mod:`repoze.bfg` -specific configuration
- directives by including the :mod:`repoze.bfg.includes` package.
- This causes all of the ZCML within the ``configure.zcml`` of the
- :mod:`repoze.bfg.includes` package (which can be found in the main
- :mod:`repoze.bfg` sources) to be "included" in this configuration
- file's scope. Effectively this means that we can use (for this
- example) the ``view`` and ``static`` directives which follow later
- in this file.
+ directives by including the ``repoze.bfg.includes`` package. This
+ causes all of the ZCML within the ``configure.zcml`` of the
+ ``repoze.bfg.includes`` package to be "included" in this
+ configuration file's scope. Effectively this means that we can use
+ (for this example) the ``view`` and ``static`` directives which
+ follow later in this file.
#. Lines 6-10 register a "default view" (a view that has no ``name``
attribute). It is registered so that it will be found when the
@@ -711,9 +718,9 @@ the :term:`application registry`. It looks like so:
is a template that will be used to render the result of the view
callable. This particular view declaration points at
``templates/mytemplate.pt``, which is a *relative* file
- specification (it's relative to the directory in which the
- ``configure.zcml`` file lives). The template file it points at is
- a :term:`Chameleon` ZPT template file.
+ specification; it's relative to the directory in which the
+ ``configure.zcml`` file lives. The template file it points at is a
+ :term:`Chameleon` ZPT template file.
#. Lines 12-15 register a static view, which will register a view
which serves up the files from the ``templates/static`` directory
@@ -729,20 +736,21 @@ the :term:`application registry`. It looks like so:
~~~~~~~~~~~~
Much of the heavy lifting in a :mod:`repoze.bfg` application comes in
-the form of *view callables*. A :term:`view callable` is the bridge
-between the content in the model, and the response given back to a
-browser.
+the form of *view callables*. A :term:`view callable` is the main
+tool of a :mod:`repoze.bfg` web application developer; it is a bit of
+code which accepts a :term:`request` and which returns a
+:term:`response`.
.. literalinclude:: MyProject/myproject/views.py
:linenos:
-Lines 1-2 provide the ``my_view`` that was registered as the view
-callable. ``configure.zcml`` said that the default URL for instances
-that are of the class :class:`myproject.models.MyModel` should run
-this :func:`myproject.views.my_view` function.
+This bit of code was registered as the view callable within
+``configure.zcml``. ``configure.zcml`` said that the default URL for
+instances that are of the class :class:`myproject.models.MyModel`
+should run this :func:`myproject.views.my_view` function.
This view callable function is handed a single piece of information:
-the the :term:`request`. The *request* is an instance of the
+the :term:`request`. The *request* is an instance of the
:term:`WebOb` ``Request`` class representing the browser's request to
our server.
@@ -774,9 +782,10 @@ views, renderers, and templates relate and cooperate.
``models.py``
~~~~~~~~~~~~~
-The ``models.py`` module provides the :term:`model` data for our
-application. We write a class named ``MyModel`` that provides the
-behavior.
+The ``models.py`` module provides the :term:`model` data and behavior
+for our application. Models are objects which store application data
+and provide APIs which mutate and return this data. We write a class
+named ``MyModel`` that provides the behavior.
.. literalinclude:: MyProject/myproject/models.py
:linenos:
@@ -804,8 +813,8 @@ so the sample application uses an instance of
~~~~~~~~~~
We need a small Python module that configures our application and
-advertises itself to our :term:`PasteDeploy` ``.ini`` file. This is
-the file named ``run.py``:
+which advertises an entry point for use by our :term:`PasteDeploy`
+``.ini`` file. This is the file named ``run.py``:
.. literalinclude:: MyProject/myproject/run.py
:linenos:
@@ -853,10 +862,10 @@ The ``tests.py`` module includes unit tests for your application.
:linenos:
This sample ``tests.py`` file has a single unit test defined within
-it. This test is executed when you run ``python setup.py test -q``.
-You may add more tests here as you build your application. You are
-not required to write tests to use :mod:`repoze.bfg`, this file is
-simply provided as convenience and example.
+it. This test is executed when you run ``python setup.py test``. You
+may add more tests here as you build your application. You are not
+required to write tests to use :mod:`repoze.bfg`, this file is simply
+provided as convenience and example.
See :ref:`unittesting_chapter` for more information about writing
:mod:`repoze.bfg` unit tests.
diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst
index 197df130e..9dd22905f 100644
--- a/docs/narr/resources.rst
+++ b/docs/narr/resources.rst
@@ -74,7 +74,6 @@ package. Resource names usually look a lot like relative UNIX file
paths.
.. index::
- single: overriding resources
pair: overriding; resources
.. _overriding_resources_section:
diff --git a/docs/narr/router.rst b/docs/narr/router.rst
index c14118772..1b0575f50 100644
--- a/docs/narr/router.rst
+++ b/docs/narr/router.rst
@@ -1,6 +1,7 @@
.. index::
single: request processing
single: request
+ single: router
.. _router_chapter:
diff --git a/docs/narr/security.rst b/docs/narr/security.rst
index b0c0ef666..67f6342df 100644
--- a/docs/narr/security.rst
+++ b/docs/narr/security.rst
@@ -1,3 +1,6 @@
+.. index::
+ single: security
+
.. _security_chapter:
Security
@@ -19,7 +22,7 @@ Here's how it works at a high level:
finding.
- A :term:`view callable` is located by :term:`view lookup` using the
- the context as well as other attributes of the request.
+ context as well as other attributes of the request.
- If an :term:`authentication policy` is in effect, it is passed the
request; it returns some number of :term:`principal` identifiers.
@@ -66,7 +69,7 @@ policies.
applications.
.. index::
- pair: enabling; authorization policy
+ single: authorization policy
Enabling an Authorization Policy
--------------------------------
@@ -79,9 +82,6 @@ to enable an authorization policy.
You can enable an authorization policy imperatively, or declaratively
via ZCML.
-.. index::
- triple: enabling; authorization policy; imperatively
-
Enabling an Authorization Policy Imperatively
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -125,9 +125,6 @@ See also the :mod:`repoze.bfg.authorization` and
:mod:`repoze.bfg.authentication` modules for alternate implementations
of authorization and authentication policies.
-.. index::
- triple: enabling; authorization policy; via ZCML
-
Enabling an Authorization Policy Via ZCML
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -393,7 +390,7 @@ ACE, as below.
.. index::
single: principal
- pair: special; principal names
+ single: principal names
Special Principal Names
-----------------------
@@ -417,7 +414,8 @@ ACLs, e.g. :data:`repoze.bfg.security.Everyone`.
(``system.Authenticated``).
.. index::
- pair: special; permission names
+ single: permission names
+ single: special permission names
Special Permissions
-------------------
@@ -437,7 +435,8 @@ module. These can be imported for use in ACLs.
given principal "has" any permission asked for by the system.
.. index::
- pair: special; ACE
+ single: special ACE
+ single: ACE (special)
Special ACEs
------------
@@ -501,7 +500,7 @@ See :ref:`location_module` for documentations of functions which use
location-awareness. See also :ref:`location_aware`.
.. index::
- pair: forbidden view; changing
+ single: forbidden view
Changing the Forbidden View
---------------------------
@@ -514,7 +513,7 @@ instructions on how to create a custom forbidden view and arrange for
it to be called when view authorization is denied.
.. index::
- pair: debugging; authorization failures
+ single: debugging authorization failures
.. _debug_authorization_section:
@@ -667,7 +666,7 @@ In other words, it has no configuration attributes; its existence in a
See :ref:`aclauthorizationpolicy_directive` for detailed information.
.. index::
- pair: creating; authentication policy
+ single: authentication policy (creating)
.. _creating_an_authentication_policy:
@@ -710,7 +709,7 @@ After you do so, you can pass an instance of such a class into the
time as ``authentication_policy`` to use it.
.. index::
- pair: creating; authorization policy
+ single: authorization policy (creating)
.. _creating_an_authorization_policy:
diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst
index 6a83d1aba..e69bf75b1 100644
--- a/docs/narr/startup.rst
+++ b/docs/narr/startup.rst
@@ -14,7 +14,7 @@ you'll see something much like this show up on the console:
This chapter explains what happens between the time you press the
"Return" key on your keyboard after typing ``paster serve
-myproject/MyProject.ini`` and the the time the line ``serving on
+myproject/MyProject.ini`` and the time the line ``serving on
0.0.0.0:6543 ...`` is output to your console.
.. index::
diff --git a/docs/narr/static.rst b/docs/narr/static.rst
index 04d76fca1..a98de3c7a 100644
--- a/docs/narr/static.rst
+++ b/docs/narr/static.rst
@@ -80,7 +80,8 @@ directive. Use of the ``add_static_view`` imperative configuration
method is completely equivalent to using ZCML for the same purpose.
.. index::
- triple: generating; static resource; urls
+ single: generating static resource urls
+ single: static resource urls
.. _generating_static_resource_urls:
@@ -151,7 +152,7 @@ URLs will continue to resolve properly after the rename.
:mod:`repoze.bfg` 1.1.
.. index::
- pair: view; static resource
+ single: static resource view
Advanced: Serving Static Resources Using a View Callable
--------------------------------------------------------
diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst
index 115cf9b6e..c073d201f 100644
--- a/docs/narr/templates.rst
+++ b/docs/narr/templates.rst
@@ -111,7 +111,9 @@ For example, here's an example of using `Mako
:term:`renderer`. However, it's reasonably easy to write custom
templating system binding packages for use under :mod:`repoze.bfg`
so that templates written in the language can be used as renderers.
- See :ref:`available_template_system_bindings` for example packages.
+ See :ref:`adding_and_overriding_renderers` for instructions on how
+ to create your own template renderer and
+ :ref:`available_template_system_bindings` for example packages.
If you need more control over the status code and content-type, or
other response attributes from views that use direct templating, you
@@ -148,7 +150,8 @@ Here's an example of manufacturing a response object using the result of
.. index::
single: templates used as renderers
- pair: renderers; template
+ single: template renderers
+ single: renderer (template)
.. _templates_used_as_renderers:
@@ -205,7 +208,7 @@ renderer configuration can be done imperatively and via :term:`ZCML`.
See :ref:`views_which_use_a_renderer`. See also
:ref:`built_in_renderers`.
-Not just any template from any arbitrary templating systemmay be used
+Not just any template from any arbitrary templating system may be used
as a renderer. Bindings must exist specifically for :mod:`repoze.bfg`
to use a templating language template as a renderer. Currently,
:mod:`repoze.bfg` has built-in support for two Chameleon templating
@@ -226,14 +229,12 @@ of :term:`Jinja2` templates as renderers. See
out of the response body (often HTML). View callables which use
renderers typically return a dictionary, and making assertions
about the information is almost always more direct than needing to
- parse HTML.
-
- Specifying a renderer from within :term:`ZCML` (as opposed to
- imperatively or via a ``bfg_view`` decorator, or using a template
- directly from within a view callable) also makes it possible for
- someone to modify the template used to render a view without
- needing to fork your code to do so. See :ref:`extending_chapter`
- for more information.
+ parse HTML. Specifying a renderer from within :term:`ZCML` (as
+ opposed to imperatively or via a ``bfg_view`` decorator, or using a
+ template directly from within a view callable) also makes it
+ possible for someone to modify the template used to render a view
+ without needing to fork your code to do so. See
+ :ref:`extending_chapter` for more information.
By default, views rendered via a template renderer return a
:term:`Response` object which has a *status code* of ``200 OK`` and a
@@ -244,7 +245,8 @@ within the view before returning the dictionary. See
:ref:`response_request_attrs` for more information.
.. index::
- triple: Chameleon; ZPT; templates
+ single: Chameleon ZPT templates
+ single: ZPT templates (Chameleon)
.. _chameleon_zpt_templates:
@@ -329,6 +331,7 @@ works in these templates.
.. index::
single: ZPT macros
+ single: Chameleon ZPT macros
Using ZPT Macros in :mod:`repoze.bfg`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -390,7 +393,7 @@ And ``templates/mytemplate.pt`` might look like so:
</html>
.. index::
- pair: Chameleon; text templates
+ single: Chameleon text templates
.. _chameleon_text_templates:
@@ -435,7 +438,7 @@ See also :ref:`built_in_renderers` for more general information about
renderers, including Chameleon text renderers.
.. index::
- pair: template renderer; side effects
+ single: template renderer side effects
Side Effects of Rendering a Chameleon Template
----------------------------------------------
@@ -448,10 +451,9 @@ files showing up in your ``templates`` directory (or otherwise
directly "next" to your templates), it is due to this feature.
If you're using a version control system such as Subversion, you
-should cause it to ignore these files. Here's the contents of my
-``svn propedit svn:ignore .`` in each of my ``templates`` directories.
-(Note that I always name my Chameleon ZPT template files with a
-``.pt`` extension, so that this pattern works):
+should cause it to ignore these files. Here's the contents of the
+author's ``svn propedit svn:ignore .`` in each of my ``templates``
+directories.
.. code-block:: bash
:linenos:
@@ -459,8 +461,13 @@ should cause it to ignore these files. Here's the contents of my
*.pt.py
*.txt.py
+Note that I always name my Chameleon ZPT template files with a ``.pt``
+extension and my Chameleon text template files with a ``.txt``
+extension so that these ``svn:ignore`` patterns work.
+
.. index::
- pair: template; automatic reloading
+ single: automatic reloading of templates
+ single: template automatic reload
.. _reload_templates_section:
@@ -486,7 +493,7 @@ variable set to ``1``, For example::
$ BFG_RELOAD_TEMPLATES=1 bin/paster serve myproject.ini
-To use a setting in the the application ``.ini`` file for the same
+To use a setting in the application ``.ini`` file for the same
purpose, set the ``reload_templates`` key to ``true`` within the
application's configuration section, e.g.::
@@ -495,7 +502,8 @@ application's configuration section, e.g.::
reload_templates = true
.. index::
- pair: template; internationalization
+ single: template internationalization
+ single: internationalization (of templates)
:term:`Chameleon` Template Internationalization
-----------------------------------------------
diff --git a/docs/narr/threadlocals.rst b/docs/narr/threadlocals.rst
index 4600b7a88..a2f5cc192 100644
--- a/docs/narr/threadlocals.rst
+++ b/docs/narr/threadlocals.rst
@@ -1,5 +1,5 @@
.. index::
- single: thread local variables
+ single: thread locals
single: get_current_request
single: get_current_registry
@@ -132,9 +132,9 @@ follows:
ever be called within application-specific forks of third-party
library code. The library you've forked almost certainly has
nothing to do with :mod:`repoze.bfg`, and making it dependent on
- repoze.bfg (rather than making your :mod:`repoze.bfg` application
- depend upon it) means you're forming a dependency in the wrong
- direction.
+ :mod:`repoze.bfg` (rather than making your :mod:`repoze.bfg`
+ application depend upon it) means you're forming a dependency in the
+ wrong direction.
Use of the :func:`repoze.bfg.threadlocal.get_current_request` function
in application code *is* still useful in very limited circumstances.
diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst
index bb773c195..2388aa7f3 100644
--- a/docs/narr/traversal.rst
+++ b/docs/narr/traversal.rst
@@ -76,7 +76,7 @@ the combination of the :term:`view name` and the :term:`context`.
Traversal is the act of obtaining these two items.
.. index::
- pair: traversal; high-level overview
+ single: traversal overview
A High-Level Overview of Traversal
----------------------------------
@@ -87,7 +87,7 @@ the ``PATH_INFO`` portion of the :term:`WSGI` environment. The
``PATH_INFO`` portion of the WSGI environment is the portion of a
request's URL following the hostname and port number, but before any
query string elements or fragment element. For example the
-``PATH_INFO`` portion of the the URL
+``PATH_INFO`` portion of the URL
``http://example.com:8080/a/b/c?foo=1`` is ``/a/b/c``.
Traversal treats the ``PATH_INFO`` segment of a URL as a sequence of
@@ -243,10 +243,11 @@ Each container node is presumed to be willing to return a child node
or raise a ``KeyError`` based on a name passed to its ``__getitem__``.
No leaf-level instance is required to have a ``__getitem__``. If
-leaf-level instances happen to have a ``__getitem__`` (through some
-historical inequity), you should subclass these node types and cause
-their ``__getitem__`` methods to simply raise a ``KeyError``. Or just
-disuse them and think up another strategy.
+instances that you'd like to be leaves already happen to have a
+``__getitem__`` through some historical inequity, you should subclass
+these node types and cause their ``__getitem__`` methods to simply
+raise a ``KeyError``. Or just disuse them and think up another
+strategy.
Usually, the traversal root is a *container* node, and as such it
contains other nodes. However, it doesn't *need* to be a container.
@@ -263,6 +264,7 @@ until all path segments are exhausted.
.. index::
single: traversal algorithm
+ single: view lookup
.. _traversal_algorithm:
@@ -285,10 +287,14 @@ sections to give you an idea of how traversal and view lookup
cooperate, because they are almost always used together.
.. index::
- pair: traversal; algorithm
+ single: view name
+ single: context
+ single: subpath
+ single: root factory
+ single: default view
-A Descrption of The Traversal Algorithm
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+A Description of The Traversal Algorithm
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When a user requests a page from your :mod:`traversal` -powered
application, the system uses this algorithm to find a :term:`context`
@@ -344,7 +350,7 @@ and a :term:`view name`.
should be treated as a :term:`view name`).
#. When traversal ends for any of the reasons in the previous step,
- the the last object found during traversal is deemed to be the
+ the last object found during traversal is deemed to be the
:term:`context`. If the path has been exhausted when traversal
ends, the :term:`view name` is deemed to be the empty string
(``''``). However, if the path was *not* exhausted before
@@ -386,7 +392,7 @@ about it in this chapter.
.. image:: modelgraphtraverser.png
.. index::
- pair: traversal; examples
+ single: traversal examples
Traversal Algorithm Examples
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -509,10 +515,12 @@ expected to return a response.
:ref:`request_and_context_view_definitions`. But you don't need to
if you don't want to. In view callables that accept only a
request, the :term:`context` found by traversal is available as the
- ``context`` attribute of the request object. The :term:`view name`
- is available as the ``view_name`` attribute of the request object.
- Other :mod:`repoze.bfg` -speficic request attributes are also
- available as described in :ref:`special_request_attributes`.
+ ``context`` attribute of the request object,
+ e.g. ``request.context``. The :term:`view name` is available as
+ the ``view_name`` attribute of the request object,
+ e.g. ``request.view_name``. Other :mod:`repoze.bfg` -speficic
+ request attributes are also available as described in
+ :ref:`special_request_attributes`.
References
----------
diff --git a/docs/narr/unittesting.rst b/docs/narr/unittesting.rst
index 9e36ea051..a13f90952 100644
--- a/docs/narr/unittesting.rst
+++ b/docs/narr/unittesting.rst
@@ -17,7 +17,7 @@ the "unit under test". If you write a unit test that aims to verify
the result of a particular codepath through a Python function, you
need only be concerned about testing the code that *lives in the
function body itself*. If the function accepts a parameter that
-represents a complex application "domain object" (such a a model, a
+represents a complex application "domain object" (such as a model, a
database connection, or an SMTP server), the argument provided to this
function during a unit test *need not be* and likely *should not be* a
"real" implementation object. For example, although a particular
@@ -58,8 +58,8 @@ useful when your code calls into :mod:`repoze.bfg` -related framework
functions.
.. index::
- pair: test; setup
- pair: test; tear down
+ single: test setup
+ single: test tear down
single: unittest
.. _test_setup_and_teardown:
@@ -164,7 +164,7 @@ anything if the application you're testing does not call any
.. index::
single: repoze.bfg.testing
- pair: Configurator; testing
+ single: Configurator testing API
Using the ``Configurator`` and ``repoze.bfg.testing`` APIs in Unit Tests
------------------------------------------------------------------------
@@ -299,7 +299,7 @@ See also the various methods of the :term:`Configurator` documented in
:ref:`configuration_module` that begin with the ``testing_`` prefix.
.. index::
- pair: creating; integration tests
+ single: integration tests
.. _integration_tests:
diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst
index 25149f30f..d7e3a17fb 100644
--- a/docs/narr/urldispatch.rst
+++ b/docs/narr/urldispatch.rst
@@ -1,5 +1,5 @@
.. index::
- single: url dispatch
+ single: URL dispatch
.. _urldispatch_chapter:
@@ -64,12 +64,13 @@ using :term:`traversal` to perform context finding and view lookup.
Route Configuration
-------------------
-:term:`route configuration` is the act of adding a new :term:`route`
+:term:`Route configuration` is the act of adding a new :term:`route`
to an application. A route has a *path*, representing a pattern meant
to match against the ``PATH_INFO`` portion of a URL, and a *name*,
which is used by developers within a :mod:`repoze.bfg` application to
uniquely identify a particular route when generating a URL. It also
-optionally has a ``factory`` and a set of :term:`view` parameters.
+optionally has a ``factory``, a set of :term:`route predicate`
+parameters, and a set of :term:`view` parameters.
A route configuration may be added to the system via :term:`imperative
configuration` or via :term:`ZCML`. Both are completely equivalent.
@@ -204,7 +205,7 @@ developer to combine :term:`URL dispatch` and :term:`traversal` in
various exceptional cases as documented in :ref:`hybrid_chapter`.
.. index::
- pair: URL dispatch; path pattern syntax
+ single: route path pattern syntax
.. _route_path_pattern_syntax:
@@ -319,11 +320,7 @@ Will generate the following matchdict:
{'fizzle':(u'La Pe\xf1a', u'a', u'b', u'c')}
.. index::
- triple: ZCML directive; route; examples
-
-
-.. index::
- pair: route; ordering
+ single: route ordering
Route Declaration Ordering
~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -354,10 +351,11 @@ patterns might be added in the following order:
In such a configuration, the ``members/abc`` pattern would *never* be
matched; this is because the match ordering will always match
-``members/:def`` first and ``members/abc`` will never be reached.
+``members/:def`` first; the route configuration with ``members/abc``
+will never be evaluated.
.. index::
- pair: route; factory
+ single: route factory
Route Factories
~~~~~~~~~~~~~~~
@@ -624,7 +622,7 @@ finding` and :term:`view lookup`.
.. index::
- pair: URL dispatch; matchdict
+ single: matchdict
The Matchdict
~~~~~~~~~~~~~
@@ -843,7 +841,8 @@ More uses for this style of associating views with routes are explored
in :ref:`hybrid_chapter`.
.. index::
- pair: URL dispatch; matching the root URL
+ single: matching the root URL
+ single: root url (matching)
Matching the Root URL
---------------------
@@ -873,7 +872,8 @@ Or provide the literal string ``/`` as the path:
/>
.. index::
- pair: URL dispatch; generating route URLs
+ single: generating route URLs
+ single: route URLs
Generating Route URLs
---------------------
@@ -897,7 +897,7 @@ hostname implied ``http:/example.com``). See the
information.
.. index::
- pair: URL dispatch; slash-redirecting
+ single: redirecting to slash-appended routes
Redirecting to Slash-Appended Routes
------------------------------------
@@ -1022,13 +1022,12 @@ Using :mod:`repoze.bfg` Security With URL Dispatch
:mod:`repoze.bfg` provides its own security framework which consults a
:term:`authorization policy` before allowing any application code to
-be called. This framework operates in terms of ACLs (Access Control
-Lists, see :ref:`security_chapter` for more information about the
-:mod:`repoze.bfg` authorization subsystem). A common thing to want to
-do is to attach an ``__acl__`` to the context object dynamically for
-declarative security purposes. You can use the ``factory`` argument
-that points at a factory which attaches a custom ``__acl__`` to an
-object at its creation time.
+be called. This framework operates in terms of an access control
+list, which is stored as an ``__acl__`` attribute of a context object.
+A common thing to want to do is to attach an ``__acl__`` to the
+context object dynamically for declarative security purposes. You can
+use the ``factory`` argument that points at a factory which attaches a
+custom ``__acl__`` to an object at its creation time.
Such a ``factory`` might look like so:
@@ -1053,38 +1052,6 @@ not very ambitious.
.. note:: See :ref:`security_chapter` for more information about
:mod:`repoze.bfg` security and ACLs.
-Using Context Within a View Callable
-------------------------------------
-
-When using :term:`url dispatch` exclusively in an application (as
-opposed to using both url dispatch *and* :term:`traversal` in the same
-application), the :term:`context` of the view isn't always terribly
-interesting, particularly if you never use a ``factory`` attribute on
-your route definitions.
-
-However, if you do use a ``factory`` attribute on your route
-definitions, you may be very interested in the :term:`context` of the
-view. You can access the ``context`` of a view within the body of a
-view callable via ``request.context``
-
-:mod:`repoze.bfg` also supports view callables defined with two
-arguments: ``context`` and ``request``. For example, the below
-function can be used as a view callable.
-
-.. code-block:: python
- :linenos:
-
- from webob import Response
-
- def hello_view(context, request):
- return Response('Hello!')
-
-The ``context`` passed to this view will be an instance returned by
-the default root factory or an instance returned by the ``factory``
-argument to your route definition.
-
-See :ref:`request_and_context_view_definitions` for more information.
-
References
----------
diff --git a/docs/narr/vhosting.rst b/docs/narr/vhosting.rst
index be42dc842..ddb90eb36 100644
--- a/docs/narr/vhosting.rst
+++ b/docs/narr/vhosting.rst
@@ -1,3 +1,6 @@
+.. index::
+ single: virtual hosting
+
.. _vhosting_chapter:
Virtual Hosting
@@ -11,9 +14,6 @@ URL space that it does not "naturally" inhabit.
a URL "prefix", as well as serving a *portion* of a :term:`traversal`
based application under a root URL.
-.. index::
- pair: virtual hosting; URL prefix
-
Hosting an Application Under a URL Prefix
-----------------------------------------
@@ -75,7 +75,7 @@ In the above configuration, we root a :mod:`repoze.bfg` application at
``/bfgapp`` within the Apache configuration.
.. index::
- pair: virtual hosting; virtual root
+ single: virtual root
Virtual Root Support
--------------------
diff --git a/docs/narr/views.rst b/docs/narr/views.rst
index 28b8b4290..4ee66d709 100644
--- a/docs/narr/views.rst
+++ b/docs/narr/views.rst
@@ -28,8 +28,8 @@ The job of actually locating and invoking the "best" :term:`view
callable` is the job of the :term:`view lookup` subsystem. The view
lookup subsystem compares information supplied by :term:`context
finding` against :term:`view configuration` statements made by the
-developer to choose the most appropriate view callable for a specific
-request.
+developer stored in the :term:`application registry` to choose the
+most appropriate view callable for a specific request.
This chapter provides documentation detailing the process of creating
view callables, documentation about performing view configuration, and
@@ -57,9 +57,8 @@ callables can optionally be defined with an alternate calling
convention.
.. index::
- pair: view; calling convention
+ single: view calling convention
single: view function
- pair: view; function
.. _function_as_view:
@@ -80,9 +79,8 @@ callable implemented as a function:
return Response('Hello world!')
.. index::
- pair: view; calling convention
+ single: view calling convention
single: view class
- pair: view; class
.. _class_as_view:
@@ -101,8 +99,9 @@ with no parameters. Views defined as classes must have the following
traits:
- an ``__init__`` method that accepts a ``request`` as its sole
- positional argument (or two arguments: ``request`` and ``context``,
- as per :ref:`request_and_context_view_definitions`).
+ positional argument or an ``__init__`` method that accepts two
+ arguments: ``request`` and ``context`` as per
+ :ref:`request_and_context_view_definitions`.
- a ``__call__`` method that accepts no parameters and which returns a
response.
@@ -127,10 +126,10 @@ object described in :ref:`function_as_view`.
If you'd like to use a different attribute than ``__call__`` to
represent the method expected to return a response, you can use an
``attr`` value as part of view configuration. See
-:ref:`view_configuration`.
+:ref:`view_configuration_parameters`.
.. index::
- pair: view; calling convention
+ single: view calling convention
.. _request_and_context_view_definitions:
@@ -201,7 +200,8 @@ No matter which view calling convention is used, the view code always
has access to the context via ``request.context``.
.. index::
- pair: view; response
+ single: view response
+ single: response
.. _the_response:
@@ -237,7 +237,8 @@ can be varied by changing the ``renderer`` attribute in the view's
configuration. See :ref:`views_which_use_a_renderer`.
.. index::
- pair: view; http redirect
+ single: view http redirect
+ single: http redirect (from a view)
Using a View Callable to Do A HTTP Redirect
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -256,11 +257,12 @@ particular kind of response.
All exception types from the :mod:`webob.exc` module implement the
Webob :term:`Response` interface; any can be returned as the response
from a view. See :term:`WebOb` for the documentation for this module;
-it includes other response types for ``Unauthorized``, etc.
+it includes other response types that imply other HTTP response codes,
+such as ``401 Unauthorized``.
.. index::
single: renderer
- pair: view; renderer
+ single: view renderer
.. _views_which_use_a_renderer:
@@ -301,8 +303,7 @@ which renders view return values to a :term:`JSON` serialization.
Other built-in renderers include renderers which use the
:term:`Chameleon` templating language to render a dictionary to a
-response. See :ref:`built_in_renderers` for the available built-in
-renderers.
+response.
If the :term:`view callable` associated with a :term:`view
configuration` returns a Response object directly (an object with the
@@ -328,7 +329,8 @@ Additional renderers can be added to the system as necessary via a
ZCML directive (see :ref:`adding_and_overriding_renderers`).
.. index::
- pair: renderers; built-in
+ single: renderers (built-in)
+ single: built-in renderers
.. _built_in_renderers:
@@ -466,7 +468,8 @@ callable with an associated template returns a Python dictionary, the
named template will be passed the dictionary as its keyword arguments,
and the template renderer implementation will return the resulting
rendered template in a response to the user. If the view callable
-returns anything but a dictionary, an error will be raised.
+returns anything but a Response object or a dictionary, an error will
+be raised.
Before passing keywords to the template, the keywords derived from the
dictionary returned by the view are augmented. The callable object
@@ -512,9 +515,8 @@ attaching properties to the request. See
:ref:`response_request_attrs`.
.. index::
- pair: renderer; response attributes
- pair: renderer; changing headers
- triple: headers; changing; renderer
+ single: response headers (from a renderer)
+ single: renderer response headers
.. _response_request_attrs:
@@ -561,13 +563,13 @@ attribute to the request before returning a result:
from repoze.bfg.view import bfg_view
- @bfg_view(name='gone')
+ @bfg_view(name='gone', renderer='templates/gone.pt')
def myview(request):
request.response_status = '404 Not Found'
return {'URL':request.URL}
.. index::
- pair: renderers; adding
+ single: renderer (adding)
.. _adding_and_overriding_renderers:
@@ -804,7 +806,7 @@ See also :ref:`renderer_directive` and
:meth:`repoze.bfg.configuration.Configurator.add_renderer`.
.. index::
- triple: exceptions; special; view
+ single: view exceptions
Using Special Exceptions In View Callables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -832,7 +834,9 @@ made available to the view which :mod:`repoze.bfg` invokes as
``request.environ['repoze.bfg.message']``.
.. index::
- triple: view; forms; unicode
+ single: unicode, views, and forms
+ single: forms, views, and unicode
+ single: views, forms, and unicode
Handling Form Submissions in View Callables (Unicode and Character Set Issues)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -966,7 +970,6 @@ rendered in a request that has a ``;charset=utf-8`` stanza on its
.. index::
single: view configuration
- pair: view; configuration
.. _view_configuration:
@@ -987,17 +990,17 @@ collectively, as a :term:`triad`.
View configuration is performed in one of three ways:
- by adding a ``<view>`` declaration to :term:`ZCML` used by your
- application (see :ref:`mapping_views_using_zcml_section` and
- :ref:`view_directive`).
+ application as per :ref:`mapping_views_using_zcml_section` and
+ :ref:`view_directive`.
- by running a :term:`scan` against application source code which has
a :class:`repoze.bfg.view.bfg_view` decorator attached to a Python
- object (see :class:`repoze.bfg.view.bfg_view` and
- :ref:`mapping_views_using_a_decorator_section`).
+ object as per :class:`repoze.bfg.view.bfg_view` and
+ :ref:`mapping_views_using_a_decorator_section`.
- by using the :meth:`repoze.bfg.configuration.Configurator.add_view`
- method (see :meth:`repoze.bfg.configuration.Configurator.add_view`
- and :ref:`mapping_views_using_imperative_config_section`).
+ method as per :meth:`repoze.bfg.configuration.Configurator.add_view`
+ and :ref:`mapping_views_using_imperative_config_section`.
Each of these mechanisms is completely equivalent to the other.
@@ -1009,7 +1012,9 @@ performed in one of the following two ways:
method to create a route with a ``view`` argument.
- by adding a ``<route>`` declaration that uses a ``view`` attribute to
- :term:`ZCML` used by your application.
+ :term:`ZCML` used by your application as per :ref:`route_directive`.
+
+.. _view_configuration_parameters:
View Configuration Parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1273,7 +1278,7 @@ Predicate Arguments
.. note:: This feature is new as of :mod:`repoze.bfg` 1.2.
.. index::
- triple: zcml; view; configuration
+ single: ZCML view configuration
.. _mapping_views_using_zcml_section:
@@ -1368,7 +1373,7 @@ apply for the class which is named.
See :ref:`view_directive` for complete ZCML directive documentation.
.. index::
- triple: view; bfg_view; decorator
+ single: bfg_view decorator
.. _mapping_views_using_a_decorator_section:
@@ -1531,7 +1536,7 @@ function. For example:
You can use the :class:`repoze.bfg.view.bfg_view` decorator as a
simple callable to manually decorate classes in Python 2.5 and below
-(without the decorator syntactic sugar), if you wish:
+without the decorator syntactic sugar, if you wish:
.. code-block:: python
:linenos:
@@ -1568,7 +1573,7 @@ This registers the same view under two different names.
.. note:: :class:`repoze.bfg.view.bfg_view` decorator stacking is a
feature new in :mod:`repoze.bfg` 1.1. Previously, these decorators
could not be stacked without the effect of the "upper" decorator
- cancelling the effect of the the decorator "beneath" it.
+ cancelling the effect of the decorator "beneath" it.
The decorator can also be used against class methods:
@@ -1622,7 +1627,6 @@ equivalently as the below:
.. index::
single: add_view
- triple: imperative; adding; view
.. _mapping_views_using_imperative_config_section:
@@ -1648,7 +1652,7 @@ example:
config.add_view(hello_world, name='hello.html')
.. index::
- pair: model; interfaces
+ single: model interfaces
.. _using_model_interfaces:
@@ -1742,7 +1746,8 @@ within view configuration, see
:ref:`models_which_implement_interfaces`.
.. index::
- pair: view; security
+ single: view security
+ pair: security; view
.. _view_security_section:
@@ -1774,7 +1779,7 @@ user does not possess the ``add`` permission relative to the current
:ref:`protecting_views`.
.. index::
- pair: view; lookup
+ single: view lookup
.. _view_lookup:
@@ -1817,7 +1822,8 @@ the user's browser, representing a "not found" (404) page. See
the default notfound view.
.. index::
- pair: debugging; not found errors
+ single: debugging not found errors
+ single: not found error (debugging)
.. _debug_notfound_section:
diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst
index c94063059..ba710d54d 100644
--- a/docs/narr/webob.rst
+++ b/docs/narr/webob.rst
@@ -1,5 +1,5 @@
.. index::
- pair: ian; bicking
+ single: Bicking, Ian
single: WebOb
.. _webob_chapter:
@@ -45,7 +45,7 @@ creating requests.
.. index::
single: request object
- single: request attributes; standard
+ single: request attributes
Request
~~~~~~~
@@ -107,7 +107,7 @@ instance, ``req.if_modified_since`` returns a `datetime
<http://pythonpaste.org/webob/class-webob.Request.html>`_.
.. index::
- pair: request attributes; special
+ single: request attributes (special)
.. _special_request_attributes:
@@ -119,35 +119,30 @@ In addition to the standard :term:`WebOb` attributes,
request.
``req.subpath``
-
The traversal :term:`subpath` will be available as the ``subpath``
attribute of the :term:`request` object. It will be a sequence
containing zero or more elements (which will be Unicode objects).
See :ref:`traversal_chapter` for information about the subpath.
``req.view_name``
-
The :term:`view name` will be available as the ``view_name``
attribute of the :term:`request` object. It will be a single string
(possibly the empty string if we're rendering a default view).
See :ref:`traversal_chapter` for information about view names.
``req.root``
-
The :term:`root` object will be available as the ``root`` attribute
of the :term:`request` object. It will be the model object at which
traversal started (the root). See :ref:`traversal_chapter` for
information about root objects.
``req.context``
-
The :term:`context` will be available as the ``context`` attribute
of the :term:`request` object. It will be the context object
implied by the current request. See :ref:`traversal_chapter` for
information about context objects.
``req.traversed``
-
The "traversal path" will be as the ``traversed`` attribute of the
:term:`request` object. It will be a sequence representing the
ordered set of names that were used to traverse to the
@@ -157,14 +152,12 @@ request.
for more information.
``req.virtual_root``
-
The :term:`virtual root` will be available as the ``virtual_root``
attribute of the :term:`request` object. It will be the virtual
root object implied by the current request. See
:ref:`vhosting_chapter` for more information about virtual roots.
``req.virtual_root_path``
-
The :term:`virtual root` *path* will be available as the
``virtual_root_path`` attribute of the :term:`request` object. It
will be a sequence representing the ordered set of names that were
@@ -172,7 +165,7 @@ request.
:ref:`vhosting_chapter` for more information about virtual roots.
.. index::
- pair: request; URLs
+ single: request URLs
URLs
++++
@@ -198,7 +191,7 @@ of the request. I'll show various values for an example URL
is True, then resolves it relative to ``req.application_url``.
.. index::
- pair: request; methods
+ single: request methods
Methods
+++++++
@@ -221,7 +214,8 @@ only a few you'll use often:
subrequests or testing.
.. index::
- pair: request; unicode
+ single: request (and unicode)
+ single: unicode (and the request)
Unicode
+++++++
@@ -312,7 +306,7 @@ Here's the highlights:
attribute later). It can also do HEAD and Range requests.
.. index::
- pair: response; headers
+ single: response headers
Headers
+++++++
@@ -325,7 +319,7 @@ The details are available in the `extracted Response documentation
<http://pythonpaste.org/webob/class-webob.Response.html>`_.
.. index::
- pair: response; creating
+ single: response (creating)
Instantiating the Response
++++++++++++++++++++++++++
@@ -345,7 +339,7 @@ default to anything, though if you subclass ``Response`` and set
``default_content_type`` you can override this behavior.
.. index::
- pair: response; exceptions
+ single: response exceptions
Exceptions
++++++++++
@@ -392,7 +386,7 @@ attributes like ``content_type``, ``charset``, etc. on these exception
objects.
.. index::
- pair: WebOb; multidict
+ single: multidict (WebOb)
Multidict
~~~~~~~~~
diff --git a/docs/tutorials/bfgwiki/authorization.rst b/docs/tutorials/bfgwiki/authorization.rst
index b2c5330f6..1b83d3651 100644
--- a/docs/tutorials/bfgwiki/authorization.rst
+++ b/docs/tutorials/bfgwiki/authorization.rst
@@ -50,8 +50,8 @@ content:
:language: python
The ``groupfinder`` function defined here is an authorization policy
-"callback"; it is a a callable that accepts a userid and a request.
-If the userid exists in the set of users known by the system, the
+"callback"; it is a callable that accepts a userid and a request. If
+the userid exists in the set of users known by the system, the
callback will return a sequence of group identifiers (or an empty
sequence if the user isn't a member of any groups). If the userid
*does not* exist in the system, the callback will return ``None``.
diff --git a/docs/tutorials/bfgwiki/basiclayout.rst b/docs/tutorials/bfgwiki/basiclayout.rst
index 213f238fd..c2b2ebd4b 100644
--- a/docs/tutorials/bfgwiki/basiclayout.rst
+++ b/docs/tutorials/bfgwiki/basiclayout.rst
@@ -106,32 +106,32 @@ function within the file named ``run.py``:
:linenos:
:language: py
-#. *Lines 1-3*. Perform some dependency imports.
+#. *Lines 1-2*. Perform some dependency imports.
-#. *Line 11*. Get the ZODB configuration from the ``tutorial.ini``
+#. *Line 12*. Get the ZODB configuration from the ``tutorial.ini``
file's ``[app:main]`` section represented by the ``settings``
dictionary passed to our ``app`` function. This will be a URI
(something like ``file:///path/to/Data.fs``).
-#. *Line 14*. We create a "finder" object using the
+#. *Line 15*. We create a "finder" object using the
``PersistentApplicationFinder`` helper class, passing it the ZODB
URI and the "appmaker" we've imported from ``models.py``.
-#. *Lines 15 - 16*. We create a :term:`root factory` which uses the
+#. *Lines 16 - 17*. We create a :term:`root factory` which uses the
finder to return a ZODB root object.
-#. *Line 17*. We construct a :term:`Configurator` with a :term:`root
+#. *Line 18*. We construct a :term:`Configurator` with a :term:`root
factory` and the settings keywords parsed by PasteDeploy. The root
factory is named ``get_root``.
-#. *Lines 18-20*. Begin configuration using the ``begin`` method of
+#. *Lines 19-21*. Begin configuration using the ``begin`` method of
the :meth:`repoze.bfg.configuration.Configurator` class, load the
``configure.zcml`` file from our package using the
:meth:`repoze.bfg.configuration.Configurator.load_zcml` method, and
end configuration using the
:meth:`repoze.bfg.configuration.Configurator.end` method.
-#. *Line 21*. Use the
+#. *Line 22*. Use the
:meth:`repoze.bfg.configuration.Configurator.make_wsgi_app` method
to return a :term:`WSGI` application.
diff --git a/docs/tutorials/bfgwiki/installation.rst b/docs/tutorials/bfgwiki/installation.rst
index fcfaff642..4f1e5a34f 100644
--- a/docs/tutorials/bfgwiki/installation.rst
+++ b/docs/tutorials/bfgwiki/installation.rst
@@ -112,7 +112,7 @@ Preparation, Windows
.. code-block:: bat
- c:\bigfntut> Scripts/easy_install -i \
+ c:\bigfntut> Scripts\easy_install -i \
http://dist.repoze.org/bfg/current/simple repoze.bfg
#. Use ``easy_install`` to install ``docutils``, ``repoze.tm``,
diff --git a/docs/tutorials/bfgwiki2/authorization.rst b/docs/tutorials/bfgwiki2/authorization.rst
index 7383fe327..9a37760f1 100644
--- a/docs/tutorials/bfgwiki2/authorization.rst
+++ b/docs/tutorials/bfgwiki2/authorization.rst
@@ -105,13 +105,13 @@ Adding ``security.py``
Add a ``security.py`` module within your package (in the same
directory as "run.py", "views.py", etc) with the following content:
The groupfinder defined here is an :term:`authentication policy`
-"callback"; it is a a callable that accepts a userid and a request.
-If the userid exists in the system, the callback will return a
-sequence of group identifiers (or an empty sequence if the user isn't
-a member of any groups). If the userid *does not* exist in the
-system, the callback will return ``None``. We'll use "dummy" data to
-represent user and groups sources. When we're done, your
-application's ``security.py`` will look like this.
+"callback"; it is a callable that accepts a userid and a request. If
+the userid exists in the system, the callback will return a sequence
+of group identifiers (or an empty sequence if the user isn't a member
+of any groups). If the userid *does not* exist in the system, the
+callback will return ``None``. We'll use "dummy" data to represent
+user and groups sources. When we're done, your application's
+``security.py`` will look like this.
.. literalinclude:: src/authorization/tutorial/security.py
:linenos:
diff --git a/docs/tutorials/bfgwiki2/basiclayout.rst b/docs/tutorials/bfgwiki2/basiclayout.rst
index 70e7a8a62..4c2d5d238 100644
--- a/docs/tutorials/bfgwiki2/basiclayout.rst
+++ b/docs/tutorials/bfgwiki2/basiclayout.rst
@@ -82,25 +82,25 @@ Here is the source for ``models.py``:
manager* instead of controlling commits and aborts to database
operations by hand.
-#. *Line 20*. Set up a SQLAlchemy metadata object.
+#. *Line 21*. Set up a SQLAlchemy metadata object.
-#. *Lines 22-24*. A model class named ``Model``. It has an
+#. *Lines 23-25*. A model class named ``Model``. It has an
``__init__`` that takes a single argument (``name``). It stores a
single attribute named ``name``.
-#. *Lines 26-31*. A SQLAlchemy ``Table`` declaration named
+#. *Lines 27-32*. A SQLAlchemy ``Table`` declaration named
``models_table`` which we'll use later to map onto our ``Model``
class.
-#. *Line 33*. We map our ``models_table`` table to our Models class
+#. *Line 34*. We map our ``models_table`` table to our Models class
here. This makes an association between the ``Model`` class and
the ``models`` table in the database, as far as SQLAlchemy is
concerned.
-#. *Lines 35-40*. A function named ``populate`` which adds a single
+#. *Lines 36-41*. A function named ``populate`` which adds a single
model instance into our SQL storage and commits a transaction.
-#. *Lines 42-50*. A function named ``initialize_sql`` which sets up
+#. *Lines 43-51*. A function named ``initialize_sql`` which sets up
an actual SQL database and binds it to our SQLAlchemy DBSession
object. It also calls the ``populate`` function, to do initial
database population.
diff --git a/docs/tutorials/bfgwiki2/definingmodels.rst b/docs/tutorials/bfgwiki2/definingmodels.rst
index 214a5e908..d2db4955e 100644
--- a/docs/tutorials/bfgwiki2/definingmodels.rst
+++ b/docs/tutorials/bfgwiki2/definingmodels.rst
@@ -68,6 +68,11 @@ Viewing the Application in a Browser
------------------------------------
We can't. At this point, our system is in a "non-runnable" state;
-we'll need to change the "views" (and associated files) in the next
-chapter to be able to start and run the application successfully.
+we'll need to change view-related files in the next chapter to be able
+to start the application successfully. If you try to start the
+application, you'll wind up with a Python traceback on your console
+that ends with this exception:
+.. code-block:: text
+
+ ImportError: cannot import name Model
diff --git a/docs/tutorials/bfgwiki2/installation.rst b/docs/tutorials/bfgwiki2/installation.rst
index 1a37e1c4d..4c8dc7080 100644
--- a/docs/tutorials/bfgwiki2/installation.rst
+++ b/docs/tutorials/bfgwiki2/installation.rst
@@ -113,7 +113,7 @@ Preparation, Windows
.. code-block:: text
- c:\bigfntut> Scripts/easy_install -i \
+ c:\bigfntut> Scripts\easy_install -i \
http://dist.repoze.org/bfg/current/simple repoze.bfg
#. Use ``easy_install`` to install various packages from PyPI.
diff --git a/docs/whatsnew-1.1.rst b/docs/whatsnew-1.1.rst
index 21dd2f471..e9f975373 100644
--- a/docs/whatsnew-1.1.rst
+++ b/docs/whatsnew-1.1.rst
@@ -783,8 +783,8 @@ Deprecations and Behavior Differences
- The import of ``repoze.bfg.security.Unauthorized`` is deprecated in
favor of ``repoze.bfg.exceptions.Forbidden``. The old location
still functions but emits a deprecation warning. The rename from
- ``Unauthorized`` to ``Forbidden`` brings parity to the the name of
- the exception and the system view it invokes when raised.
+ ``Unauthorized`` to ``Forbidden`` brings parity to the name of the
+ exception and the system view it invokes when raised.
- Custom ZCML directives which register an authentication or
authorization policy (ala "authtktauthenticationpolicy" or
diff --git a/repoze/bfg/authorization.py b/repoze/bfg/authorization.py
index 9ba9eae40..8c46b4a33 100644
--- a/repoze/bfg/authorization.py
+++ b/repoze/bfg/authorization.py
@@ -12,7 +12,7 @@ from repoze.bfg.security import Everyone
class ACLAuthorizationPolicy(object):
""" An :term:`authorization policy` which consults an :term:`ACL`
object attached to a :term:`context` to determine authorization
- information about a a :term:`principal` or multiple principals.
+ information about a :term:`principal` or multiple principals.
If the context is part of a :term:`lineage`, the context's parents
are consulted for ACL information too. The following is true
about this security policy.
diff --git a/repoze/bfg/paster.py b/repoze/bfg/paster.py
index 452c13fc5..da1be9692 100644
--- a/repoze/bfg/paster.py
+++ b/repoze/bfg/paster.py
@@ -92,6 +92,7 @@ class BFGShellCommand(Command):
'root object.')
banner = "Python %s on %s\n%s" % (sys.version, sys.platform, cprt)
config_file, section_name = self.args
+ self.logging_file_config(config_file)
app = get_app(config_file, section_name, loadapp=self.loadapp[0])
root, closer = get_root(app)
if self.IPShell is not None and not self.options.disable_ipython:
diff --git a/repoze/bfg/traversal.py b/repoze/bfg/traversal.py
index ab6eea038..496b874a2 100644
--- a/repoze/bfg/traversal.py
+++ b/repoze/bfg/traversal.py
@@ -131,7 +131,7 @@ def model_path(model, *elements):
attempt to append it to a string and it will cause a
:exc:`TypeError`.
- .. note:: The the :term:`root` model *must* have a ``__name__``
+ .. note:: The :term:`root` model *must* have a ``__name__``
attribute with a value of either ``None`` or the empty
string for paths to be generated properly. If the root
model has a non-null ``__name__`` attribute, its name
@@ -288,7 +288,7 @@ def model_path_tuple(model, *elements):
``model`` object based on its position in an object graph, e.g
``('', 'foo', 'bar')``. Any positional arguments passed in as
``elements`` will be appended as elements in the tuple
- representing the the model path. For instance, if the model's
+ representing the model path. For instance, if the model's
path is ``('', 'foo', 'bar')`` and elements equals ``('a', 'b')``,
the returned tuple will be ``('', 'foo', 'bar', 'a', b')``. The
first element of this tuple will always be the empty string (a
@@ -312,7 +312,7 @@ def model_path_tuple(model, *elements):
dictionary will be placed in the path tuple; no warning
or error will be given.
- .. note:: The the :term:`root` model *must* have a ``__name__``
+ .. note:: The :term:`root` model *must* have a ``__name__``
attribute with a value of either ``None`` or the empty
string for path tuples to be generated properly. If
the root model has a non-null ``__name__`` attribute,
diff --git a/repoze/bfg/url.py b/repoze/bfg/url.py
index 1d4760842..b8340be6f 100644
--- a/repoze/bfg/url.py
+++ b/repoze/bfg/url.py
@@ -58,7 +58,7 @@ def route_url(route_name, request, *elements, **kw):
structure will be turned into a query string per the documentation
of :func:`repoze.bfg.encode.urlencode` function. After the query
data is turned into a query string, a leading ``?`` is prepended,
- and the the resulting string is appended to the generated URL.
+ and the resulting string is appended to the generated URL.
.. note:: Python data structures that are passed as ``_query``
which are sequences or dictionaries are turned into a
@@ -162,7 +162,7 @@ def model_url(model, request, *elements, **kw):
structure will be turned into a query string per the documentation
of ``repoze.url.urlencode`` function. After the query data is
turned into a query string, a leading ``?`` is prepended, and the
- the resulting string is appended to the generated URL.
+ resulting string is appended to the generated URL.
.. note:: Python data structures that are passed as ``query``
which are sequences or dictionaries are turned into a
diff --git a/repoze/bfg/view.py b/repoze/bfg/view.py
index af3acb8b6..bb8972329 100644
--- a/repoze/bfg/view.py
+++ b/repoze/bfg/view.py
@@ -51,7 +51,7 @@ _marker = object()
def render_view_to_response(context, request, name='', secure=True):
""" Call the :term:`view callable` configured with a :term:`view
- configuration` that matches the the :term:`view name` ``name``
+ configuration` that matches the :term:`view name` ``name``
registered against the specified ``context`` and ``request`` and
return a :term:`response` object. This function will return
``None`` if a corresponding :term:`view callable` cannot be found
@@ -88,7 +88,7 @@ def render_view_to_response(context, request, name='', secure=True):
def render_view_to_iterable(context, request, name='', secure=True):
""" Call the :term:`view callable` configured with a :term:`view
- configuration` that matches the the :term:`view name` ``name``
+ configuration` that matches the :term:`view name` ``name``
registered against the specified ``context`` and ``request`` and
return an iterable object which represents the body of a response.
This function will return ``None`` if a corresponding :term:`view
@@ -119,9 +119,9 @@ def render_view_to_iterable(context, request, name='', secure=True):
def render_view(context, request, name='', secure=True):
""" Call the :term:`view callable` configured with a :term:`view
- configuration` that matches the the :term:`view name` ``name``
+ configuration` that matches the :term:`view name` ``name``
registered against the specified ``context`` and ``request`` and
- and unwind the the view response's ``app_iter`` (see
+ and unwind the view response's ``app_iter`` (see
:ref:`the_response`) into a single string. This function will
return ``None`` if a corresponding :term:`view callable` cannot be
found (when no :term:`view configuration` matches the combination
diff --git a/setup.py b/setup.py
index 1a408d93a..92ac1a3b4 100644
--- a/setup.py
+++ b/setup.py
@@ -12,7 +12,7 @@
#
##############################################################################
-__version__ = '1.2a11'
+__version__ = '1.2b1'
import os
import sys