PHP
  Home arrow PHP arrow Simple Dynamic Templating for Small Sites ...
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
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? 
PHP

Simple Dynamic Templating for Small Sites Using PHP
By: Daryl Houston
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 9
    2003-05-01

    Table of Contents:

    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


    Let Daryl help you help your users. In this article, Daryl provides PHP code to help your users to navigate through your website and knowing exactly where they are at all times. Read more ...

    One of the simplest but most important Web interface necessities is always letting the user know where he or she is within your site.  This is most often done using visual cues such as highlighted navigation items, which often match the rollover states of the navigation items. 

    While many content management systems and application frameworks have this sort of functionality built in, these code bases are overkill for simple sites.  You don't need Broadvision or Vignette or even any of the Nuke permutations for a 5-10 page brochure site.

    Arguably, maintaining such a brochure site requires little enough effort that a templating system isn't even necessary, but I always find it preferable to have one set of templates to maintain.  Setting your site up in this manner ensures consistency across pages, and consistency is as important for a small site as for a gargantuan portal (and maybe moreso).

    Let's start with some assumptions for our first example.  We're working on a 5-page Web site containing pages for home, about, contact, products, and services.  All files for the purposes of this example are in the document root directory, and they all share the basic site template.  In the navigation, whenever you mouse over any of the five navigation items, the rollover graphic changes colors. 

    What we wish to accomplish is having the appropriate navigation item for each page highlight automatically when a visitor loads the page.  Since this is simplified templating, we've got a top.php, a bottom.php, and a file containing content for each of the five pages.  The top and bottom templates contain all the graphical elements and tables that form the design of the site.  And each of the content pages encloses its content with php tags to include top.php and bottom.php. 

    I'm also making the assumption that for each navigation item, if the default image name is "image.jpg," the rollover state image name will be "image1.jpg."

    At the top of top.php, you'll want to include the following block, substituting your page names and domain:

    <?php
     $root="
    http://www.yourdomain.com
    ";
     $server_path="/full/path/to/document_root";
     $path=split("/",$_SERVER["REQUEST_URI"]);
     $path=array_reverse($path);
     if(eregi("index.php",$path[0]) || $path[0]=="")
     {
      $home=1;
     }
     elseif(eregi("about.php",$path[0]))
     {
      $about=1;
     }
     elseif(eregi("contact.php",$path[0]))
     {
      $contact=1;
     }
     elseif(eregi("products.php",$path[0]))
     {
      $products=1;
     }
     elseif(eregi("services.php",$path[0]))
     {
      $services=1;
     }
    ?>

    We're taking the request URI and splitting on / in order to get the components of the URL.  Then we reverse the components so that we can crawl the array from left to right (or 0 to n if you prefer to think of it that way) and determine what page has been requested. 

    The first array element represents the page requested, and subsequent elements represent any subdirectories, the domain, and some extra junk that we'll never need.  Since we're assuming all files are in the document root, this reversal isn't so important, but once we look at descending into directories, reversing the array just makes the process a little easier. 

    We could use PHP's parse_url() function here, but if we were descending into directories, we'd then have to split and parse the path element manually anyway, so I just manually parse the URL to start with.

    Once we've got our URL parsed, we process the components by going into an if block and performing the eregi() function for each of our possible page names.  I use eregi() because my first use of this little tool was for a site that sometimes had query strings to parse.  If we use eregi() rather than the == operator, query strings don't necessarily affect our results -- we're looking for a minimum of the passed string in the URL component. 

    In other words, to eregi(), "contact.php" and "contact.php?subject=Advertising" both evaluate to true.  You do have to be careful about naming pages when using this script, however.  For example, if you had a page named "sales_contact.php" and another named "press_contact.php," both would evaluate to true in the third elseif above and thus both would have the $contact variable set to 1. 

    If you want the same nav to be highlighted for both, this is a bonus.  If you want different nav to be highlighted for each, you'll need to make sure you pass "sales_contact.php" and "press_contact.php" to the if block separately and set separate variables for each page.

    What we're doing in the code chunk above is setting a bunch of flags.  Now we have to use those to affect the navigation.  I tend to use DreamWeaver's rollover functions to do my navigation, so the code sample displayed below -- a table row containing my nav -- makes use of those functions.  Obviously, you can modify this to suit your needs.  The principle behind the navigation swap will remain the same regardless of the implementation.

    <tr>
     <td align="left" valign="top" bgcolor="#000000">
      <a href="<?php echo $root; ?> /index.php"
         onMouseOut="MM_swapImgRestore()" 
         onMouseOver="MM_swapImage('home','','<?php echo $root; ?> /images/home1.gif',1)">
         <img border="0"
             src="<?php echo $root; ?>/images/home<?php echo $home; ?>.gif"
             alt="Home" name="home">
      </a>
     </td>
     <td align="left" valign="top" bgcolor="#000000">
      <a href="<?php echo $root; ?>/about.php"
         onMouseOut="MM_swapImgRestore()"
         onMouseOver="MM_swapImage('about','','<?php echo $root; ?>/images/about1.gif',1)">
         <img border="0"
              src="<?php echo $root; ?>/images/about<?php echo $about; ?>.gif"
              alt="About" name="about">
      </a>
     </td>
     <td align="left" valign="top" bgcolor="#000000">
      <a href="<?php echo $root; ?>/contact.php"
         onMouseOut="MM_swapImgRestore()"
         onMouseOver="MM_swapImage('contact','','<?php echo $root; ?>/images/contact1.gif',1)">
         <img border="0"
              src="<?php echo $root; ?>/images/contact<?php echo $contact; ?>.gif"
              alt="Contact" name="contact">
      </a>
     </td>
     <td align="left" valign="top" bgcolor="#000000">
      <a href="<?php echo $root; ?>/products.php"
         onMouseOut="MM_swapImgRestore()"
         onMouseOver="MM_swapImage('products','','<?php echo $root; ?>/images/products1.gif',1)">
         <img border="0"
              src="<?php echo $root; ?>/images/products<?php echo $products; ?>.gif"
              alt="products" name="products">
      </a>
     </td>
     <td align="left" valign="top" bgcolor="#000000">
      <a href="<?php echo $root; ?>/services.php"
         onMouseOut="MM_swapImgRestore()"
         onMouseOver="MM_swapImage('services','','<?php echo $root; ?>/images/services1.gif',1)">
         <img border="0" src="<?php echo $root; ?>/images/services<?php echo $services; ?>.gif"
              alt="Services" name="services">
      </a>
     </td>
    </tr>

    The thing to look for in each table cell definition above is the snippet that echoes the flags set in the if block.  Toward the end of the line in the first table cell, for example, you see the following:

    <img border="0"
           src="<?php echo $root; ?>/images/home<?php echo $home; ?>.gif"
           alt="Home" name="home">

    Initially, we're setting the image source to "home.gif," since by default, the $home variable has no value to print out.  If the $home flag was set to 1 in the if block above, however, when we echo the variable, we echo a 1, thus changing the image source to "home1.gif."  And voila -- the URL sniffer has determined that we're on the home page and has highlighted the appropriate nav so that visitors always know what site section they're in.

    Now, imagine we've got a slightly more complex site with some files in the document root and some in subdirectories.  The principle is the same, but the if block is a little more complex.

    <?php
     if(eregi("about",$path[1])
     {
      $about=1;
      if(eregi("company.php",$path[0]))
      {
       $about_company=1;
      }
      elseif(eregi("people.php",$path[0]))
      {
       $about_people=1;
      }
     }
     elseif(eregi("products",$path[1])
     {
      $products=1;
      if(eregi("hats.php",$path[0]))
      {
       $products_hats=1;
      }
      elseif(eregi("coats.php",$path[0]))
      {
       $products_coats=1;
      }
     }
     elseif($path[1]=="")
     {
      if(eregi("index.php",$path[0]))
      {
       $home=1;
      }
      elseif($path[0]=="")
      {
       $home=1;
      }
      elseif(eregi("about.php",$path[0]))
      {
       $about=1;
      }
      elseif(eregi("contact.php",$path[0]))
      {
       $contact=1;
      }
      elseif(eregi("products.php",$path[0]))
      {
       $products=1;
      }
      elseif(eregi("services.php",$path[0]))
      {
       $services=1;
      }
     }
    ?>

    In this example, we're looking at the second component of the path -- which, since we reversed the array above, represents the directory of the file being requested -- to get the current subdirectory, and we're setting the appropriate flag to 1.  Then we're entering a nested if block that checks the first path component to see which page within a given subsection the visitor is currently browsing. 

    So if the URL is
    http://www.yourdomain.com/about/company.php, then the $about flag and the $about_company flag will be set to 1.  We can use these flags in our nav and our subnav to highlight the current section and page.  You can see here the value of reversing the $path array. 

    Doing so allows us to move from left to right (or 0 to n) in the array; not doing so would require us to use code more along the lines of:

    if(eregi("about",$path[sizeof($path)-2))
    {
      //do stuff;
    }

    Such code is certainly doable, but it's harder to read and debug.

    If you're using subnav and sub-subnav, depending upon what your site template looks like, you may wish to add some complexity to the way your top and bottom templates are built, but it's nothing our little script can't handle.  If you're displaying all subnav on all pages, you simply print out all nav in your main include templates, but suppose you wish to restrict the display of subnav. 

    For example, imagine that you wish to display subnav for the about section only on pages that pertain to the about section.  The first step would be to break your about subnav out into a separate include file.  I imagine the include would look something like the following:

    <table>
     <tr>
      <td align="left" valign="top" bgcolor="#000000">
       <a href="<?php echo $root; ?>/about/company.php"
          onMouseOut="MM_swapImgRestore()"
          onMouseOver="MM_swapImage('about_company','','<?php echo $root; ?>/images/about_company1.gif',1)">
          <img border="0" src="<?php echo $root; ?>/images/about_company<?php echo $about_company; ?>.gif"
          alt="Company" name="about_company">
       </a>
      </td>
     </tr>
     <tr>
      <td align="left" valign="top" bgcolor="#000000">
       <a href="<?php echo $root; ?>/about/people.php"
          onMouseOut="MM_swapImgRestore()"
          onMouseOver="MM_swapImage('about_people','','<?php echo $root; ?>/images/about_people1.gif',1)">
          <img border="0" src="<?php echo $root; ?>/images/about_people<?php echo $about_people; ?>.gif"
               alt="People" name="about_people">
       </a>
      </td>
     </tr>
    </table>

    Note that the variable names here correspond to those in the main if block.  Provided the if block is evaluated before the include is processed, the variables should pass through, and this code should work as well as the main nav code.  In order to determine whether or not to display the subnav, you'd simply add the following line to your template in the appropriate spot (presumably right underneath the main about navigation graphic:

    <?php
    if($about==1)
    {
     include "about.inc.php";
    }
    ?>

    If you start using subnav and subdirectories, you'll want to be careful about how you include files.  The block above will work fine provided "about.inc.php" can be located in the current directory.  But what if it's not?  I usually add a line like

    $server_path="/full/path/to/document_root";

    to the top of my file (you'll see it in the first code sample given above).  Using this variable in conjunction with any include statements will guarantee that any time you're including a file, you're doing so with an absolute path, preventing ugly errors as a result of relative path issues.

    Even for sites whose scope is broader than a 5-10 page online brochure, this little trick can be a handy tool for developers who want a quick solution for building a simple template-driven site without all the overhead and headache of a more involved system. 

    Objections might be raised that since variables are being hard coded into the template and must correlate with variables hard-coded in the main if block, this system is inelegant and not, strictly speaking, dynamic. 

    For my purposes, at any rate, it has proven a useful way of maintaining consistency across small-to-mid sized sites without having to hard code graphics references in static pages sitewide and without having to resort to some of the more beastly systems that can require more work up front and more difficult maintenance throughout the life of the site.


    DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

    More PHP Articles
    More By Daryl Houston

     

    IBM® developerWorks developerWorks - FREE Tools!


    Check out the new Jazz space on developerWorks

    <a href="http://zeus.developershed.com/shonuff.php?blackbird=3853&zoneid=442&source=&dest=http%3A%2F%2Fwww.ibm.com%2Fdeveloperworks%2Fspaces%2Fjazz%3FS_TACT%3D105AGY31%26S_CMP%3DDEVSHED&ismap="><img src="http://images.devshed.com/corp/img/news/jazz01.gif" alt="developerWorks Jazz space" align="left"></a>You've heard the buzz about Jazz... want to know more about it from a developer's perspective? Check out the Jazz space on developerWorks. This space is an up-to-date resource for developers, including technical information about Jazz and products built on Jazz, like Rational Team Concert Express. The Jazz space includes content from a wide variety of sources, including links, feeds, and comments from experts.
    FREE! Go There Now!


    IBM DB2 Deep Compression ROI Tool

    The IBM DB2 Deep Compression ROI tool is designed for DBA’s and IT management personnel to perform a clinical analysis of the cost savings gained from the Storage Optimization feature of DB2 9 for Linux, UNIX and Windows. The feature, also known as Deep Compression, compresses data that lies within a database by up to 80% at times.
    FREE! Go There Now!


    NEW! Best Practices: The Integrated Project and Portfolio Management Platform.

    Hear how IBM Rational Project and Portfolio Management integrated solutions help teams put the right tools and processes in place to maximize the effectiveness and efficiency of project teams and ensure that the business vision is being executed correctly. Learn how to automate and integrate requirements prioritization, top-down project planning, communications and controls, and methodology deployment to keep your scope, costs, and schedules under control. Tackle with an end-to-end approach the management of scope and scope changes, usage of methodology to control and empower project teams, and optimization of resources to align activity costs with the overall project plan.
    FREE! Go There Now!


    NEW! Applying lean thinking to the governance of software development

    Effective governance for lean development isn’t about command and control. Instead, the focus is on enabling the right behaviors and practices through collaborative and supportive techniques. Hear from Scott Ambler on how it is far more effective to motivate people to do the right thing than it is to force them to do so. Learn how to form a lightweight, collaboration-based framework that reflects the realities of modern IT organizations.
    FREE! Go There Now!


    NEW! Download DB2 9.5 for Linux, Unix, and Windows

    Download a free trial version of IBM DB2 9.5 for Linux, UNIX, and Windows. DB2 9 is the result of a five-year development project that transformed traditional (static) database technology into an interactive data server that merges the high performance and ease of use of DB2 with the self-describing benefits of XML.
    FREE! Go There Now!


    NEW! Evaluate Rational Host Access Transformation Services (HATS) Toolkit V7.1

    Visit IBM developerWorks to download a free trial of the Rational Host Access Transformation Services (HATS) Toolkit. The HATS toolkit provides a set of plug-ins for the IBM Rational Software Delivery Platform to help you easily extend your legacy applications. HATS makes your 3270 and 5250 applications available as HTML through the most popular Web browsers, while converting your host screens to a Web look and feel and it also enables you to develop new Web, portal, and rich-client applications.
    FREE! Go There Now!


    NEW! Innovate don't duplicate! Asset reuse strategies for success

    Asset Reuse is a key strategy for companies looking to create innovative solutions to solve complex software development problems. Searching for, identifying, updating, using and deploying software assets can be a difficult challenge. Listen to this webcast, to learn about strategies and tools that you can leverage for a successful project, including Rational Asset Manager, Rational Software Architect and WebSphere Service Registry and Repository.
    FREE! Go There Now!


    NEW! Rational Modeling Extension for Microsoft.Net

    Rational Modeling Extension for Microsoft .NET enhances usability for code generation supporting a more intelligent refactoring. The latest enhancements enable organizations with Java and .NET systems and software development maintain architectural integrity across heterogeneous platforms.
    FREE! Go There Now!


    NEW! Rational Talks to You: Manage RUP-based CMMI initiatives

    Join this Rational Talks to You teleconference on December 4 at 1:00 pm ET to discuss how Rational Method Composer can help meet your compliance objectives. Get your questions answered!
    FREE! Go There Now!


    NEW! Webcast: Extreme transaction processing with WebSphere Extended Deployment

    In this webcast, you'll get an introduction to the eXtreme Transaction Processing (XTP) features of WebSphere Extended Deployment and the common architectural traits required by XTP applications. See how WebSphere Extended Deployment's ObjectGrid feature provides a state-of-the-art infrastructure for hosting XTP applications.
    FREE! Go There Now!



    All FREE IBM® developerWorks Tools!

    PHP ARTICLES

    - Making Usage Statistics in PHP
    - Installing PHP under Windows: Further Config...
    - File Version Management in PHP
    - Statistical View of Data in a Clustered Bar ...
    - Creating a Multi-File Upload Script in PHP
    - Executing Microsoft SQL Server Stored Proced...
    - Code 10x More Efficiently Using Data Access ...
    - A Few Tips for Speeding Up PHP Code
    - The Modular Web Page
    - Quick E-Commerce with PHP and PayPal
    - Regression Testing With JMeter
    - Building an Iterator with PHP
    - PHP Frontend to ImageMagick
    - Using PEAR's mimeDecode Module
    - Incoming Mail and PHP







    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 1 Hosted by Hostway
    For more Enterprise Application Development news, visit eWeek