Latest Version: 0.9.6.2
  Dashboard > Pylons Cookbook > ... > Templating > Navigation Components with Myghty
  Pylons Cookbook Log In | Sign Up   View a printable version of the current page.  
  Navigation Components with Myghty
Added by James Gardner, last edited by D. B. Dweeb on Jun 14, 2007  (view change)
Labels: 
(None)

Warning

This is a work in progress and hasn't been tested yet

In this tutorial we will create a simple website with a main template, top-level navigation, a breadcrumb trail and some simple components.

The 3aims website runs on a Pylons application which is very similar to this, as does the PylonsHQ site.

Note:This tutorial uses Pylons 0.9, the development version of Pylons.

Getting Started

First install Pylons 0.9:

easy_install -U http://pylonshq.com/svn/Pylons/trunk

When Pylons 0.9 is released you should install it like this instead:

easy_install -U pylons==0.9

Then create your project:

paster create --template=pylons website

Start up the development server to see what we already have:

cd website
paster serve --reload development.ini

Visit http://localhost:5000

Making Use of Pylons' template.py controller

If you look at your config/routing.py file you will see this line last:

map.connect('*url', controller='template', action='view')

If none of the other routes match the request URL the request will be dispatched to the view method of the template controller.

If you look at the template controller you will see that the view() method simply returns a 404 response:

abort(404)

This is usually what you would want, if the file cannot be found a 404 error should be raised. We are going to change this method so that Pylons checks if a suitable template can be found before raising a 404.

Understanding Eggs

Our application needs to check whether or not the URL requested can be found as a file in the templates directory. Luckily Pylons applications use the Python Eggs format so we can use pkg_resources to see if the template exists. See http://peak.telecommunity.com/DevCenter/PkgResources#basic-resource-access for full information.

Before pkg_resources can find our application we need to install it. In the project directory run this command:

python setup.py develop

This command installs the application in a development mode so that changes we make to the code are instantly available in the website package.

We can now write the code to inspect our website package to see if the template resource exists in our applications. Add this line to the top of the template.py controller to look like this:

import pkg_resources

then add this code to the view() method:

page = '/'.join(['templates',url+'.myt'])
if pkg_resources.resource_exists('website', page) \
and not pkg_resources.resource_isdir('website', page):
# avoid unicode errors with str(...)
    return render_response(str(url+'.myt'))
directory = '/'.join(['templates',url])
if pkg_resources.resource_isdir('website', directory) \
and pkg_resources.resource_exists('website', directory+'/index.myt') \
and not pkg_resources.resource_isdir('website', directory+'/index.myt'):
    return render_response(str(url.strip('/')+'/index.myt'))
abort(404)

Note that if you called your project something other than website you would need to adjust the code above accordingly.

Create a sample template named templates/test.myt which contains:

Hello World!

Then visit http://localhost:5000/test and you will see your Hello World! message displayed.

The code we wrote in templates.py will also serve an index.myt file if a directory is requested. Create a new file in the templates directory called index.myt and add the text:

This is the site homepage.

If you visit http://localhost:5000/ you will notice the old welcome message is still there. This is because the default configuration of the Cascade middleware in config/middleware is to serve static files before trying to serve files from the Pylons application.

Delete public/index.html and visit http://localhost:5000/ again. This time you should see your index page displayed.

Myghty Template Inheritance

For this simple website we are going to take advantage of Myghty template inheritance and autohandlers. http://www.myghty.org/docs/inheritance.myt Edit the autohandler file in the templates directory to look like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><& SELF:title &></title>
</head>
<body>

<& /navbar.myc, toggle=m.scomp('SELF:nav') &>

% m.call_next()

</body>
</html>

<%method title>
Simple Website
</%method>

<%method nav>Home</%method>
Note:There should be no leading spaces before the line % m.call_next() or the inheritance will not work.

You should also create a file called navbar.myc in the templates directory which contains the following:

<p>
% for link, url in [('Home','/'), ('Test','test')]:
%       if ARGS['toggle'] == link:
<a href="<% url %>"><b><% link %></b></a>
%       else:
<a href="<% url %>"><% link %></a>
%       #endif
% #endfor
</p>

Again, there should be no leading space before any of the % signs.

Now if you visit http://localhost:5000/test again you will see the navigation bar in place automatically because Myghty calles the autohandler first and then the m.call_next() code calls the test.myt file and inserts the content in its place.

In this way it is possible to create a heirachy of templates each of which add more HTML as you drill down through directories.

Changing the Title

It would be nice if the title could change in each page. Try adding this to the test.myt file at the bottom:

<%method title>
Hello Test Page
</%method>

If you visit the test page again the title will have changed. The line <& SELF:title &> we defined earlier in templates/autohandler calls the title() method of any child templates. In this case because we have defined a title method the title of the page is replaced by the value in that method, in this case, Hello Test Page.

Now try adding this instead:

<%method title>
<& PARENT:title &> : Hello Test Page
</%method>

This time when you visit http://localhost:5000/test the tite contains the title of the page above it in the hierarchy and also `` : Hello Test Page`` added to the end. This is because <& PARENT:title &> is replaced with the value of the title() method on the parent template, in this case the autohandler file.

Fixing the Navigation

In a similar way to the way we can modify the title in the child template we can also change which navigation link is selected. Add this to the test.myt file at the bottom:

<%method nav>Test</%method>

You should now find when you visit http://localhost:5000/test that the Test link is highlighted not the Home link. This is because the navbar.myc component is passed the value of the nav() method as the argument toggle. Since we have now defined the nav() method a different value is displyed.

Note that in the title() method we could put the text on multiple lines but in the nav() method defined above it all has to be on one line. This is because the extra whitespace isn't a problem between <title></title> tags but is a problem when comparing strings in navbar.myc.

Breadcrumb Trails

We can add in a breadcumb trail in a very similar way to how we achieved the title. Add this to templates/autohandler:

<%method breadcrumbs>
% return [['Home','/']]
</%method>

Then add this to test.myt at the bottom:

<%method breadcrumbs>
% a = m.comp('PARENT:breadcrumbs')
% a.append(['Hello Test Page','/test'])
% return a
</%method>

Next we need another component to render the breadcrumb trail. Create a new component templates/breadcrumbs.myc:

<p>
% counter = 0
% for link, url in ARGS['breadcrumbs']:
%       counter += 1
%       if counter == len(ARGS['breadcrumbs']):
                <a href="<% url %>"><b><% link %></b></a>
%       else:
                <a href="<% url %>"><% link %></a> &gt;
%       #endif
% #endfor
</p>

Finally we need to place the breadcrumbs into autohandler. Add the following line just above % m.call_next():

<& /breadcrumbs.myc, breadcrumbs=m.comp('SELF:breadcrumbs')&>

Visit http://localhost:5000/test again and you will see a simple breadcrumb trail.

That's it! You now have a good working basis for a website without going near a Pylons controller!

Site running on a free Atlassian Confluence Open Source Project License granted to Pylons. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.3.3 Build:#645 Feb 13, 2007) - Bug/feature request - Contact Administrators
Top