diff options
| author | Chris McDonough <chrism@plope.com> | 2011-01-18 12:34:08 -0500 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2011-01-18 12:34:08 -0500 |
| commit | bee62477293fc2c06c9fde4b28cbf35fbfcbaadb (patch) | |
| tree | d32de80b39d7799fb627e7b51d5403bdb1f27252 /docs/designdefense.rst | |
| parent | 8b4146009da0b612e8e001e68cd5f6f63d361c53 (diff) | |
| download | pyramid-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.rst | 113 |
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. |
