diff options
| -rw-r--r-- | CHANGES.txt | 9 | ||||
| -rw-r--r-- | docs/glossary.rst | 3 | ||||
| -rw-r--r-- | docs/index.rst | 1 | ||||
| -rw-r--r-- | docs/narr/hooks.rst | 77 | ||||
| -rw-r--r-- | docs/narr/project.rst | 2 | ||||
| -rw-r--r-- | docs/narr/resources.rst | 216 |
6 files changed, 230 insertions, 78 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index d601f3199..9a343aa50 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -8,7 +8,14 @@ Features environment variable (``BFG_CONFIGURE_ZCML``) to name a ZCML file that will be used to bootstrap the application. Previously, the integrator could not influence which ZCML file was used to do the - boostrapping (only the original application developer). + boostrapping (only the original application developer could do so). + +Documentation +------------- + +- Added a "Resources" chapter to the narrative documentation which + explains how to override resources within one package from another + package. 1.0a9 (2009-07-01) ================== diff --git a/docs/glossary.rst b/docs/glossary.rst index 3abe31ea6..46b94d62d 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -24,6 +24,9 @@ Glossary non-Python-source that lives in a Python package can be considered a resource file. See also `PkgResources <http://peak.telecommunity.com/DevCenter/PkgResources>`_ + Resource + Any file contained within a Python :term:`package` which is *not* + a Python source code file. Package A directory on disk which contains an ``__init__.py`` file, making it recognizable to Python as a location which can be ``import`` -ed. diff --git a/docs/index.rst b/docs/index.rst index 41d3409b3..928ded272 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -35,6 +35,7 @@ Narrative documentation in chapter form explaining how to use narr/templates narr/models narr/security + narr/resources narr/hybrid narr/vhosting narr/events diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 9eba8a92c..086dc16ad 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -118,81 +118,4 @@ an object that implements any particular interface; it simply needs have a ``status`` attribute, a ``headerlist`` attribute, and and ``app_iter`` attribute. -.. _overriding_resources_section: - -Overriding Resources --------------------- - -A ZCML directive exists named "resource". This ZCML directive allows -you to override Chameleon templates within a package (both directories -full of templates and individual template files) with other templates -in the same package or within another package. This allows you to -"fake out" a view's use of a template, causing it to retrieve a -different template than the one actually named by a relative path to a -call like ``render_template_to_response('templates/mytemplate.pt')``. -For example, you can override a template file by doing:: - - <resource - to_override="some.package:templates/mytemplate.pt" - override_with="another.package:othertemplates/anothertemplate.pt" - /> - -The string passed to "to_override" and "override_with" is named a -"specification". The colon separator in a specification separates the -package name from a package-relative directory name. The colon and -the following relative path are optional. If they are not specified, -the override attempts to resolve every lookup into a package from the -directory of another package. For example:: - - <resource - to_override="some.package" - override_with="another.package" - /> - - -Individual subdirectories within a package can also be overridden:: - - <resource - to_override="some.package:templates/" - override_with="another.package:othertemplates/" - /> - -If you wish to override a directory with another directory, you must -make sure to attach the slash to the end of both the ``to_override`` -specification and the ``override_with`` specification. If you fail to -attach a slash to the end of a specification that points a directory, -you will get unexpected results. You cannot override a directory -specification with a file specification, and vice versa (a startup -error will occur if you try). - -You cannot override a resource with itself (a startup error will -occur if you try). - -Only individual *package* resources may be overridden. Overrides will -not traverse through subpackages within an overridden package. This -means that if you want to override resources for both -``some.package:templates``, and ``some.package.views:templates``, you -will need to register two overrides. - -The package name in a specification may start with a dot, meaning that -the package is relative to the package in which the ZCML file resides. -For example:: - - <resource - to_override=".subpackage:templates/" - override_with="another.package:templates/" - /> - -Overrides for the same ``to_overrides`` specification can be named -multiple times within ZCML. Each ``override_with`` path will be -consulted in the order defined within ZCML, forming an override search -path. - -Resource overrides can actually override resources other than -templates. Any software which uses the ``pkg_resources`` -``get_resource_filename``, ``get_resource_stream`` or -``get_resource_string`` APIs will obtain an overridden file when an -override is used. However, the only built-in facility which uses the -``pkg_resources`` API within BFG is the templating stuff, so we only -call out template overrides here. diff --git a/docs/narr/project.rst b/docs/narr/project.rst index b465082eb..a8b0ccdd4 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -7,6 +7,8 @@ You can use :mod:`repoze.bfg` 's sample application generator to get started. This generator uses :term:`Paste` templates to allow creation of a new project by answering a series of questions. +.. _creating_a_project: + Creating the Project -------------------- diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst new file mode 100644 index 000000000..fb6e82de0 --- /dev/null +++ b/docs/narr/resources.rst @@ -0,0 +1,216 @@ +.. _resources_chapter: + +Resources +========= + +A :term:`resource` is any file contained within a Python +:term:`package` which is *not* a Python source code file. For +example, each of the following is a resource: + +- a :term:`Chameleon` template file contained within a Python package. + +- a GIF image file contained within a Python package. + +- a CSS file contined within a Python package. + +- a Javascript source file contained within a Python package. + +- A directory within a package that does not have an ``__init__.py`` + in it (if it possessed an ``__init__.py`` it would *be* a package). + +The use of resources is quite common in most web development projects. +For example, when you create a :mod:`repoze.bfg` application using one +of the available "paster" templates, as described in +:ref:`creating_a_project`, the directory representing the application +contains a Python :term:`package`. Within that Python package, there +are directories full of files which are resources. For example, there +is a ``templates`` directory which contains ``.pt`` files, and a +``static`` directory which contains ``.css``, ``.js``, and ``.gif`` +files. + +.. _understanding_resources: + +Understanding Resources +----------------------- + +Let's imagine you've created a :mod:`repoze.bfg` application that uses +a :term:`Chameleon` template via the ``render_template_to_response`` +API. For example, the application might address the resource named +``templates/some_template.pt`` using that API within a ``views.py`` +file inside a ``myapp`` package: + +.. code-block:: python + :linenos: + + render_template_to_response('templates/some_template.pt') + +"Under the hood", when this API is called, :mod:`repoze.bfg` attempts +to make sense out of the string ``templates/some_template.pt`` +provided by the developer. To do so, it first finds the "current" +package. The "current" package is the Python package in which the +``views.py`` module which contains this code lives. This would be the +``myapp`` package, according to our example so far. By resolving the +current package, :mod:`repoze.bfg` has enough information to locate +the actual template file. These are the elements it needs: + +- The *package name* (``myapp``) + +- The *resource name* (``templates/some_template.pt``) + +:mod:`repoze.bfg` uses the :term:`pkg_resources` API to resolve the +package name and resource name to an absolute +(operating-system-specific) file name. It eventually passes this +resolved absolute filesystem path to the Chameleon templating engine, +which then uses it to load, parse, and execute the template file. + +Package names often contain dots. For example, ``repoze.bfg`` is a +package. Resource names usually look a lot like relative UNIX file +paths. + +.. _overriding_resources_section: + +Overriding Resources +-------------------- + +It can often be useful to override specific resources "from outside" a +given :mod:`repoze.bfg` application. For example, you may wish to +reuse an existing :mod:`repoze.bfg` application more or less +unchanged. However, some specific template file owned by the +application might have inappropriate HTML, or some static resource +(such as a logo file or some CSS file) might not appropriate. You +*could* just fork the application entirely, but it's often more +convenient to just override the resources that are inappropriate and +reuse the application "as is". This is particularly true when you +reuse some "core" application over and over again for some set of +customers (such as a CMS application, or some bug tracking +application), and you want to make arbitrary visual modifications to a +particular application deployment without forking the underlying code. + +To this end, :mod:`repoze.bfg` contains a feature that makes it +possible to "override" one resource with one or more other resources. +In support of this feature, a :term:`ZCML` directive exists named +``resource``. The ``resource`` directive allows you to *override* the +following kinds of resources defined in any Python package: + +- Individual :term:`Chameleon` templates. + +- A directory containing multuple Chameleon templates. + +- Individual static files served up by an instance of the + ``repoze.bfg.view.static`` helper class. + +- A directory of static files served up by an instance of the + ``repoze.bfg.view.static`` helper class. + +- Any other resource (or set of resources) addressed by code that uses + the setuptools :term:`pkg_resources` API. + +Usually, overriding a resource in an existing application means +performing the following steps: + +- Create a new Python package. The easiest way to do this is to + create a new :mod:`repoze.bfg` application using the "paster" + template mechanism. See :ref:`creating_a_project` for more + information. + +- Install the new package into the same Python environment as the + original application (e.g. ``python setup.py develop`` or ``python + setup.py install``). + +- Change the ``configure.zcml`` in the new package to include one or + more ``resource`` ZCML directives (see :ref:`resource_directive` + below). The new package's ``configure.zcml`` should then include + the original :mod:`repoze.bfg` application's ``configure.zcml`` via + an include statement, e.g. ``<include + package="theoriginalpackage"/>``. + +- Add override resources to the package as necessary. + +- Change the Paste ``.ini`` file that starts up the original + application. Add a ``configure_zcml`` statement within the + application's section in the file which points at your *new* + package's ``configure.zcml`` file. See :ref:`environment_chapter` + for more information about this setting. + +.. _resource_directive: + +The ``resource`` ZCML Directive +------------------------------- + +An individual :mod:`repoze.bfg` ``resource`` ZCML statement can +override a single resource. For example: + +.. code-block:: xml + :linenos: + + <resource + to_override="some.package:templates/mytemplate.pt" + override_with="another.package:othertemplates/anothertemplate.pt" + /> + +The string value passed to both ``to_override`` and ``override_with`` +attached to a resource directive is called a "specification". The +colon separator in a specification separates the *package name* from +the *resource name*. The colon and the following resource name are +optional. If they are not specified, the override attempts to resolve +every lookup into a package from the directory of another package. +For example: + +.. code-block:: xml + :linenos: + + <resource + to_override="some.package" + override_with="another.package" + /> + +Individual subdirectories within a package can also be overridden: + +.. code-block:: xml + :linenos: + + <resource + to_override="some.package:templates/" + override_with="another.package:othertemplates/" + /> + +If you wish to override a directory with another directory, you *must* +make sure to attach the slash to the end of both the ``to_override`` +specification and the ``override_with`` specification. If you fail to +attach a slash to the end of a specification that points a directory, +you will get unexpected results. + +You cannot override a directory specification with a file +specification, and vice versa (a startup error will occur if you try). +You cannot override a resource with itself (a startup error will occur +if you try). + +Only individual *package* resources may be overridden. Overrides will +not traverse through subpackages within an overridden package. This +means that if you want to override resources for both +``some.package:templates``, and ``some.package.views:templates``, you +will need to register two overrides. + +The package name in a specification may start with a dot, meaning that +the package is relative to the package in which the ZCML file resides. +For example: + +.. code-block:: xml + :linenos: + + <resource + to_override=".subpackage:templates/" + override_with="another.package:templates/" + /> + +Multiple ``resource`` statements which name a shared ``to_override`` +but a different ``override_with`` specification can be "stacked" to +form a search path. The first resource that exists in the search path +will be used; if no resource exists in the override path, the original +resource is used. + +Resource overrides can actually override resources other than +templates and static files. Any software which uses the +``pkg_resources`` ``get_resource_filename``, ``get_resource_stream`` +or ``get_resource_string`` APIs will obtain an overridden file when an +override is used. |
