summaryrefslogtreecommitdiff
path: root/docs/narr/configuration.rst
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2010-11-03 23:11:07 -0400
committerChris McDonough <chrism@plope.com>2010-11-03 23:11:07 -0400
commitc7c40b9b3b3c0008185f1a44a2aba4f95f29abd0 (patch)
tree839bf0a16a3add905e58dc037703ce400f1fa43e /docs/narr/configuration.rst
parent108698b020c4b360c180ab3faa6f11e45a51439c (diff)
downloadpyramid-c7c40b9b3b3c0008185f1a44a2aba4f95f29abd0.tar.gz
pyramid-c7c40b9b3b3c0008185f1a44a2aba4f95f29abd0.tar.bz2
pyramid-c7c40b9b3b3c0008185f1a44a2aba4f95f29abd0.zip
de-zcml-ify various chapters and move ZCML to the declarative chapter
Diffstat (limited to 'docs/narr/configuration.rst')
-rw-r--r--docs/narr/configuration.rst317
1 files changed, 43 insertions, 274 deletions
diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst
index cbc49d94b..82d0c8dda 100644
--- a/docs/narr/configuration.rst
+++ b/docs/narr/configuration.rst
@@ -6,30 +6,30 @@
Application Configuration
=========================
-Each deployment of an application written using :mod:`pyramid`
-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 manages corporate data might plug in code that
-manages accounting information. :mod:`pyramid` 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
-parsed at application startup time as "configuration".
-:mod:`pyramid` 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
-code into the :mod:`pyramid` framework, you are "configuring"
-:mod:`pyramid` for the purpose of creating a particular application
-deployment.
-
-There are two different mechanisms you may use to configure
-:mod:`pyramid` to create an application: *imperative* configuration
-and *declarative* configuration. We'll examine both modes in the
-sections which follow.
+Each deployment of an application written using :mod:`pyramid` 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 manages corporate
+data might plug in code that manages accounting information. :mod:`pyramid`
+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 parsed at
+application startup time as "configuration". :mod:`pyramid` 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 code into the :mod:`pyramid` framework, you are
+"configuring" :mod:`pyramid` for the purpose of creating a particular
+application deployment.
+
+There are two different mechanisms you may use to configure :mod:`pyramid` to
+create an application: *imperative* configuration and *declarative*
+configuration. We'll be using primarily the *imperative* configuration
+method in this book, for the sake of brevity and simplicity. For information
+about how to define application configuration declaratively, see
+:ref:`declarative_chapter`.
.. index::
single: imperative configuration
@@ -39,13 +39,6 @@ sections which follow.
Imperative Configuration
------------------------
-Experienced Python programmers might find that performing
-configuration "imperatively" fits their brain best. This is the
-configuration mode in which a developer cedes the least amount of
-control to the framework; it's "imperative" because you express the
-configuration directly in Python code, and you have the full power of
-Python at your disposal as you issue configuration statements.
-
Here's one of the simplest :mod:`pyramid` applications, configured
imperatively:
@@ -77,201 +70,22 @@ power of Python, including conditionals, can be employed in this mode
of configuration.
.. index::
- single: declarative configuration
-
-.. _declarative_configuration:
-
-Declarative Configuration
--------------------------
-
-A :mod:`pyramid` 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
-dialect.
-
-A :mod:`pyramid` application configured declaratively requires not
-one, but two files: a Python file and a :term:`ZCML` file.
-
-In a file named ``helloworld.py``:
-
-.. code-block:: python
- :linenos:
-
- from paste.httpserver import serve
- from pyramid.response import Response
- from pyramid.configuration import Configurator
-
- def hello_world(request):
- return Response('Hello world!')
-
- if __name__ == '__main__':
- config = Configurator()
- config.begin()
- config.load_zcml('configure.zcml')
- config.end()
- app = config.make_wsgi_app()
- serve(app, host='0.0.0.0')
-
-In a file named ``configure.zcml`` in the same directory as the
-previously created ``helloworld.py``:
-
-.. code-block:: xml
- :linenos:
-
- <configure xmlns="http://pylonshq.com/pyramid">
-
- <include package="pyramid.includes" />
-
- <view
- view="helloworld.hello_world"
- />
-
- </configure>
-
-This pair of files forms an application functionally equivalent to the
-application we created earlier in :ref:`imperative_configuration`.
-Let's examine the differences between that code listing and the code
-above.
-
-In :ref:`imperative_configuration`, we had the following lines within
-the ``if __name__ == '__main__'`` section of ``helloworld.py``:
-
-.. code-block:: python
- :linenos:
-
- if __name__ == '__main__':
- config = Configurator()
- config.begin()
- config.add_view(hello_world)
- config.end()
- app = config.make_wsgi_app()
- serve(app, host='0.0.0.0')
-
-In our "declarative" code, we've removed the call to ``add_view`` and
-replaced it with a call to the
-:meth:`pyramid.configuration.Configurator.load_zcml` method so that
-it now reads as:
-
-.. code-block:: python
- :linenos:
-
- if __name__ == '__main__':
- config = Configurator()
- config.begin()
- config.load_zcml('configure.zcml')
- config.end()
- app = config.make_wsgi_app()
- serve(app, host='0.0.0.0')
-
-Everything else is much the same.
-
-The ``config.load_zcml('configure.zcml')`` line tells the configurator
-to load configuration declarations from the file named
-``configure.zcml`` which sits next to ``helloworld.py`` on the
-filesystem. Let's take a look at that ``configure.zcml`` file again:
-
-.. code-block:: xml
- :linenos:
-
- <configure xmlns="http://pylonshq.com/pyramid">
-
- <include package="pyramid.includes" />
-
- <view
- view="helloworld.hello_world"
- />
-
- </configure>
-
-Note that this file contains some XML, and that the XML contains a
-``<view>`` :term:`configuration declaration` tag that references a
-:term:`dotted Python name`. This dotted name refers to the
-``hello_world`` function that lives in our ``helloworld`` Python
-module.
-
-This ``<view>`` declaration tag performs the same function as the
-``add_view`` method that was employed within
-:ref:`imperative_configuration`. In fact, the ``<view>`` tag is
-effectively a "macro" which calls the
-:meth:`pyramid.configuration.Configurator.add_view` method on your
-behalf.
-
-The ``<view>`` tag is an example of a :mod:`pyramid` declaration
-tag. Other such tags include ``<route>`` and ``<scan>``. Each of
-these tags is effectively a "macro" which calls methods of a
-:class:`pyramid.configuration.Configurator` object on your behalf.
-
-Essentially, using a :term:`ZCML` file and loading it from the
-filesystem allows us to put our configuration statements within this
-XML file rather as declarations, rather than representing them as
-method calls to a :term:`Configurator` object. Otherwise, declarative
-and imperative configuration are functionally equivalent.
-
-Using declarative configuration has a number of benefits, the primary
-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`.
-
-.. index::
- single: ZCML conflict detection
-
-ZCML Conflict Detection
-~~~~~~~~~~~~~~~~~~~~~~~
-
-A minor additional feature of ZCML is *conflict detection*. If you
-define two declaration tags within the same ZCML file which logically
-"collide", an exception will be raised, and the application will not
-start. For example, the following ZCML file has two conflicting
-``<view>`` tags:
-
-.. code-block:: xml
- :linenos:
-
- <configure xmlns="http://pylonshq.com/pyramid">
-
- <include package="pyramid.includes" />
-
- <view
- view="helloworld.hello_world"
- />
-
- <view
- view="helloworld.hello_world"
- />
-
- </configure>
-
-If you try to use this ZCML file as the source of ZCML for an
-application, an error will be raised when you attempt to start the
-application. This error will contain information about which tags
-might have conflicted.
-
-.. index::
single: view_config
- single: ZCML view directive
single: configuration decoration
single: code scanning
.. _decorations_and_code_scanning:
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 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:`pyramid` allows you to insert
-:term:`configuration decoration` statements very close to code that is
+-------------------------------------------
+
+An alternate mode of configuration lends more *locality of reference* to a
+:term:`configuration declaration`. It's sometimes painful to have all
+configuration done in imperative 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:`pyramid` 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
@@ -322,46 +136,6 @@ and its subpackages. For example:
app = config.make_wsgi_app()
serve(app, host='0.0.0.0')
-:term:`ZCML` can also invoke a :term:`scan` via its ``<scan>``
-directive. If a ZCML file is processed that contains a scan
-directive, the package the ZCML file points to is scanned.
-
-.. topic:: Declaratively Starting a Scan
-
- .. code-block:: python
- :linenos:
-
- # helloworld.py
-
- from paste.httpserver import serve
- from pyramid.response import Response
- from pyramid.view import view_config
-
- @view_config()
- def hello(request):
- return Response('Hello')
-
- if __name__ == '__main__':
- from pyramid.configuration import Configurator
- config = Configurator()
- config.begin()
- config.load_zcml('configure.zcml')
- config.end()
- app = config.make_wsgi_app()
- serve(app, host='0.0.0.0')
-
- .. code-block:: xml
- :linenos:
-
- <configure xmlns="http://namespaces.repoze.org">
-
- <!-- configure.zcml -->
-
- <include package="pyramid.includes"/>
- <scan package="."/>
-
- </configure>
-
The scanning machinery imports each module and subpackage in a package
or module recursively, looking for special attributes attached to
objects defined within a module. These special attributes are
@@ -384,20 +158,15 @@ method, effectively:
config.add_view(hello)
-Which Mode Should I Use?
-------------------------
-
-A combination of imperative configuration, declarative configuration
-via ZCML and scanning can be used to configure any application. They
-are not mutually exclusive.
+Declarative Configuration
+-------------------------
-The :mod:`pyramid` authors often recommend using mostly declarative
-configuration, because it's the more traditional form of configuration
-used in :mod:`pyramid` applications, it can be overridden and
-extended by third party deployers, and there are more examples for it
-"in the wild".
+A third mode of configuration can be employed when you create a
+:mod:`pyramid` application named *declarative configuration*. This mode uses
+:term:`ZCML` to represent configuration statements rather than Python. ZCML
+is often used when application extensibility is important. Most of the
+examples in the narrative portion of this documentation concentrate on
+imperative configuration rather than ZCML, but almost everything that can be
+configured imperatively can also be configured via ZCML. See
+:ref:`declarative_chapter` for more information about ZCML.
-However, imperative mode configuration can be simpler to understand,
-and the framework is not "opinionated" about the choice. This book
-presents examples in both styles, mostly interchangeably. You can
-choose the mode that best fits your brain as necessary.