From b29429e470c093573f3735b0dbf09d42c29cfe4d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 2 Jul 2010 01:47:47 +0000 Subject: - The ``repoze.bfg.url.route_url`` API has changed. If a keyword ``_app_url`` is present in the arguments passed to ``route_url``, this value will be used as the protocol/hostname/port/leading path prefix of the generated URL. For example, using an ``_app_url`` of ``http://example.com:8080/foo`` would cause the URL ``http://example.com:8080/foo/fleeb/flub`` to be returned from this function if the expansion of the route pattern associated with the ``route_name`` expanded to ``/fleeb/flub``. - It is now possible to use a URL as the ``name`` argument fed to ``repoze.bfg.configuration.Configurator.add_static_view``. When the name argument is a URL, the ``repoze.bfg.url.static_url`` API will generate join this URL (as a prefix) to a path including the static file name. This makes it more possible to put static media on a separate webserver for production, while keeping static media package-internal and served by the development webserver during development. --- repoze/bfg/configuration.py | 97 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 85 insertions(+), 12 deletions(-) (limited to 'repoze/bfg/configuration.py') diff --git a/repoze/bfg/configuration.py b/repoze/bfg/configuration.py index 869e8c2c2..60fe4627e 100644 --- a/repoze/bfg/configuration.py +++ b/repoze/bfg/configuration.py @@ -34,6 +34,7 @@ from repoze.bfg.interfaces import IRouteRequest from repoze.bfg.interfaces import IRoutesMapper from repoze.bfg.interfaces import ISecuredView from repoze.bfg.interfaces import ISettings +from repoze.bfg.interfaces import IStaticURLInfo from repoze.bfg.interfaces import ITemplateRenderer from repoze.bfg.interfaces import ITranslationDirectories from repoze.bfg.interfaces import ITraverser @@ -59,7 +60,7 @@ from repoze.bfg.request import route_request_iface from repoze.bfg.resource import PackageOverrides from repoze.bfg.resource import resolve_resource_spec from repoze.bfg.settings import Settings -from repoze.bfg.static import StaticRootFactory +from repoze.bfg.static import StaticURLInfo from repoze.bfg.threadlocal import get_current_registry from repoze.bfg.threadlocal import get_current_request from repoze.bfg.threadlocal import manager @@ -68,7 +69,6 @@ from repoze.bfg.traversal import DefaultRootFactory from repoze.bfg.traversal import find_interface from repoze.bfg.urldispatch import RoutesMapper from repoze.bfg.view import render_view_to_response -from repoze.bfg.view import static from repoze.bfg.view import default_notfound_view from repoze.bfg.view import default_forbidden_view @@ -1454,27 +1454,100 @@ class Configurator(object): ctranslate = ChameleonTranslate(translator) self.registry.registerUtility(ctranslate, IChameleonTranslate) - def add_static_view(self, name, path, cache_max_age=3600, _info=u''): - """ Add a view used to render static resources to the current - configuration state. + def add_static_view(self, name, path, **kw): + """ Add a view used to render static resources such as images + and CSS files. The ``name`` argument is a string representing :term:`view - name` of the view which is registered. + name` of the view which is registered. It may alternately be + a *url prefix*. The ``path`` argument is the path on disk where the static files reside. This can be an absolute path, a package-relative path, or a :term:`resource specification`. + The ``cache_max_age`` keyword argument is input to set the + ``Expires`` and ``Cache-Control`` headers for static resources + served. Note that this argument has no effect when the + ``name`` is a *url prefix*. + + Usage + ----- + + The ``add_static_view`` function is typically used in + conjunction with the :func:`repoze.bfg.url.static_url` + function. ``add_static_view`` adds a view which renders a + static resource when some URL is visited; + :func:`repoze.bfg.url.static_url` generates a URL to that + resource. + + The ``name`` argument to ``add_static_view`` is usually a + :term:`view name`. When this is the case, the + :func:`repoze.bfg.url.static_url` API will generate a URL + which points to a BFG view, which will serve up a set of + resources that live in the package itself. For example: + + .. code-block:: python + + add_static_view('images', 'mypackage:images/') + + Code that registers such a view can generate URLs to the view + via :func:`repoze.bfg.url.static_url`: + + .. code-block:: python + + static_url('mypackage:images/logo.png', request) + + When ``add_static_view`` is called with a ``name`` argument + that represents a simple view name, as it is above, subsequent + calls to :func:`repoze.bfg.url.static_url` with paths that + start with the ``path`` argument passed to ``add_static_view`` + will generate a URL something like ``http:///images/logo.png``, which will cause the ``logo.png`` file + in the ``images`` subdirectory of the ``mypackage`` package to + be served. + + ``add_static_view`` can alternately be used with a ``name`` + argument which is a *URL*, causing static resources to be + served from an external webserver. This happens when the + ``name`` argument is a URL (detected as any string with a + slash in it). In this mode, the ``name`` is used as the URL + prefix when generating a URL using + :func:`repoze.bfg.url.static_url`. For example, if + ``add_static_view`` is called like so: + + .. code-block:: python + + add_static_view('http://example.com/images', 'mypackage:images/') + + Subsequently, the URLs generated by + :func:`repoze.bfg.url.static_url` for that static view will be + prefixed with ``http://example.com/images``: + + .. code-block:: python + + static_url('mypackage:images/logo.png', request) + + When ``add_static_view`` is called with a ``name`` argument + that is the URL prefix ``http://example.com/images``, + subsequent calls to :func:`repoze.bfg.url.static_url` with + paths that start with the ``path`` argument passed to + ``add_static_view`` will generate a URL something like + ``http://example.com/logo.png``. The external webserver + listening on ``example.com`` must be itself configured to + respond properly to such a request. + See :ref:`static_resources_section` for more information. """ spec = self._make_spec(path) - view = static(spec, cache_max_age=cache_max_age) - self.add_route(name, "%s*subpath" % name, view=view, - view_for=StaticRootFactory, - factory=StaticRootFactory(spec), - _info=_info) - # testing API + info = self.registry.queryUtility(IStaticURLInfo) + if info is None: + info = StaticURLInfo(self) + self.registry.registerUtility(info, IStaticURLInfo) + info.add(name, spec, **kw) + + # testing API def testing_securitypolicy(self, userid=None, groupids=(), permissive=True): """Unit/integration testing helper: Registers a pair of faux -- cgit v1.2.3