Perl
  Home arrow Perl arrow Page 11 - Building a Complete Website using the ...
Dev Shed Forums 
Administration  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Forums Sitemap 
IBM® developerWorks 
Dedicated Servers 
E-Commerce Hosting 
Linux Web Hosting 
Managed Hosting 
Small Business Hosting 
Download TestComplete 
VPS Hosting 
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
PERL

Building a Complete Website using the Template Toolkit
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 29
    2004-09-15

    Table of Contents:
  • Building a Complete Website using the Template Toolkit
  • A “Hello World” HTML Template
  • Benefits of Modularity
  • Loading the Configuration Template
  • Creating a Project Directory
  • A Place for Everything, and Everything in Its Place
  • Adding Headers and Footers Automatically
  • More Template Components
  • Setting Default Values
  • Wrapper and Layout Templates
  • Using Layout Templates
  • Menu Components
  • Structured Configuration Templates
  • Layered Configuration Templates
  • Assessment

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
     
    ADVERTISEMENT

    Dell PowerEdge Servers

    Building a Complete Website using the Template Toolkit - Using Layout Templates
    (Page 11 of 15 )

    Most real web sites will require far more complex layout templates than the simple wrapper we saw in Example 2-16. A common practice is to use HTML tables to place different elements such as headers, footers, and menus in a consistent position and formatting style. These elements may themselves be built using tables and other HTML elements, perhaps nested several times over. This can quickly lead to confus ing markup that is hard to read and even harder to update.

    Consider the following example, which illustrates how difficult nested tables can be to write and maintain:

    <table border="0" cellpadding="0" cellspacing="0">
      <tr valign="top">
        <td>
          <table border="0">
            <tr>
              <td>
                Oh Dear!
              </td>
              <td>
                This is not a good example
                of a layout template...
              </td>
              <td>
                <table>
                  ...etc...
                </table>
              </tr>
            </table>
          </td>
          <td>
            <table>
              ...etc...
            </table>
          </td>
          .
          .
          .

    The sensible formatting helps to make the structure clearer through use of indenting. However, it is still difficult to match rows and cells with their correspondingn tables, and there is little indication of what the different tables contribute to the overall layout.

    A better approach is to build the layout using several different templates. For example, we can simplify the preceding template by moving the inner tables to separate
    templates:

    <table border="0" cellpadding="0" cellspacing="0">
      <tr valign="top">
      <td>
        [% PROCESS sidebar %]
      </td>
      <td>
        [% PROCESS topmenu %]
      </td>
      .
      .
      .

    Now we can easily see the high-level structure without getting bogged down in the detail of the nested tables. Furthermore, by giving our templates names that reflect their purpose (e.g., sidebar and topmenu), we effectively have a self-documenting template that shows at a glance what it does. Another benefit is that the individual elements, the sidebar and topmenu in this example, will themselves be much easier to write and maintain in isolation. They also become reusable, allowing you to incorporate them into another part of the site (or perhaps another site) with a PROCESS or similar directive.

    Layout Example

    Let’s work through a complete example now, applying this principle to the presentation framework for our web site. Example 2-17 shows an alternate version of the wrapper template that delegates the task to two further templates, html and layout.

    Example 2-17. lib/wrapper2

    [% WRAPPER html + layout;
         content;
       END
    -%]

    The two wrapper templates, html and layout, are both specified in the one WRAPPER directive, separated using the + character in the same way that we used it with the PROCESS directive in Example 2-9. In this case, the page content will be processed first, then the layout template, and finally the html template. Remember that the
    WRAPPER directive works “inside out” by processing the wrapped content first, and then the wrapping templates.

    If we unwrap the preceding directive into two separate WRAPPER calls, it should become more obvious why the WRAPPER directive processes the templates in the reverse order to how they’re specified:

    [% WRAPPER html;
        WRAPPER layout;
          content;
        END;
      END
    %]

    The end result is that it does what you would expect, regardless of the slightly counterintuitive order in which it does it. The html template ends up wrapping the layout template, which in turn wraps the value of the content variable, which in this case is the output from processing the main page template.

    Side-effect wrappers

    The WRAPPER directive can also be used in side-effect notation. Consider the following fragment:

    [% WRAPPER layout;
         content;
       END
    %]

    You can simplify this by writing it as follows:

    [% content WRAPPER layout %]

    The wrapper template shown in Example 2-17 can be rewritten in the same way, as shown in Example 2-18.


    Example 2-18. lib/wrapper3

    [% content WRAPPER html + layout -%]

    Separating layout concerns

    Using two separate layout templates, html and layout, allows us to make a clear separation between the different kinds of markup that we’re adding to each page. The html template adds the <head> and <body> elements required to make each page valid HTML. The layout template deals with the overall presentation of the visible page
    content, adding a header, footer, menu, and other user interface components.

    Example 2-19 shows the html template.

    Example 2-19. lib/html

    <html>
      <head>
        <title>[% author %]: [% template.title %]</title>
      </head>

      <body bgcolor="[% bgcol %]">
        [% content %]
      </body>
    </html>

    Example 2-20 shows the layout template.

    Example 2-20. lib/layout

    <table border="0" width="100%">
      <tr>
        <td colspan="2">
          [% PROCESS pagehead %]
        </td>
      </tr>
      <tr valign="top">
        <td width="150">
          [% PROCESS menu %]
        </td>
        <td>
          [% content %]
        </td>
      </tr>
      <tr>
        <td colspan="2" align="center">
          [% PROCESS pageinfo %]
        </td>
      </tr>
    </table>

    We’ve created a new header template, pagehead, shown in Example 2-21, which generates a headline for the page. It’s simple for now, but we can easily change it to something more complicated at a later date.

    Example 2-21. lib/pagehead

    [% template.title %]

    We’re also using another template, menu, to handle the generation of a menu for the site. We’ll be looking at this shortly.

    Example 2-22 shows the final template used in the layout, pageinfo. This incorporates the copyright message and some information about the page template being processed.

    Example 2-22. lib/pageinfo

    [% USE Date %]

    &copy; [% copyr %]

    <br />

    [% template.name -% ]
    last modified
    [%- Date.format(template.modtime) %]

    Notice how we’re using the template.name and template.modtime variables to access the filename and modification time of the current page template. The template.modtime value is returned as a large number that means something to computers* but not a great deal to humans. To turn this into something more meaningful, we’re using the Date plugin to format the number as a human-readable string.

    Plugins and the USE directive

    Plugins are a powerful feature of the Template Toolkit that allow you to load and use complex functionality in your templates, but without having to worry about any of the underlying implementation detail. Plugins are covered in detail in Chapter 6, but there’s not much you need to know to start using them.

    In Example 2-22, we first load the Date plugin with the USE directive:

    [% USE Date %]

    This creates a Date template variable that contains a reference to a plugin object (of the Template::Plugin::Date class, but you don’t need to know that). We can then call the format method against the Date object using the dot operator, passing the value for template.modtime as an argument:

    [%- Date.format(template.modtime) %]

    The output generated would look something like this:

    17:43:35 14-Jul-2003

    * It’s the number of seconds that have elapsed since January 1, 1970, known as the the Unix epoch.

    That’s all we need to do to load and use the Date plugin. Dozens of plugins are avail able for doing all kinds of different tasks, described in detail in Chapter 6. 

    Buy the book!If you've enjoyed what you've seen here, or to get more information, click on the "Buy the book!" graphic. Pick up a copy today!

    Visit the O'Reilly Network http://www.oreillynet.com for more online content.

       

    PERL ARTICLES

    - Perl: A Continuing Look at Hashes and Multid...
    - Perl: Another Round with Hashes
    - Perl Hashes
    - Perl Lists: A Final Look at List::Util
    - Perl Lists: Utilizing List::Util
    - Perl Lists: The Split() Function
    - SQL and CGI with Perl and DBI
    - Perl Lists: More Functions and Operators
    - SELECT Queries and Perl
    - Perl Lists: More on Manipulation
    - Creating a Database with Perl and DBI
    - Perl: Sailing the List(less) Seas
    - Perl and DBI
    - Perl: Concatenating Text and More
    - Perl Text: Quoting Without Quote Marks

     
    Accelerating Trading Partner Performance
     
    Competing on Analytics
     
    Cost Effective Scaling with Virtualization and Coyote Point Systems
     
    Five Checkpoints to Implementing IP Telephony
     
    Hosted Email Security: Staying Ahead of New Threats
     




    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 4 hosted by Hostway