Skip to content

Commit

Permalink
Merge cae1366 into cd96619
Browse files Browse the repository at this point in the history
  • Loading branch information
jamadden committed Sep 25, 2018
2 parents cd96619 + cae1366 commit c402df5
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 47 deletions.
8 changes: 0 additions & 8 deletions docs/api/zopeconfigure.rst
Expand Up @@ -2,11 +2,3 @@
=======================================

.. automodule:: zope.configuration.zopeconfigure

.. autointerface:: IZopeConfigure
:members:
:member-order: bysource

.. autoclass:: ZopeConfigure
:members:
:member-order: bysource
99 changes: 85 additions & 14 deletions docs/narr.rst
@@ -1,6 +1,6 @@
==========================
Zope configuration system
==========================
===========================
Zope configuration system
===========================

The zope configuration system provides an extensible system for
supporting variouse kinds of configurations.
Expand Down Expand Up @@ -41,16 +41,16 @@ the directive. There are four kinds of directives:
are typically functions that take a context and zero or more
keyword arguments and return a sequence of configuration actions.

To learn how to create simple directives, see `tests/simple.py`.
To learn how to create simple directives, see ``tests/simple.py``.


- Grouping directives collect information to be used by nested
directives. They are called with a context object which they adapt
to some interface that extends IConfigurationContext.

To learn how to create grouping directives, look at the
documentation in zopeconfigure.py, which provides the implementation
of the zope `configure` directive.
documentation for :mod:`zope.configuration.zopeconfigure`, which
provides the implementation of the zope ``configure`` directive.

Other directives can be nested in grouping directives.

Expand Down Expand Up @@ -78,7 +78,7 @@ the directive. There are four kinds of directives:
Flesh out narrative docs.

Using the configuration machinery programatically
==================================================
=================================================

An extended example:

Expand Down Expand Up @@ -339,7 +339,7 @@ inside a package directive:


Overriding Included Configuration
==================================
=================================

When we have conflicting directives, we can resolve them if one of
the conflicting directives was from a file that included all of
Expand Down Expand Up @@ -571,16 +571,84 @@ There is a ``condition`` attribute in the
"http://namespaces.zope.org/zcml" namespace which is honored on all
elements in ZCML. The value of the attribute is an expression
which is used to determine if that element and its descendents are
used. If the condition is true, processing continues normally,
used. If the condition evaluates to true, processing continues normally;
otherwise that element and its descendents are ignored.

Currently the expression is always of the form "have featurename", and it
checks for the presence of a ``<meta:provides feature="featurename" />``.
The expression is always of the form "*verb* *arguments*". There are
four verbs that are supported:

- have
- not-have
- installed
- not-installed

Note that logical "if/else" conditions can be achieved by using both the
positive verb and its not-prefixed counterpart on sibling elements
with the same arguments. Logical "and" conditions can be achieved by
nesting elements. To group arbitrary directives under a condition,
nest them under a new ``<configure>`` element.

.. seealso:: :meth:`zope.configuration.xmlconfig.ConfigurationHandler.evaluateCondition`

For documentation and examples of the XML implementation of conditions.

Features
--------

The verbs ``have`` and ``not-have`` test for the presence or absense
of features in the configuration context. The argument is a single
feature name. Features can be established in Python code using
:meth:`~zope.configuration.config.ConfigurationContext.provideFeature`,
or they can be set during ZCML processing with the ``meta:provides``
directive (e.g., ``<meta:provides feature="featurename" />``.)

A popular use of features is to enable certain configuration only
during development with a feature called ``devmode``. (This also
demonstrates applying a condition to a single directive.)

.. code-block:: xml
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:zcml="http://namespaces.zope.org/zcml" >
<include package="." file="devconfig.zcml" zcml:condition="have devmode" />
</configure>
Module Availability
-------------------

The verbs ``installed`` and ``not-installed`` test whether a Python
module can be imported successfully or not. They can be used to enable
optional configuration if a package is present, or enable fallback
functionality if it isn't. (This also demonstrates grouping directives
under a new ``<configure>`` element, and establishing a logical "if/else".)

.. code-block:: xml
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:zcml="http://namespaces.zope.org/zcml" >
<configure zcml:condition="installed some.package">
<!-- Use it -->
<include package="some.package" />
</configure>
<configure zcml:condition="not-installed some-package">
<!-- Enable our fallback code -->
<adapter for=".ISomeInterface"
provides=".ISomeFunction"
factory=".MockFunction" />
</configure>
</configure>
Example
-------

Our demonstration uses a trivial registry; each registration consists
of a simple id inserted in the global `registry` in this module. We
of a simple id inserted in the global ``registry`` in this module. We
can checked that a registration was made by checking whether the id is
present in `registry`.
present in ``registry``.

.. doctest::

Expand All @@ -590,6 +658,9 @@ present in `registry`.

We start by loading the example ZCML file, *conditions.zcml*:

.. literalinclude:: ../src/zope/configuration/tests/conditions.zcml
:language: xml

.. doctest::

>>> import zope.configuration.tests
Expand Down Expand Up @@ -944,7 +1015,7 @@ done either to:
with a single set of directive parameters.

Grouping directives are used to handle both of these cases. See the
documentation in :mod:`zope.configure.zopeconfigure`. This file describes the
documentation in :mod:`zope.configuration.zopeconfigure`. This file describes the
implementation of the zope ``configure`` directive, which groups
directives that use a common package or internationalization domain.
You should also have read the section on "Creating simple directives."
Expand Down
52 changes: 27 additions & 25 deletions src/zope/configuration/zopeconfigure.py
Expand Up @@ -33,28 +33,28 @@
The parameter schema is given by IZopeConfigure. It specifies a
package parameter and an i18n_domain parameter. The package parameter
is specified as a ``GlobalObject``. This means it must be given as a
is specified as a `~.GlobalObject`. This means it must be given as a
dotted name that can be resolved through import. The i18n domain is
just a plain (not unicode) string.
The handler class has a constructor that takes a context to be adapted
and zero or more arguments (depending on the paramter schema). The
handler class must implement
``zope.configuration.interfaces.IGroupingContext``, which defines
`zope.configuration.interfaces.IGroupingContext`, which defines
hooks ``before`` and ``after``, that are called with no arguments
before and after nested directives are processed. If a grouping
directive handler creates any actions, or does any computation, this
is normally done in either the ``before`` or ``after`` hooks.
Grouping handlers are normally decorators.
The base class,
``zope.configuration.config.GroupingContextDecorator``, is normally
`zope.configuration.config.GroupingContextDecorator`, is normally
used to define grouping directive handlers. It provides:
- An implementation of IConfigurationContext, which grouping directive
- An implementation of `~.IConfigurationContext`, which grouping directive
handlers should normally implement,
- A default implementation of ``IGroupingContext`` that provides empty
- A default implementation of `~.IGroupingContext` that provides empty
hooks.
- Decorator support that uses a ``__getattr__`` method to delegate
Expand All @@ -63,32 +63,34 @@
- A constructor that sets the ``context`` attribute to the adapted
context and assigns keyword arguments to attributes.
The ``ZopeConfigure`` provides handling for the ``configure``
directive. It subclasses GroupingContextDecorator, and overrides the
The class `ZopeConfigure` provides handling for the ``configure``
directive. It subclasses `~.GroupingContextDecorator`, and overrides the
constructor to set the ``basepath`` attribute if a ``package`` argument
is provided. Note that it delegates the job of assigning paramters to
attribute to the ``GroupingContextDecorator`` constructor.
attribute to the `~.GroupingContextDecorator` constructor.
The last step is to register the directive using the meta
configuration directive. If we wanted to register the Zope
``configure`` directive for the ``zope`` namespace, we'd use a
meta-configuration directive like::
<meta:groupingDirective
namespace="http://namespaces.zope.org/zope"
name="configure"
schema="zope.configuration.zopeconfigure.IZopeConfigure"
handler="zope.configuration.zopeconfigure.ZopeConfigure"
>
Zope configure
The ``configure`` node is normally used as the root node for a
configuration file. It can also be used to specify a package or
internationalization domain for a group of directives within a
file by grouping those directives.
</meta:groupingDirective>
We use the groupingDirective meta-directive to register a grouping
meta-configuration directive like:
.. code-block:: xml
<meta:groupingDirective
namespace="http://namespaces.zope.org/zope"
name="configure"
schema="zope.configuration.zopeconfigure.IZopeConfigure"
handler="zope.configuration.zopeconfigure.ZopeConfigure"
>
Zope configure
The ``configure`` node is normally used as the root node for a
configuration file. It can also be used to specify a package or
internationalization domain for a group of directives within a
file by grouping those directives.
</meta:groupingDirective>
We use the ``groupingDirective`` meta-directive to register a grouping
directive. The parameters are self explanatory. The textual contents
of the directive provide documentation text, excluding parameter
documentation, which is provided by the schema.
Expand Down

0 comments on commit c402df5

Please sign in to comment.