diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-01-27 21:57:11 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-01-27 21:57:11 +0000 |
| commit | e62e479e338e428f6cfd3b07790545982b7cb94f (patch) | |
| tree | c9784577f791d4a8ea5b80a9fce211ce86009712 /repoze/bfg/url.py | |
| parent | 2301cf61977102b85279ea7c04797f76012202e5 (diff) | |
| download | pyramid-e62e479e338e428f6cfd3b07790545982b7cb94f.tar.gz pyramid-e62e479e338e428f6cfd3b07790545982b7cb94f.tar.bz2 pyramid-e62e479e338e428f6cfd3b07790545982b7cb94f.zip | |
Features
--------
- The ``repoze.bfg.url.model_url`` API now works against contexts
derived from Routes URL dispatch (``Routes.util.url_for`` is called
under the hood).
- "Virtual root" support for traversal-based applications has been
added. Virtual root support is useful when you'd like to host some
model in a :mod:`repoze.bfg` model graph as an application under a
URL pathname that does not include the model path itself. For more
information, see the (new) "Virtual Hosting" chapter in the
documentation.
- A ``repoze.bfg.traversal.virtual_root`` API has been added. When
called, it returns the virtual root object (or the physical root
object if no virtual root has been specified).
Implementation Changes
----------------------
- ``repoze.bfg.traversal.RoutesModelTraverser`` has been moved to
``repoze.bfg.urldispatch``.
- ``model_url`` URL generation is now performed via an adapter lookup
based on the context and the request.
- ZCML which registers two adapters for the ``IContextURL`` interface
has been added to the configure.zcml in ``repoze.bfg.includes``.
Diffstat (limited to 'repoze/bfg/url.py')
| -rw-r--r-- | repoze/bfg/url.py | 55 |
1 files changed, 18 insertions, 37 deletions
diff --git a/repoze/bfg/url.py b/repoze/bfg/url.py index a51333353..9ea82ed7a 100644 --- a/repoze/bfg/url.py +++ b/repoze/bfg/url.py @@ -3,43 +3,28 @@ import re import urllib -from zope.component import queryUtility -from zope.interface import implements - -from repoze.bfg.location import lineage -from repoze.bfg.interfaces import IURLGenerator - -class DefaultURLGenerator(object): - implements(IURLGenerator) - def model_url(self, model, request): - rpath = [] - for location in lineage(model): - name = location.__name__ - if name: - rpath.append(_urlsegment(name)) - if rpath: - prefix = '/' + '/'.join(reversed(rpath)) + '/' - else: - prefix = '/' - return request.application_url + prefix - -default_url_generator = DefaultURLGenerator() +from zope.component import getMultiAdapter +from repoze.bfg.interfaces import IContextURL +from repoze.bfg.interfaces import VH_ROOT_KEY def model_url(model, request, *elements, **kw): """ - Generate a string representing the absolute URL of the model - object based on the ``wsgi.url_scheme``, ``HTTP_HOST`` or + Generate a string representing the absolute URL of the model (or + context) object based on the ``wsgi.url_scheme``, ``HTTP_HOST`` or ``SERVER_NAME`` in the request, plus any ``SCRIPT_NAME``. If a + 'virtual root path' is present in the request environment (the + value of the environ key ``%s``), and the ``model`` was obtained + via traversal, the URL path will not include the virtual root + prefix (it will be stripped out of the generated URL). If a ``query`` keyword argument is provided, a query string based on its value will be composed and appended to the generated URL string (see details below). The overall result of this function - is always a string (never unicode). The ``model`` passed in must - be :term:`location`-aware. + is always a UTF-8 encoded string (never unicode). - .. note:: If any model in the lineage has a unicode name, it will - be converted to UTF-8 before being attached to the URL. - When composing the path based on the model lineage, - empty names in the model graph are ignored. + .. note:: If the ``model`` used is the result of a traversal, it + must be :term:`location`-aware. The 'model' can also be the + context of a URL dispatch; contexts found this way do not need + to be location-aware. Any positional arguments passed in as ``elements`` must be strings or unicode objects. These will be joined by slashes and appended @@ -63,19 +48,16 @@ def model_url(model, request, *elements, **kw): the resulting string is appended to the generated URL. .. note:: Python data structures that are passed as ``query`` - whichare sequences or dictionaries are turned into a + which are sequences or dictionaries are turned into a string under the same rules as when run through urllib.urlencode with the ``doseq`` argument equal to ``True``. This means that sequences can be passed as values, and a k=v pair will be placed into the query string for each value. - """ - - urlgenerator = queryUtility(IURLGenerator) - if urlgenerator is None: - urlgenerator = default_url_generator + """ % VH_ROOT_KEY - model_url = urlgenerator.model_url(model, request) + context_url = getMultiAdapter((model, request), IContextURL) + model_url = context_url() if 'query' in kw: qs = '?' + urlencode(kw['query'], doseq=True) @@ -87,7 +69,6 @@ def model_url(model, request, *elements, **kw): else: suffix = '' - app_url = request.application_url # never ends in a slash return model_url + suffix + qs def urlencode(query, doseq=False): |
