URL generator

A class that consolidates Pyramid’s various URL-generating functions into one concise API that’s convenient for templates. It performs the same job as pylons.url in Pylons applications, but the API is different.

Pyramid has several URL-generation routines but they’re scattered between Pyramid request methods, WebOb request methods, Pyramid request attributes, WebOb request attributes, and Pyramid functions. They’re named inconsistently, and the names are too long to put repeatedly in templates. The methods are usually – but not always – paired: one method returning the URL path only (“/help”), the other returning the absolute URL (“http://example.com/help”). Pylons defaults to URL paths, while Pyramid tends to absolute URLs (because that’s what the methods with “url” in their names return). The Akhet author prefers path URLs because the automatically adjust under reverse proxies, where the application has the wrong notion of what its visible scheme/host/port is, but the browser knows which scheme/host/port it requested the page on.

URLGenerator unifies all these by giving short one-word names to the most common methods, and having a switchable default between path URLs and absolute URLs.

Usage

Copy the “subscribers” module in the Akhet demo (akhet_demo/subscribers.py) to your own application, and modify it if desired. Then, include it in your main function:

# In main().
config.include(".subscribers")

The subscribers attach the URL generator to the request as request.url_generator, and inject it into the template namespace as url.

URLGenerator was contributed by Michael Merickel and modified by Mike Orr.

API

class akhet.urlgenerator.URLGenerator(context, request, qualified=False)
__call__(*elements, **kw)

Same as the .route method.

__init__(context, request, qualified=False)

Instantiate a URLGenerator based on the current request.

  • request: a Pyramid Request.
  • context: a Pyramid Context.
  • qualified: If true, return fully-qualified URLs with the “scheme://host” prefix. If false (default), return only the URL path if the underlying Pyramid function allows it.
app

The application URL or path.

I’m a “reified” attribute which means I start out as a property but I turn into an ordinary string attribute on the first access. This saves CPU cycles if I’m accessed often.

I return the application prefix of the URL. Append a slash to get the home page URL, or additional path segments to get a sub-URL.

If the constructor arg ‘qualified’ is true, I return request.application_url, otherwise I return request.script_name.

ctx

The URL of the default view for the current context.

I’m a “reified” attribute which means I start out as a property but I turn into an ordinary string attribute on the first access. This saves CPU cycles if I’m accessed often.

I am mainly used with traversal. I am different from .app when using context factories. I always return a qualified URL regardless of the constructor’s ‘qualified’ argument.

route(route_name, *elements, **kw)

Generate a route URL.

I return a URL based on a named route. Calling the URLGenerator instance is the same as calling me. If the constructor arg ‘qualified’ is true, I call pyramid.url.route_url, otherwise I call pyramid.url.route_path.

Arguments:

  • route_name: the name of a route.
  • *elements: additional segments to append to the URL path.

Keyword arguments are passed to the underlying function. The following are recognized:

  • _query: the query parameters. May be a dict-like object with an .items() method or a sequence of 2-tuples.
  • _anchor: the URL’s “#ancor” fragment without the “#”.
  • _qualified: override the constructor’s “qualified” flag.
  • _app_url: override the “scheme://host” prefix. (This also causes the result to be qualified if it wouldn’t otherwise be.)
  • Other keyword args override path variables defined in the route.

If the relevant route has a pregenerator defined, it may modify the elements or keyword args.

current(*elements, **kw)

Generate a URL based on the current request’s route.

I call pyramid.url.current_route_url. I’m the same as calling .route with the current route name. The result is always qualified regardless of the constructor’s ‘qualified’ argument.

resource(*elements, **kw)

Return a “resource URL” as used in traversal.

*elements is the same as with .route. Keyword args query and anchor are the same as the _query and _anchor args to .route.

When called without arguments, I return the same as .ctx.

Subclassing

The source code (akhet/urlgenerator.py) has some commented examples of things you can do in a subclass. For instance, you can define a static method to generate a URL to a static asset in your application, or a deform method to serve static files from the Deform form library. The instance has request and context attributes, which you can use to calculate any URL you wish. You can put a subclass in your application and then adjust the subscribers to use it.

The reason the base class does not define a static method, is that we’re not sure yet what the best long-term API is. We want something concise enough for everyday use but also supporting unusual cases, and something we can guarantee is correct and we’re comfortable supporting long-term. There’s also the issue of the static route helper vs Pyramid’s static view, or multiple Pyramid static views responding to different sub-URLs. In the meantime, if you want a static method, you can decide on your own favorite API and implement it.

Table Of Contents

Previous topic

Static route

Next topic

Pony