Routing and Template Cookbook: Basic routing, handlers, and templates

Making a page with the routing and Template Toolkit system requires a few things:


 * 1) Define a URL string or pattern
 * 2) Create a handler function, attached to the URL string or pattern
 * 3) Make any needed templates

The URL(s) and handler function(s) go into the controller file, which will be somewhere in $LJHOME/cgi-bin/DW/Controller.

The template(s) will go into $LJHOME/views.

= Defining a URL =

First, you need to define a URL in a controller file in $LJHOME/cgi-bin/DW/Controller. This will tell the system what handler function to use for a given URL pattern.

Here are some examples of registering a URL. There are two main functions to do this with, register_string and register_regex.

Defining an index page
This registers all of /something, /something/ and /something/index

= Creating a handler function =

The handler function tells the system what to do with the browser request it is receiving. It's also defined in the controller file you register the URL in, in $LJHOME/cgi-bin/DW/Controller. The handler function will look up things, define variables we need for the page, and pass them onto the template.

I'm going to use the Nav controller as an example. You can see the entire page at DW::Controller::Nav.pm.

We define our URL in the same file we place the handler function, so we'll start there:

First, I want to get the options, subpatterns, and request:

Remember that subpattern I made in my URL regex? I'll figure out if I'm using it or an argument here.

Here, I'm doing error checking. If I don't get back the array of menu hashes, I'm going to serve an error page that contains a translated error message. Notice how I have to define the whole path to the error message, and can't just use ".error.invalidcat".

I'm getting some cruft that is needed by the real menu that I don't want to display on this page, so I'll go through all the menus and strip out HTML from the titles. Ideally there would be a Template Toolkit filter that could do this, but I have not found one yet; we may have to make one.

This is a nifty part. I can display the contents of this page either as HTML or as JSON (which is made for machine parsing), with very very little additional code.

The first one is how to return something as JSON. I just print out the object conversion to the request and return OK.

The HTML format takes a bit more work. We want to pass in more variables to the template and return the rendered template.

Here we go preparing the variables:

And this is the call to render our template (more on making that next):

If my format isn't HTML or JSON, we throw a 404.

And that's the handler!

= Creating a template =

The template will be placed somewhere logical in $LJHOME/views. This one will be nav.tt. Currently, translation strings will go in nav.tt.text</tt>.

This section is a comment:

This section sets the title of the page. If we have a category, it will be the category title. Otherwise, it will use the ML translation of the title for the page.

This section creates the menu sections, applying code for each menu and each item in each menu. If this isn't only displaying a category, it makes the title. You can see the html filter being used in places like [% menu.title | html %]</tt> to ensure that all HTML is safe, and the url filter being used in [% menu_item.url | url %]</tt> to make sure that URL will be validly encoded.

That template is all that's required to render the HTML for the nav page! You can see it live on Dreamwidth.