diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-09-17 19:58:01 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-09-17 19:58:01 +0000 |
| commit | 750ce41f217cd7b638ad5b69fcb9df1b49841b58 (patch) | |
| tree | a0a8edbc60694d3ae16b70570b0184a8ef28ee65 /repoze/bfg/url.py | |
| parent | 19473e78e61ad084f07a0f7820a75b6c64d93dcd (diff) | |
| download | pyramid-750ce41f217cd7b638ad5b69fcb9df1b49841b58.tar.gz pyramid-750ce41f217cd7b638ad5b69fcb9df1b49841b58.tar.bz2 pyramid-750ce41f217cd7b638ad5b69fcb9df1b49841b58.zip | |
- Add a ``repoze.bfg.url.static_url`` API which is capable of
generating URLs to static resources defined by the ``<static>`` ZCML
directive. See the "Views" narrative chapter's section titled
"Generating Static Resource URLs" for more information.
Diffstat (limited to 'repoze/bfg/url.py')
| -rw-r--r-- | repoze/bfg/url.py | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/repoze/bfg/url.py b/repoze/bfg/url.py index dcaea67ff..f21334191 100644 --- a/repoze/bfg/url.py +++ b/repoze/bfg/url.py @@ -1,5 +1,6 @@ """ Utility functions for dealing with URLs in repoze.bfg """ +import os import urllib from zope.component import queryMultiAdapter @@ -7,6 +8,8 @@ from zope.component import getUtility from repoze.bfg.interfaces import IContextURL from repoze.bfg.interfaces import IRoutesMapper +from repoze.bfg.path import caller_package +from repoze.bfg.static import StaticRootFactory from repoze.bfg.traversal import TraversalContextURL from repoze.bfg.traversal import quote_path_segment @@ -29,9 +32,9 @@ def route_url(route_name, request, *elements, **kw): route_url('foobar', request, foo='1') => <KeyError exception> route_url('foobar', request, foo='1', bar='2') => <KeyError exception> route_url('foobar', request, foo='1', bar='2', - 'traverse=('a','b') => http://e.com/1/2/a/b + 'traverse=('a','b')) => http://e.com/1/2/a/b route_url('foobar', request, foo='1', bar='2', - 'traverse=('/a/b') => http://e.com/1/2/a/b + 'traverse=('/a/b')) => http://e.com/1/2/a/b Values replacing ``:segment`` arguments can be passed as strings or Unicode objects. They will be encoded to UTF-8 and URL-quoted @@ -197,6 +200,55 @@ def model_url(model, request, *elements, **kw): return model_url + suffix + qs + anchor +def static_url(path, request, **kw): + """ + Generates a fully qualified URL for a static resource. The + resource must live within a location defined via the ``<static>`` + ZCML directive. + + The ``path`` argument points at a file or directory on disk which + a URL should be generated for. The ``path`` may be either a + relative path (e.g. ``static/foo.css``) or a :term:`resource + specification` (e.g. ``mypackage:static/foo.css``). A ``path`` + may not be an absolute filesystem path (a ValueError will be + raised if this function is supplied with an absolute path). + + The ``request`` argument should be a WebOb request. + + The purpose of the ``**kw`` argument is the same as the purpose of + the ``route_url`` ``*kw`` argument. See the documentation for + that function to understand the arguments which you can provide to + it. However, typically, you don't need to pass anything as + ``*kw`` when generating a static resource URL. + + This function raises a ValueError if a ``<static>`` ZCML + definition cannot be found which matches the path specification. + + .. note:: This feature is new in :mod:`repoze.bfg` 1.1. + """ + mapper = getUtility(IRoutesMapper) + routes = mapper.get_routes() + if os.path.isabs(path): + raise ValueError('Absolute paths cannot be used to generate static ' + 'urls (use a package-relative path or a resource ' + 'specification).') + if not ':' in path: + # if it's not a package:relative/name and it's not an + # /absolute/path it's a relative/path; this means its relative + # to the package in which the caller's module is defined. + package = caller_package(level=2) + path = '%s:%s' % (package.__name__, path) + + for route in routes: + factory = route.factory + if factory.__class__ is StaticRootFactory: + if path.startswith(factory.spec): + subpath = path[len(factory.spec):] + kw['subpath'] = subpath + return route_url(route.name, request, **kw) + + raise ValueError('No static URL definition matching %s' % path) + def urlencode(query, doseq=False): """ A wrapper around Python's stdlib `urllib.urlencode function |
