Permalink
Browse files

merge generic_rendering branch

  • Loading branch information...
Chris McDonough
Chris McDonough committed Jul 26, 2010
1 parent 2eb64f7 commit 250c0218d0bd7dab6ea7e16c7051af71394f2a63
View
@@ -42,11 +42,46 @@ Features
- A new method of the ``Configurator`` exists:
``set_request_factory``. If used, this method will set the factory
- used by the :mod:`repoze.bfg` router to create all request objects.
+ used by the ``repoze.bfg`` router to create all request objects.
- The ``Configurator`` constructor takes an additional argument:
``request_factory``. If used, this argument will set the factory
- used by the :mod:`repoze.bfg` router to create all request objects.
+ used by the ``repoze.bfg`` router to create all request objects.
+
+- The ``Configurator`` constructor takes an additional argument:
+ ``request_factory`. If used, this argument will set the factory
+ used by the ``repoze.bfg`` router to create all request objects.
+
+- A new method of the ``Configurator`` exists:
+ ``set_renderer_globals_factory``. If used, this method will set the
+ factory used by the ``repoze.bfg`` router to create renderer
+ globals.
+
+- A new method of the ``Configurator`` exists: ``get_settings``. If
+ used, this method will return the current settings object (performs
+ the same job as the ``repoze.bfg.settings.get_settings`` API).
+
+- The ``Configurator`` constructor takes an additional argument:
+ ``renderer_globals_factory`. If used, this argument will set the
+ factory used by the ``repoze.bfg`` router to create renderer
+ globals.
+
+- Add ``repoze.bfg.renderers.render``,
+ ``repoze.bfg.renderers.render_to_response`` and
+ ``repoze.bfg.renderers.get_renderer`` functions. These are
+ imperative APIs which will use the same rendering machinery used by
+ view configurations with a ``renderer=`` attribute/argument to
+ produce a rendering or renderer. Because these APIs provide a
+ central API for all rendering, they now form the preferred way to
+ perform imperative template rendering. Using functions named
+ ``render_*` from modules such as ``repoze.bfg.chameleon_zpt`` and
+ ``repoze.bfg.chameleon_text`` is now discouraged (although not
+ deprecated). The code the backing older templating-system-specific
+ APIs now calls into the newer ``repoze.bfg.renderer`` code.
+
+- The ``repoze.bfg.configuration.Configurator.testing_add_template``
+ has been renamed to ``testing_add_renderer``. A backwards
+ compatibility alias is present using the old name.
Documentation
-------------
@@ -57,6 +92,15 @@ Documentation
- The ``Hooks`` narrative chapter now contains a section about
changing the request factory.
+- The API documentation includes a new module:
+ ``repoze.bfg.renderers``.
+
+- The ``Templates`` chapter was updated; all narrative that used
+ templating-specific APIs within examples to perform rendering (such
+ as the ``repoze.bfg.chameleon_zpt.render_template_to_response``
+ method) was changed to use ``repoze.bfg.renderers.render_*``
+ functions.
+
Bug Fixes
---------
@@ -67,6 +111,34 @@ Bug Fixes
``TypeError: expected string or buffer`` exception. Now, the
predicate returns False as intended.
+Deprecations
+------------
+
+- The ``repoze.bfg.renderers.rendered_response`` function was never an
+ official API, but may have been imported by extensions in the wild.
+ It is officially deprecated in this release. Use
+ ``repoze.bfg.renderers.render_to_response`` instead.
+
+- The following APIs are *documentation* deprecated (meaning they are
+ officially deprecated in documentation but do not raise a
+ deprecation error upon their usage, and may continue to work for an
+ indefinite period of time):
+
+ In the ``repoze.bfg.chameleon_zpt`` module: ``get_renderer``,
+ ``get_template``, ``render_template``,
+ ``render_template_to_response``. The suggested alternatives are
+ documented within the docstrings of those methods (which are still
+ present in the documentation).
+
+ In the ``repoze.bfg.chameleon_text`` module: ``get_renderer``,
+ ``get_template``, ``render_template``,
+ ``render_template_to_response``. The suggested alternatives are
+ documented within the docstrings of those methods (which are still
+ present in the documentation).
+
+ In general, to perform template-related functions, one should now
+ use the various methods in the ``repoze.bfg.renderers`` module.
+
Backwards Incompatibilities
---------------------------
@@ -98,6 +170,67 @@ Backwards Incompatibilities
the logic which raised the ``NotFound`` exception in the view out
into a custom view predicate.
+- If, when you run your application's unit test suite under BFG 1.3, a
+ ``KeyError`` naming a template or a ``ValueError`` indicating that a
+ 'renderer factory' is not registered may is raised
+ (e.g. ``ValueError: No factory for renderer named '.pt' when looking
+ up karl.views:templates/snippets.pt``), you may need to perform some
+ extra setup in your test code.
+
+ The best solution is to use the
+ ``repoze.bfg.configuration.Configurator.testing_add_renderer`` (or,
+ alternately the deprecated
+ ``repoze.bfg.testing.registerTemplateRenderer`` or
+ ``registerDummyRenderer``) API within the code comprising each
+ individual unit test suite to register a "dummy" renderer for each
+ of the templates and renderers used by code under test. For
+ example::
+
+ config = Configurator()
+ config.testing_add_renderer('karl.views:templates/snippets.pt')
+
+ This will register a basic dummy renderer for this particular
+ missing template. The ``testing_add_renderer`` API actually
+ *returns* the renderer, but if you don't care about how the render
+ is used, you don't care about having a reference to it either.
+
+ A more rough way to solve the issue exists. It causes the "real"
+ template implementations to be used while the system is under test,
+ which is suboptimal, because tests will run slower, and unit tests
+ won't actually *be* unit tests, but it is easier. Always ensure you
+ call the ``setup_registry()`` method of the Configurator . Eg::
+
+ reg = MyRegistry()
+ config = Configurator(registry=reg)
+ config.setup_registry()
+
+ Calling ``setup_registry`` only has an effect if you're *passing in*
+ a ``registry`` argument to the Configurator constructor.
+ ``setup_registry`` is called by the course of normal operations
+ anyway if you do not pass in a ``registry``.
+
+ If your test suite isn't using a Configurator yet, and is still
+ using the older ``repoze.bfg.testing`` APIs name ``setUp`` or
+ ``cleanUp``, these will register the renderers on your behalf.
+
+ A variant on the symptom for this theme exists: you may already be
+ dutifully registering a dummy template or renderer for a template
+ used by the code you're testing using ``testing_register_renderer``
+ or ``registerTemplateRenderer``, but (perhaps unbeknownst to you)
+ the code under test expects to be able to use a "real" template
+ renderer implementation to retrieve or render *another* template
+ that you forgot was being rendered as a side effect of calling the
+ code you're testing. This happened to work because it found the
+ *real* template while the system was under test previously, and now
+ it cannot. The solution is the same.
+
+ It may also help reduce confusion to use a *resource specification*
+ to specify the template path in the test suite and code rather than
+ a relative path in either. A resource specification is unambiguous,
+ while a relative path needs to be relative to "here", where "here"
+ isn't always well-defined ("here" in a test suite may or may not be
+ the same as "here" in the code under test).
+
1.3a5 (2010-07-14)
==================
View
101 TODO.txt
@@ -15,50 +15,10 @@
- ``decorator=`` parameter to bfg_view.
-Renderer overhaul
-------------------
-
-Currently the division of responsibility between the BFG configurator
-and a BFG renderer implementation is awkward and wrong.
-
-- Renderer factories have no ability to convert a raw ``renderer=``
- path (e.g. ``templates/foo.pt```) into something internally
- meaningful. Instead, BFG mangles the string into a package-relative
- spec before it is passed to the renderer factory. This is wrong, as
- some renderers may not be interested in package-relative specs at
- all (for instance, loader-style renderers which have a hardcoded set
- of template locations). The reason, however, that BFG currently
- does it this way is that the raw renderer path alone does not
- contain enough information itself to be useful; knowledge of the
- *package* is also required for package-based renderers to make sense
- of relative renderer strings (e.g. ``templates/foo.pt`` could mean
- the ``templates/foo.pt`` file within the ``mypackage`` package).
-
- To fix this, we need to provide some way to pass the package name to
- the renderer factory as well as the renderer path. But the package
- name isn't the only thing an *arbitrary* renderer might need.
- Another renderer might need, for example, a deployment setting. So
- we'll need to identify all the crap that *might* be useful to a
- renderer factory and we'll need to pass all of it into the renderer
- factory as a garbage barge dictionary; individual renderers will
- make use of whatever they can from that garbage barge dictionary.
- Garbage barge dict item candidates: ``package`` (the "current"
- package), ``config`` (the configurator), ``package_name`` (the
- current package's ``__name__``), ``settings`` (the deployment
- settings), ``registry`` (the component registry).
-
-- A BFG renderer currently returns a *string*. It would be more
- symmetric if a renderer always returned a Response object. Then the
- calling machinery inside BFG could treat a view which happened to
- use a renderer exactly the same as a view which returns a response
- directly. Maybe. Problem: varying response attributes such as
- ``content-type``, etc only makes sense when the view callable uses a
- renderer; not when it doesn't, so there's some asymmetry there.
- Maybe we make renderers return Responses, but still keep the
- attribute-inspection stuff inside BFG, only used when we call a view
- which we know uses a renderer. We *could* always call the attribute
- inspection stuff, but it would be a slowdown in cases where views
- really do always return a Response directly.
+- Try to better explain the relationship between a renderer and a
+ template in the templates chapter and elsewhere. Scan the
+ documentation for reference to a renderer as *only* view
+ configuration (it's a larger concept now).
- The ``system`` value passed to a renderer is not extensible. It
should be extensible on a per-application basis. For example, you
@@ -71,56 +31,3 @@ and a BFG renderer implementation is awkward and wrong.
``system`` values available to it as templates renderered via a view
renderer.
-To at least partially ameliorate the above, renderer factories should
-be changed to things that have a set of interfaces something like
-this::
-
- class IRendererFactory(Interface):
- def __call__(path, info):
- "" Return an IRenderer."""
-
- class IRenderer(Interface):
- def __call__(value, system):
- """ Return a Response """
-
-A semi-pseudocode example:
-
- from webob import Response
-
- class SampleRendererFactory(object):
- def __init__(self, **config):
- self.config = config
-
- def __call__(self, path, info):
- path = do_something_to_evaluate_path_using_info(path, info)
- search_path = self.config['search_path']
- debug = self.config['debug']
- def renderer(value, system):
- string = do_rendering(search_path, debug, path, value, system)
- return Response(string)
- return renderer
-
- if __name__ == '__main__':
-
- def view1(request):
- return {'a':1}
-
- def view2(request):
- return {'a':2}
-
- renderer_factory = SampleRendererFactory(search_path=['/a', '/b'])
-
- package_name = 'some.package'
-
- for view, path in [
- (view1, 'templates/foo.pt'),
- (view2, 'templates/bar.pt'),
- ]:
- renderer = renderer_factory(path, dict(package_name=package_name))
- register_renderer_for_view(renderer, view)
-
-This is mostly an amelioration for the first and second bullet points
-above. The second two bullet points are not addressed by it.
-
-Also: think about generalizing this a bit into something which wraps a
-view callable like a decorator, which can influence input and output.
View
@@ -19,6 +19,7 @@ documentation is organized alphabetically by module name.
api/interfaces
api/location
api/paster
+ api/renderers
api/router
api/scripting
api/security
View
@@ -5,7 +5,7 @@
.. automodule:: repoze.bfg.configuration
- .. autoclass:: Configurator(registry=None, package=None, settings=None, root_factory=None, authentication_policy=None, authorization_policy=None, renderers=DEFAULT_RENDERERS, debug_logger=None, locale_negotiator=None, request_factory=None)
+ .. autoclass:: Configurator(registry=None, package=None, settings=None, root_factory=None, authentication_policy=None, authorization_policy=None, renderers=DEFAULT_RENDERERS, debug_logger=None, locale_negotiator=None, request_factory=None, renderer_globals_factory=None)
.. attribute:: registry
@@ -20,7 +20,9 @@
.. automethod:: unhook_zca()
- .. automethod:: setup_registry(settings=None, root_factory=None, authentication_policy=None, renderers=DEFAULT_RENDERERS, debug_logger=None)
+ .. automethod:: get_settings
+
+ .. automethod:: setup_registry(settings=None, root_factory=None, authentication_policy=None, renderers=DEFAULT_RENDERERS, debug_logger=None, locale_negotiator=None, request_factory=None, renderer_globals_factory=None)
.. automethod:: add_renderer(name, factory)
@@ -54,11 +56,13 @@
.. automethod:: set_request_factory
+ .. automethod:: set_renderer_globals_factory
+
.. automethod:: testing_securitypolicy
.. automethod:: testing_models
.. automethod:: testing_add_subscriber
- .. automethod:: testing_add_template
+ .. automethod:: testing_add_renderer
View
@@ -0,0 +1,13 @@
+.. _renderers_module:
+
+:mod:`repoze.bfg.renderers`
+---------------------------
+
+.. module:: repoze.bfg.renderers
+
+.. autofunction:: get_renderer
+
+.. autofunction:: render
+
+.. autofunction:: render_to_response
+
View
@@ -756,3 +756,8 @@ Glossary
cultural context. Often shortened to "l10" (because the word
"localization" is L, 10 letters, then N). See also:
:term:`Internationalization`.
+
+ renderer globals
+ Values injected as names into a renderer based on application
+ policy. See :ref:`adding_renderer_globals` for more
+ information.
Oops, something went wrong.

0 comments on commit 250c021

Please sign in to comment.