--- a/src/source/zca.rst Fri Apr 20 16:52:49 2018 +0200
+++ b/src/source/zca.rst Fri Apr 27 11:51:08 2018 +0200
@@ -1,7 +1,7 @@
.. _zca:
Zope Component Architecture with PyAMS
-======================================
+++++++++++++++++++++++++++++++++++++++
The **Zope Component Architecture** (aka **ZCA**) is used by the Pyramid framework "under the hood" to handle interfaces,
adapters and utilities. You don't **have to** use it in your own applications. But you can.
@@ -9,64 +9,55 @@
The ZCA is mainly adding elements like **interfaces**, **adapters** and **utilities** to the Python language. It
allows you to write a framework or an application by using **components** which can be extended easily.
+Interfaces
+ Interfaces are objects that specify (document) the external behavior
+ of objects that "provide" them. An interface specifies behavior through, a documentation in a doc string,
+ attribute definitions and conditions of attribute values.
+
+Components
+ Components are objects that are associated with interfaces.
+
+Utilities
+ Utilities are just components that provide an interface and that are looked up by an interface and a name
+
+Adapters
+ Adapters are components that are computed from other components to adapt them to some interface.
+ Because they are computed from other objects, they are provided as factories, usually classes.
+
+
You will find several useful resources about ZCA concepts on the internet.
-
.. seealso::
Zope Documentations:
- - `Components and Interfaces <http://zope.readthedocs.io/en/latest/zdgbook/ComponentsAndInterfaces.html>`_
- - `Zope component <http://zopecomponent.readthedocs.io/en/latest/narr.html>`_
- - `Zope interface <https://docs.zope.org/zope.interface/README.html>`_
+ - `Components and Interfaces <http://zope.readthedocs.io/en/latest/zdgbook/ComponentsAndInterfaces.html>`_
+ - `Zope component <http://zopecomponent.readthedocs.io/en/latest/narr.html>`_
+ - `Zope interface <https://docs.zope.org/zope.interface/README.html>`_
+Utilities
+---------
+
Local utilities
----------------
+'''''''''''''''
In ZCA, a **utility** is a **registered** component which provides an **interface**. This interface is the
**contract** which defines features (list of attributes and methods) provided by the component which implements it.
When a Pyramid application starts, a **global registry** is created to register a whole set of utilities and
adapters; this registration can be done via ZCML directives or via native Python code.
-In addition, PyAMS allows you to define **local utilities**, which are stored and registered in the ZODB via a **site
-manager**.
-
-
-Defining site root
-------------------
-
-One of PyAMS pre-requisites is to use the ZODB, at least to store the site root application, it's configuration and a
-set of local utilities. :ref:`site` describes application startup and **local site manager** initialization process.
-
-This site can be used to store **local utilities** whose configuration, which is easily available to site
-administrators through management interface, is stored in the ZODB.
-
-
-Registering global utilities
-----------------------------
-
-**Global utilities** are components providing an interface which are registered in the global registry.
-PyAMS_utils package provides custom annotations to register global utilities without using ZCML. For example, a skin
-is nothing more than a simple utility providing the *ISkin* interface:
-
-.. code-block:: python
-
- from pyams_default_theme.layer import IPyAMSDefaultLayer
- from pyams_skin.interfaces import ISkin
- from pyams_utils.registry import utility_config
-
- @utility_config(name='PyAMS default skin', provides=ISkin)
- class PyAMSDefaultSkin(object):
- """PyAMS default skin"""
-
- label = _("PyAMS default skin")
- layer = IPyAMSDefaultLayer
-
-This annotation registers a utility, named *PyAMS default skin*, providing the *ISkin* interface. It's the developer
-responsibility to provide all attributes and methods required by the provided interface.
+In addition, PyAMS allows you to define **local utilities**, which are stored and registered in the ZODB via a
+**site manager**.
Registering local utilities
----------------------------
+'''''''''''''''''''''''''''
+
+
+.. tip::
+
+ :ref:`site` can be used to store **local utilities** whose configuration, which is easily
+ available to site administrators through management interface, is stored in the ZODB.
+
A local utility is a persistent object, registered in a *local site manager*, and providing a specific interface (if
a component provides several interfaces, it can be registered several times).
@@ -150,8 +141,32 @@
by an event is providing given interface.
+Registering global utilities
+''''''''''''''''''''''''''''
+
+**Global utilities** are components providing an interface which are registered in the global registry.
+PyAMS_utils package provides custom annotations to register global utilities without using ZCML. For example, a skin
+is nothing more than a simple utility providing the *ISkin* interface:
+
+.. code-block:: python
+
+ from pyams_default_theme.layer import IPyAMSDefaultLayer
+ from pyams_skin.interfaces import ISkin
+ from pyams_utils.registry import utility_config
+
+ @utility_config(name='PyAMS default skin', provides=ISkin)
+ class PyAMSDefaultSkin(object):
+ """PyAMS default skin"""
+
+ label = _("PyAMS default skin")
+ layer = IPyAMSDefaultLayer
+
+This annotation registers a utility, named *PyAMS default skin*, providing the *ISkin* interface. It's the developer
+responsibility to provide all attributes and methods required by the provided interface.
+
+
Looking for utilities
----------------------
+'''''''''''''''''''''
ZCA provides the *getUtility* and *queryUtility* functions to look for a utility. But these methods only applies to
global registry.
@@ -173,8 +188,11 @@
functions API, but are looking for utilities in the local registry before looking in the global registry.
+Adapters
+--------
+
Registering adapters
---------------------
+''''''''''''''''''''
An adapter is also a kind of utility. But instead of *just* providing an interface, it adapts an input object,
providing a given interface, to provide another interface. An adapter can also be named, so that you can choose which
@@ -248,8 +266,11 @@
As you can see, adapted objects can be given as functions or as classes.
+Vocabularies
+------------
+
Registering vocabularies
-------------------------
+''''''''''''''''''''''''
A **vocabulary** is a custom factory which can be used as source for several field types, like *choices* or *lists*.
Vocabularies have to be registered in a custom registry, so PyAMS_utils provide another annotation to register them.
@@ -268,3 +289,7 @@
def __init__(self, *args, **kw):
terms = [SimpleTerm(t, t, t) for t in pytz.all_timezones]
super(TimezonesVocabulary, self).__init__(terms)
+
+
+
+