Using URLs

turbogearsl.url()

CherryPy makes defining what happens for a given URL quite easy: you just give your Python objects the methods you need. In your templates and your code, you can just use the URLs based on how you’ve defined them for CherryPy.

Sometimes, however, the URLs you use are affected by the environment they’re in. For example, if your whole TurboGears site is running at http://yoursite.com/~yourusername/tg, you’ll need to be sure that absolute URLs take that into account.

TurboGears provides a convenient url function to create these URLs. Let’s say you want to redirect to /view?id=5&page=10. You can call turbogears.url("/view", id=5, page=10) to get a URL that takes into account the top of the site. How does it know where the top of the site is? The server.webpath configuration variable will tell it where the top of your site is.

The url function is also available in templates as tg.url.

Future versions of TurboGears will also make it easy to wire up multiple TurboGears applications in one site. The url function already understands the concept of an application root and will generate absolute URLs relative to the application root.

Note

Note: in order for the url function to recognize the application root, your root controller class must extend from turbogears.controllers.RootController. It is also recommended that your controllers extend from turbogears.controllers.Controller.

turbogears.absolute_url()

New in TurboGears 1.1

When you reference other parts of your application in the template output by URLs, you should normally use relocatable URLs, i.e. URLs which do not specify a URL scheme and host name, so that they will automatically point to the same server as the page where they are used.

Sometimes, however, you need to construct full, absolute URLs, including the URL scheme and the server name, so you can include them in e.g. an RSS/Atom feed, an email, a log file, etc. That is what the absolute_url function is for. It wraps the normal url function and takes the same arguments, but always returns a full, absolute URL.

It tries to account for differnt deployment situations, where your TurboGears server may server differnt virtaul hosts or runs behind a reverse proxy, by using the Host X-Forwarded-Host headers when appropriate.

The host name part of the URL, to be more precisely, is determined this way:

  • If the config setting tg.url_domain is set and non-null, use this value.
  • Else, if the base_url_filter.use_x_forwarded_host config setting is True, use the value from the Host or X-Forwarded-Host request header.
  • Else, if the config setting base_url_filter.on is True and base_url_filter.base_url is non-null, use its value for the host and scheme part of the URL.
  • As a last fallback, use the value of server.socket_host and server.socket_port config settings (defaults to 'localhost:8080'). This should only happen, when the client uses an outdated HTTP version.

The URL scheme ('http' or 'https') used is determined in the following way:

  • If base_url_filter.base_url is used, use the scheme from this URL.
  • If there is a X-Use-SSL request header, use 'https'.
  • Else, if the config setting tg.url_scheme is set and non-null, use its value.
  • Else, use the value of cherrypy.request.scheme.

Usage examples

# 'tg.url_domain' is set to 'www.server.com'
absolute_url('/foo')
--> 'http://www.server.com/foo'

# Client sends 'Host' header with value 'blog.foo.org'
absolute_url('/', article=10)
--> 'http://blog.foo.org/?article=10'

# 'base_url_filter.on' == True, 'base_url_filter.use_x_forwarded_host' == False
# and 'base_url_filter.base_url' == 'http://acme.com:8888/'
absolute_url('/about')
--> 'http://acme.com:8888/about'

# Reverse proxy sets 'X-Use-SSL' header and client sends 'Host' header with value
# 'www.secure.org'
absolute_url('/login')
--> 'https://www.secure.org/login')

# 'tg.url_scheme' is set to 'https' and client sends 'Host' header with value
# 'www.secure.org'
absolute_url('/login')
--> 'https://www.secure.org/login')