Templating in Restish — Restish v0.7.1 documentation

### Navigation

- index
- modules |
- next |
- previous |
- Restish v0.7.1 documentation »

Overview

# Templating in Restish

Restish does not imply the use of any particular templating language. Instead, we have provided stubs that can be used with some of the more popular templating languages which can be enabled by uncommenting a section withing the wsgiapp.py.

## Configuring a templating language within lib/templating.py

Here is an example of the uncommented code that enables the mako renderer.

    def make_renderer(app_conf):
        """
        Create and return a restish.templating "renderer".
        """

        import pkg_resources
        import os.path
        from restish.contrib.makorenderer import MakoRenderer
        return MakoRenderer(
                directories=[
                    pkg_resources.resource_filename('myproject', 'templates')
                    ],
                module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
                input_encoding='utf-8', output_encoding='utf-8',
                default_filters=['unicode', 'h']
                )

The mako renderer configures the project template directory, a cache directory, our default encoding and a default filter (unicode, which is mako default, and html escaping, which we felt is safest).

## Explicit templating

You can call the templating engine explicity by using `restish.templating`. e.g.

    class Root(resource.Resource):

        @resource.GET()
        def html(self, request):
            content = templating.render(request, 'mytemplate.html', {'name': 'Tim'})
            return http.ok( [('Content-Type','text/html')], content )

## Templating decorator

However it is a lot easier to use the templating decorator. By adding this decorator,

    class Root(resource.Resource):

        @resource.GET()
        @templating.page('mytemplate.html')
        def html(self, request):
            return {'name': 'Tim'}

templating.page uses the content type passed in by the request so all you need to do is provide a template in the decorator and the arguments for the template in the return dictionary.

## Template Default Variables

Quite often you will write your own functions or want supply default variables to use within your template (possibly a set of site urls). This can be set up within the `<project>/lib/templating.py` by overriding the args method of the Rendering class.

    class Rendering(templating.Rendering):

        def args(self, request):
            # Call the super class to get the basic set of args.
            args = super(Rendering, self).args(request)
            # Push to the args and return them.
            args['myurldict'] = {'about': '/about', 'contact':'/contact'}
            return args

## A better way of dealing with URLs

Using strings for urls isn’t particularly safe in a lot of cases and sometimes you might want a little more flexibility with your url handling. Also, some urls are application specific and the template has no way of finding out what the current url is. Restish automatically includes a `urls` arg which is a `URLAccessor` based on the current request.

Note

These attributes are the same as the attributes on the webob request object. See http://pythonpaste.org/webob/

`URLAccessor.` `url`
  Return the full current (i.e. requested), URL.

`URLAccessor.` `path`
  Return the path part of the current URL, relative to the root of the web server.

`URLAccessor.` `path_qs`
  Return the path of the current URL, relative to the root of the web server, and the query string.

`URLAccessor.` `host_url`
  Return the host’s URL, i.e. the URL of the HTTP server.

`URLAccessor.` `path_url`
  Return the path’s URL, i.e. the current URL without the query string.

`URLAccessor.` `application_url`
  Return the WSGI application’s URL.

Let’s see what these look like for an example url `http://restish.com/tickets/search?u=foo#first` which is a wsgi app mounted at `/tickets`

Template var | Output
--- | ---
`${urls.url}` | `http://restish.com/tickets/search?u=foo#first`
`${urls.path}` | `/tickets/search`
`${urls.path_qs}` | `/tickets/search?u=foo#first`
`${urls.host_url}` | `http://restish.com`
`${urls.path_url}` | `http://restish.com/tickets/search`
`${urls.application_url}` | `http://restish.com/tickets`

There is also a `urls.new()` method which allows you to create your own urls from scratch. Once you have one of these urls (or a new one) you can use some of the utility methods on them to create modified urls. e.g.

Template var | Output
--- | ---
`${urls.new('/').child('Tim Parkin')` | `/Tim%20Parkin`
`${urls.url.parent()}` | `http://restish.com/tickets?u=foo#first`
`${urls.application_url.click('search?u=foo')` | `/tickets/search?u=foo`
`${urls.url.sibling('help')}` | `http://restish.com/tickets/help?u=foo#first`
`${urls.url.sibling('help').path_qs}` | `/tickets/help?u=foo#first`
`${urls.path_qs.anchor()}` | `/tickets/search?u=foo`
`${urls.path_qs.anchor('last')}` | `/tickets/search?u=foo#last`
`${urls.path_qs.clear_queries()}` | `/tickets/search#last`
`${urls.path_qs.replace_query('u','bar')}` | `/tickets/search?u=bar#first`
`${urls.path_qs.add_query('page','7')}` | `/tickets/search?u=foo&page=7#first`
`${urls.url.secure()}` | `https://restish.com/tickets/search?u=foo#first`
`${urls.path_qs.add_queries([('p','7'),('x','9')])}` | `/tickets/search?u=foo&p=7&x=9#first`

Here are the docstrings for the above methods/properties

`URL.` `root`()
  Contruct a URL to the root of the web server.

`URL.` `sibling`(segment)
  Construct a url where the given path segment is a sibling of this url

`URL.` `child`(*path)
  Construct a url where the given path segment is a child of this url

`URL.` `parent`()
  Pop a URL segment from this url.

`URL.` `click`(href)

  Modify the path as if `href` were clicked

  Create a url as if the current url was given by `self` and `href` was clicked on

`URL.` `add_query`(name, value=None)

  Add a query argument with the given value

  Parameters: | key – the query key value – The query value. None means do not use a value. e.g. `?key=`

`URL.` `add_queries`(query_list)

  Add multiple query args from a list of tuples

  Parameters: | query_list – list of tuple (key, value) pairs

`URL.` `replace_query`(name, value=None)

  Remove all existing occurrences of the query argument ‘name’, if it exists, then add the argument with the given value.

  Parameters: | key – the query key value – The query value. None means do not use a value. e.g. `?key=`

`URL.` `remove_query`(name)

  Remove all query arguments with the given name

  Parameters: | name – the name of the query arguments to remove

`URL.` `clear_queries`(name=None)

  Remove all existing query arguments

  Parameters: | name – the name of the query arguments to remove, defaults to removing all

`URL.` `secure`(secure=True, port=None)

  Modify the scheme to https/http and return the new URL.

  Parameters: | secure – choose between https and http, default to True (https) port – port, override the scheme’s normal port

`URL.` `anchor`(anchor=None)

  Modify the fragment/anchor and return a new URL.

  Parameters: | anchor – An anchor of None (the default) or ‘’ will remove the current anchor.

You can also filter particular parts of a url

`URL.` `scheme`
  The url scheme (http, https, etc)

`URL.` `netloc`
  The domain or network location

`URL.` `path`
  The path of the url without query string or fragment

`URL.` `path_qs`
  The path, query string and fragment

`URL.` `path_segments`
  A list of url segments

`URL.` `query`
  The query parameters as a string

`URL.` `query_list`
  The query parameters as a list of tuples

`URL.` `fragment`
  The url fragment (e.g. #anchor)

## Pages and Elements

When more complex applications are developed, it is quite common to have resources that are used repeatedly on multiple pages. Restish includes two subclassses of resource called Page and Element. A Page is a resource that has a per request scoped registry of Elements (Where Elements are simple resources but which also have a registry of Elements to allow nested Elements).

An example of where this could be useful is where a login status is regularly included on pages throughout a site.

    class LoginStatusElement(page.Element):

        def __call__(self, request):
            return templating.render(request, 'login_status.html',{})

    class BasePage(page.Page):

        @page.element('login')
        def login_status(self, request):
            return auth.LoginStatusElement()

    <div id="loginstatus"> ${element('login_status')()|n} </div>

### Navigation

- index
- modules |
- next |
- previous |
- Restish v0.7.1 documentation »