summaryrefslogtreecommitdiff
path: root/docs/designdefense.rst
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-01-18 12:34:08 -0500
committerChris McDonough <chrism@plope.com>2011-01-18 12:34:08 -0500
commitbee62477293fc2c06c9fde4b28cbf35fbfcbaadb (patch)
treed32de80b39d7799fb627e7b51d5403bdb1f27252 /docs/designdefense.rst
parent8b4146009da0b612e8e001e68cd5f6f63d361c53 (diff)
downloadpyramid-bee62477293fc2c06c9fde4b28cbf35fbfcbaadb.tar.gz
pyramid-bee62477293fc2c06c9fde4b28cbf35fbfcbaadb.tar.bz2
pyramid-bee62477293fc2c06c9fde4b28cbf35fbfcbaadb.zip
modernize design defense after zcml externalization
Diffstat (limited to 'docs/designdefense.rst')
-rw-r--r--docs/designdefense.rst113
1 files changed, 36 insertions, 77 deletions
diff --git a/docs/designdefense.rst b/docs/designdefense.rst
index 1b77e61c9..a7cc31d81 100644
--- a/docs/designdefense.rst
+++ b/docs/designdefense.rst
@@ -21,19 +21,20 @@ an acronym for "there is more than one way to do it").
it includes more than one way to resolve a URL to a :term:`view callable`:
via :term:`url dispatch` or :term:`traversal`. Multiple methods of
configuration exist: :term:`imperative configuration`, :term:`configuration
-decoration`, and :term:`ZCML`. It works with multiple different kinds of
-persistence and templating systems. And so on. However, the existence of
-most of these overlapping ways to do things are not without reason and
-purpose: we have a number of audiences to serve, and we believe that TIMTOWTI
-at the web framework level actually *prevents* a much more insidious and
-harmful set of duplication at higher levels in the Python web community.
+decoration`, and :term:`ZCML` (optionally via :term:`pyramid_zcml`). It works
+with multiple different kinds of persistence and templating systems. And so
+on. However, the existence of most of these overlapping ways to do things
+are not without reason and purpose: we have a number of audiences to serve,
+and we believe that TIMTOWTI at the web framework level actually *prevents* a
+much more insidious and harmful set of duplication at higher levels in the
+Python web community.
:app:`Pyramid` began its life as :mod:`repoze.bfg`, written by a team of
people with many years of prior :ref:`Zope` experience. The idea of
-:term:`traversal`, the usage of :term:`ZCML` and the way :term:`view lookup`
-works was stolen entirely from Zope. The authorization subsystem provided by
-:app:`Pyramid` is a derivative of Zope's. The idea that an application can
-be *extended* without forking is also a Zope derivative.
+:term:`traversal` and the way :term:`view lookup` works was stolen entirely
+from Zope. The authorization subsystem provided by :app:`Pyramid` is a
+derivative of Zope's. The idea that an application can be *extended* without
+forking is also a Zope derivative.
Implementations of these features were *required* to allow the :app:`Pyramid`
authors to build the bread-and-butter CMS-type systems for customers in the
@@ -164,12 +165,11 @@ variable. Using an API that consults a thread local makes understanding how
it works non-local.
You've now bought in to the fact that there's a registry that is just
-"hanging around". But how does the registry get populated? Why,
-:term:`ZCML` of course. Sometimes. Or via imperative code. In this
-particular case, however, the registration of ``ISettings`` is made by the
-framework itself "under the hood": it's not present in any ZCML nor was it
-performed imperatively. This is extremely hard to comprehend. Problem
-number six.
+"hanging around". But how does the registry get populated? Why, via code
+that calls directives like ``config.add_view``. In this particular case,
+however, the registration of ``ISettings`` is made by the framework itself
+"under the hood": it's not present in any user configuration. This is
+extremely hard to comprehend. Problem number six.
Clearly there's some amount of cognitive load here that needs to be borne by
a reader of code that extends the :app:`Pyramid` framework due to its use of
@@ -323,17 +323,18 @@ the ZCA registry:
- Composability. A ZCA component registry can be populated imperatively, or
there's an existing mechanism to populate a registry via the use of a
- configuration file (ZCML). We didn't need to write a frontend from scratch
- to make use of configuration-file-driven registry population.
+ configuration file (ZCML, via :term:`pyramid_zcml`). We didn't need to
+ write a frontend from scratch to make use of configuration-file-driven
+ registry population.
- Pluggability. Use of the ZCA registry allows for framework extensibility
via a well-defined and widely understood plugin architecture. As long as
framework developers and extenders understand the ZCA registry, it's
possible to extend :app:`Pyramid` almost arbitrarily. For example, it's
- relatively easy to build a ZCML directive that registers several views "all
- at once", allowing app developers to use that ZCML directive as a "macro"
- in code that they write. This is somewhat of a differentiating feature
- from other (non-Zope) frameworks.
+ relatively easy to build a directive that registers several views "all at
+ once", allowing app developers to use that directive as a "macro" in code
+ that they write. This is somewhat of a differentiating feature from other
+ (non-Zope) frameworks.
- Testability. Judicious use of the ZCA registry in framework code makes
testing that code slightly easier. Instead of using monkeypatching or
@@ -346,9 +347,8 @@ the ZCA registry:
for just these purposes. The ZCA registry contains optional C code for
this purpose which demonstrably has no (or very few) bugs.
-- Ecosystem. Many existing Zope packages can be used in
- :app:`Pyramid` with few (or no) changes due to our use of the ZCA
- registry and :term:`ZCML`.
+- Ecosystem. Many existing Zope packages can be used in :app:`Pyramid` with
+ few (or no) changes due to our use of the ZCA registry.
Conclusion
++++++++++
@@ -366,13 +366,12 @@ this is you, it's extremely hard to have a lot of sympathy for you. You'll
either need to get familiar with how we're using the ZCA registry or you'll
need to use only the documented APIs; that's why we document them as APIs.
-If you *extend* or *develop* :app:`Pyramid` (create new ZCML directives, use
-some of the more obscure "ZCML hooks" as described in :ref:`hooks_chapter`,
-or work on the :app:`Pyramid` core code), you will be faced with needing to
-understand at least some ZCA concepts. In some places it's used unabashedly,
-and will be forever. We know it's quirky, but it's also useful and
-fundamentally understandable if you take the time to do some reading about
-it.
+If you *extend* or *develop* :app:`Pyramid` (create new directives, use some
+of the more obscure "hooks" as described in :ref:`hooks_chapter`, or work on
+the :app:`Pyramid` core code), you will be faced with needing to understand
+at least some ZCA concepts. In some places it's used unabashedly, and will
+be forever. We know it's quirky, but it's also useful and fundamentally
+understandable if you take the time to do some reading about it.
Pyramid Uses Interfaces Too Liberally
-------------------------------------
@@ -459,46 +458,6 @@ completely optional. No ZCML is required at all to use :app:`Pyramid`, nor
any other sort of frameworky declarative frontend to application
configuration.
-Pyramid Uses ZCML; ZCML is XML and I Don't Like XML
----------------------------------------------------
-
-:term:`ZCML` is a configuration language in the XML syntax. Due to the
-"imperative configuration" feature (new in :mod:`repoze.bfg` 1.2), you don't
-need to use ZCML at all. But if you really do want to perform declarative
-configuration, perhaps because you want to build an extensible application,
-you may need to use and understand it.
-
-:term:`ZCML` contains elements that are mostly singleton tags that are
-called *declarations*. For an example:
-
-.. code-block:: xml
- :linenos:
-
- <route
- view=".views.my_view"
- path="/"
- name="root"
- />
-
-This declaration associates a :term:`view` with a route pattern.
-
-All :app:`Pyramid` declarations are singleton tags, unlike many other XML
-configuration systems. No XML *values* in ZCML are meaningful; it's always
-just XML tags and attributes. So in the very common case it's not really
-very much different than an otherwise "flat" configuration format like
-``.ini``, except a developer can *create* a directive that requires nesting
-(none of these exist in :app:`Pyramid` itself), and multiple "sections" can
-exist with the same "name" (e.g. two ``<route>`` declarations) must be able
-to exist simultaneously.
-
-You might think some other configuration file format would be better. But
-all configuration formats suck in one way or another. I personally don't
-think any of our lives would be markedly better if the declarative
-configuration format used by :app:`Pyramid` were YAML, JSON, or INI. It's
-all just plumbing that you mostly cut and paste once you've progressed 30
-minutes into your first project. Folks who tend to agitate for another
-configuration file format are folks that haven't yet spent that 30 minutes.
-
.. _model_traversal_confusion:
Pyramid Uses "Model" To Represent A Node In The Graph of Objects Traversed
@@ -983,11 +942,11 @@ the :term:`Zope Component Architecture`, you can optionally use it to expose
other more domain-specific configuration plugpoints while developing an
application. The plugpoints you expose needn't be as coarse as the ones
provided automatically by :app:`Pyramid` itself. For example, you might
-compose your own :term:`ZCML` directive that configures a set of views for a
-prebaked purpose (e.g. ``restview`` or somesuch) , allowing other people to
-refer to that directive when they make declarations in the ``configure.zcml``
-of their customization package. There is a cost for this: the developer of
-an application that defines custom plugpoints for its deployers will need to
+compose your own directive that configures a set of views for a prebaked
+purpose (e.g. ``restview`` or somesuch) , allowing other people to refer to
+that directive when they make declarations in the ``includeme`` of their
+customization package. There is a cost for this: the developer of an
+application that defines custom plugpoints for its deployers will need to
understand the ZCA or he will need to develop his own similar extensibility
system.