diff options
| author | Chris McDonough <chrism@agendaless.com> | 2010-01-18 18:07:12 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2010-01-18 18:07:12 +0000 |
| commit | c5f24b2957a2a7569d70930ac5bc630cc5aaac55 (patch) | |
| tree | b6c09425e10c2900bf2120dfe4d390e9070f960c /docs | |
| parent | e4ed8fdb6acc8a9b040c8f61221da0e79821e071 (diff) | |
| download | pyramid-c5f24b2957a2a7569d70930ac5bc630cc5aaac55.tar.gz pyramid-c5f24b2957a2a7569d70930ac5bc630cc5aaac55.tar.bz2 pyramid-c5f24b2957a2a7569d70930ac5bc630cc5aaac55.zip | |
Prep for b1
Merge a bunch of paper-based docs fixes
Configure logging during bfgshell.
Diffstat (limited to 'docs')
40 files changed, 648 insertions, 627 deletions
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 |
