Latest Version: 0.9.6.2
  Dashboard > Pylons Cookbook > ... > Getting Started > An Approach For Planning the Structure of a Pylons Application
  Pylons Cookbook Log In | Sign Up   View a printable version of the current page.  
  An Approach For Planning the Structure of a Pylons Application
Added by James Gardner, last edited by Mark Christian Jones on Aug 28, 2007  (view change) show comment
Labels: 
(None)

Name Space Section Page Version Status Reviewed Author(s)
An Approach For Planning the Structure of a Pylons Application Pylons Cookbook Home An Approach For Planning the Structure of a Pylons Application 1.0 Draft False James Gardner

Introduction

Once you have read the Pylons book you will be in a good position to understand the various parts of a Pylons application and how the different components work together. This article aims to provide an approach for analyzing the requirements of a site you wish to implement in Pylons and then organising the routes, controllers and templates in the most appropriate fashion. It won't cover the details of how you go on to create your implementation since this is already covered in the Pylons book.

Create Mockups

The first step in the production of any site is to create mockups of each of the main web pages either on paper or with a graphics package. This enables you to think through how the site will look, what navigation structures are necessary and whether or not the design and information architecture you have created adequately allows the users of your site to achieve the tasks the site is designed for.

Once you have a rough idea of how the site will look it is normally a good idea to implement the main screens as static HTML pages in such that you can click through all the pages in the same way a user might in your final site. You can create these pages in an empty directory without using any Pylons code yet.

Creating a draft HTML implementation might seem like unnecessary effort at first because you will re-implement Pylons versions of the pages later with a proper templating structure but the reality is that it is much quicker to draft representative static HTML pages than to create all the final Pylons versions so the initial investment of time is well worth it to avoid costly re-implementation later on. The HTML you use for the draft implementation can also be reused in the templates later on.

If you have created your main screens you should be able to click through them all in the same way a user would to ensure that you have properly thought out the URL structure and that any links contain the correct entity IDs and other information that your application will eventually need in order to generate that page. You should try to ensure the URLs are structured in a neat and logical fashion that will make sense to the users of the application. A rule of thumb to is that If you have a good URL structure it should be possible for your users to navigate the new site by editing the URLs.

Decide on the Controllers

Once you have tested your HTML implementation (and held any preliminary user testing sessions to ensure it performs as you expect) you should make a list of all the key URLs that are being used remembering to include any variables which need to be passed around the application. From this list of URLs it should become clear which controllers you need to create in order to handle all the URLs.

You will probably want to have a controller for each main section of the site. If you are creating a site for editing tables of data in databases you should create a controller for each table. A default Pylons project will already come with the controllers view.py and error.py so you can't create controllers with these names.

Now that you have decided which controllers you need you should go ahead and can create them together with the routes you will need to map your URL structure to the controllers.

Plan The Templates 

Pylons uses Mako by default for templating and Mako features powerful inheritance tools which make the structuring of a site much easier. In order to benefit from the inheritance facilities it is important to plan out your inheritance structure carefully.

Look at all your mockups and try to identify the minimum number of top level templates you are going to need. A top level template is a template which defines certain parts of a page which will be present in all the child templates. If all your pages have a common header or footer you will probably only need one top level template which will define the header or footer whereas if you have many different pages which don't share any structure you will need more than one.

For each top level template you will need to create regions which will be overridden in the child templates. Decide how many regions each top level template needs and implement empty function calls for them. For example, our top level template named header_and_footer.tmpl to define the header and footer might have just one region and look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<html>
<head><title>Sample Page</title></head>
<body>
<p>This is the header</p>
${self.content()}
<p>This is the footer</p>
</body>

<%def name="content()">
<p>This content will be overridden in the derived class</p>
</%def>

Now if you can implement your two column layout template named two_col.tmpl like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<%inherit file="header_and_footer.tmpl" />

<%def name="content()">
<table border="0">
<tr>
<td>${left()}</td>
<td>${right()}</td>
</tr>
</table>
</%def>

<%def name="left()">
<p>This is the left content which should be overridden in the child template</p>
</%def>

<%def name="right()">
<p>This is the right content which should be overridden in the child template</p>
</%def>

Once you have created an inheritance structure so that you have templates capable of being used to display each of the pages in your mockups you can structure them into a directory structure that mirrors the inheritance structure.

Once you have your inheritance structure defined, you need to look for regions that are very similar amongst lots of pages but with minor differences which could be implemented using components. For example, navigation structures might produce very similar output on different pages but with different links highlighted depending on the location of the page in the site. You wouldn't want to have to create a new template for each slight variation of the navigation region so you create a component.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<%def name="nav(highlight)">
<ul>
    % for section in ['Home', 'About', 'Contact']:
        % if section == highlight:
	    <li class="highlight">${section}</li>
	% else:
            <li>${section}</li>
        % endif
    % endfor
</ul>
</%def>

Now that we have defined all our inheritance structure and components we can create the actual templates which will be called by the Pylons controllers:

1
2
3
<%inherit file="two_col.tmpl">
<%def name="left()">${nav('Home')}</%def>
<%def name="right()"><p>This is the homepage!</p></%def>

As you can see once the inheritance structure is set up it is very easy to create quite complex pages simply by inheriting your new template from an existing one and overriding certain regions as appropriate.

Directory Structure For Templates

Now that we have all the templates we need it is worth structuring them in a logical structure on the filesystem. I like to do so like this:

- pylonsapp
    - templates
        - base
        - component
        - derived

The base directory should contain your inheritance structure with derived classes always in the directory level below the templates they derive from. Templates can be called index.tmpl if there is no other natural name for them.

The component directory contains useful components to be used by the base and derived templates.

The derived directory should contain the templates which will actually be called by your Pylons controllers and contain the content. Typically these templates will be implementations of the base templates and will contain all the logic that will generate the controller-specific content. I like to structure templates in this directory based on the controller and action which uses them.

Summing Up

Hopefully I've demonstrated a useful way of planning on how a Pylons application is structured based on the URLs it uses and the layout structure of the pages. Keeping templates in the inheritance chain separate from both components and those that are called from controllers helps keep things under control.

Any comments would be gratefully received.

With pylons 0.9.5 (perhaps due to mako changes?) to make the component work, after making the component file named nav.txt the actual template file needs to have a namespace import and modify the function call accordingly:

...
<%namespace name="ns_nav" file="nav.txt"/>
<%def name="left()">${ns_nav.nav('Home')}</%def>
...

Also change the two_col_template calls from

${left()} and ${right()}

to

${self.left()} and ${self.right()}
Posted by Marco De Felice at Aug 09, 2007 14:09 | Permalink
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