FireFox! The PHP Forum Loans and Credit
Panama Web Design for Hire Free Insurance Quotes!
Web Hosting Advertise Here $10 a Month Designer Children
Never Pay Taxes Again HGH Domain name registration
Web Hosting and Dedicated Servers Insurance Affordable web-hosting


HomeWatched TopicsRegisterSearchDirectory
FAQMemberlistUsergroupsLog inStoresItemsBank
Google

Reply to topic Page 1 of 1
Writing a Template System in PHP
Message  

Reply with quote
Post Writing a Template System in PHP 
The Implementation
I decided the best approach was to implement an object oriented programming solution. I envisioned something that would look similar to the following when implemented:

<?php
require_once("lib/template.php");

$page = new Page("template.html");

$page->replace_tags(array(
  "title" => "HOME",
  "descript" => "Welcome to my website!",
  "main" => "dat/index.dat",
  "menu" => "dat/menu.dat",
  "left" => "dat/submenu.dat",
  "right" => "dat/right.dat",
  "footer" => "dat/footer.php"
));

$page->output();
?>  

Source: http://codewalkers.com/tutorials/58/2.html

View user's profile Send private message

Reply with quote
Post  
The Template File
Before I could start scripting my templating engine I first needed a template file. Not only would the template file be the cornerstone of the entire site, but it would also dictate how the class should be written.

Though I could have chosen any set of characters to delimit my placeholders, I chose braces because they seem to be the ones most commonly used in other templating scripts. This would hopefully make template file sharing easier in the future.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html>
  <head>
    <title>{title}</title>
    <meta http-equiv="Content-Type"
          content="text/html; charset=iso-8859-1" />
    <link rel="stylesheet" href="css/mystyles.css"
          type="text/css" />
  </head>
  <body>
    <div id="banner">
      <img src="images/logo.png" alt="Main Logo" />
      <div id="menubar">
        {menu}
      </div>
    </div>
    <div id="leftcol">
      {left}
    </div>
    <div id="rightcol">
      {right}
    </div>
    <div id="main">

      {main}
    </div>
    <div id="footer">
      {footer}
    </div>
  </body>
</html>  

Source: http://codewalkers.com/tutorials/58/3.html

View user's profile Send private message

Reply with quote
Post  
The Class Skeleton
Now armed with the knowledge of how template files would be structured and how I wanted the interface to look, I could start constructing the skeleton of the class:

<?php
class Page
{
  var $page;

  function Page($template) {

  }

  function replace_tags($tags) {

  }

  function output() {

  }
}
?>  


The array $tags is keyed using the place holders and its values are the corresponding replacement data. The variable $page is used to store the page as it's being generated.

Source: http://codewalkers.com/tutorials/58/4.html

View user's profile Send private message

Reply with quote
Post  
Constructor and Output
I went back to write the class's constructor.

<?php
function Page($template = "template.html") {
  if (file_exists($template))
    $this->page = join("", file($template));
  else
    die("Template file $template not found.");
}
?>  


I like to allow for default arguments to the methods I write when it makes sense to do so. In this case the default template file is template.html, but it can always be overridden by simply passing the name of another file to the constructor.

I needed to first check to see if the template file existed. If it did then I could load it into memory. If it didn't then there was nothing I could do so I killed the script and sent a nice error message to the user.

Then I turned my attention to the output method, the code of which should be pretty self-explanatory.

<?php
function output() {
  echo $this->page;
}
?>  

Source: http://codewalkers.com/tutorials/58/5.html

View user's profile Send private message

Reply with quote
Post  
Replacing Tags
Next came time to write the workhorse method of the class, the replace_tags method.

<?php
function replace_tags($tags = array()) {
  if (sizeof($tags) > 0)
    foreach ($tags as $tag => $data) {
      $data = (file_exists($data)) ? join("", file($data)) : $data;
      $this->page = eregi_replace("{" . $tag . "}", $data,
                    $this->page);
    }
  else
    die("No tags designated for replacement.");
}
?>  


The method accepts an incoming array of references to replacement data keyed by place holder. A foreach statement cycles through the array.

With each iteration of the foreach, a check is made to see if the value is a filename. If it is then the file's contents is loaded as the replacement data; if it isn't then it's assumed the data was passed as straight text. This allows the method to be a bit more flexible for the end user.

Once it's determined what the replacement data is, the placeholders (along with it's delimiters) are swapped out with the corresponding information. While ereg_replace might be more appropriate, I chose to allow for case insensitivity again as a convenience factor.

Source: http://codewalkers.com/tutorials/58/6.html

View user's profile Send private message

Reply with quote
Post  
Including Dynamic Files
At this point the class is sufficient to template plain text and HTML files, but a greater level of functionality might be desired. For example, what if the user wanted to insert a footer section that contains dynamic data such as the date or page address? It would definitely be nice if the templating script would make allowances for other script files.

I modified replace_tags to pass data that validates as a file name off to a private function.

<?php
function parse($file) {
  ob_start();
  include($file);
  $buffer = ob_get_contents();
  ob_end_clean();
  return $buffer;
}

function replace_tags($tags = array()) {
  if (sizeof($tags) > 0)
    foreach ($tags as $tag => $data) {
      $data = (file_exists($data)) ? $this->parse($data) : $data;
      $this->page = eregi_replace("{" . $tag . "}", $data,
                    $this->page);
      }
  else
    die("No tags designated for replacement.");
}
?>  


Parse accepts the name of a file and includes its contents (include will processes any PHP directives found within the file). Output buffering is used to store the processed data so we can return it and prevents the included file from being sent to standard output prematurely.

Source: http://codewalkers.com/tutorials/58/7.html

View user's profile Send private message

Reply with quote
Post  
The Final Code
Now the templating script is finished. I can store the code in a separate file and reference it when needed.

<?php
class Page
{
  var $page;

  function Page($template = "template.html") {
    if (file_exists($template))
      $this->page = join("", file($template));
    else
      die("Template file $template not found.");
  }

  function parse($file) {
    ob_start();
    include($file);
    $buffer = ob_get_contents();
    ob_end_clean();
    return $buffer;
  }

  function replace_tags($tags = array()) {
    if (sizeof($tags) > 0)
      foreach ($tags as $tag => $data) {
        $data = (file_exists($data)) ? $this->parse($data) : $data;
        $this->page = eregi_replace("{" . $tag . "}", $data,
                      $this->page);
        }
    else
      die("No tags designated for replacement.");
  }

  function output() {
    echo $this->page;
  }
}
?>  


After initializing the object with the name of the HTML template file, pass an array of place holders found within the template and the data files or information to the replace_tags method and use the output method to flush the processed page from the class to standard output.

<?php
require_once("lib/template.php");

$page = new Page("template.html");

$page->replace_tags(array(
  "title" => "HOME",
  "descript" => "Welcome to my website!",
  "main" => "dat/index.dat",
  "menu" => "dat/menu.dat",
  "left" => "dat/submenu.dat",
  "right" => "dat/right.dat",
  "footer" => "dat/footer.php"
));

$page->output();
?>  

Source: http://codewalkers.com/tutorials/58/8.html

View user's profile Send private message

Reply with quote
Post  
Tricks
One example of just how powerful the class can be and just how easy it can make development is using it to highlight a menu's link to the active page.

Place a style declaration similar to the following within the template's head section:

<style type="text/css">
  #{activemenu} {color: red; font-weight: bold;}
</style>  


The menu file would contain similar id attributes within its markup:

<a href="link1.php" id="menuItem1">link 1</a>
<a href="link2.php" id="menuItem2">link 2</a>
<a href="link3.php" id="menuItem3">link 3</a>
<a href="link4.php" id="menuItem4">link 4</a>  


The active link would then be highlighted by passing the appropriate id value to replace the activemenu tag found in the template file:

<?php
replace_tags(array(
  "menu" => "dat/menu.dat",
  "activemenu" => "menuItem3"
));
?>  


The templating class may be only 35 lines of code or so, but has limitless, untapped potential.

Source: http://codewalkers.com/tutorials/58/9.html

View user's profile Send private message
Display posts from previous:
Reply to topic Page 1 of 1
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
  



Google

FireFox! The PHP Forum Loans and Credit
Panama Web Design for Hire Free Insurance Quotes!
Web Hosting Advertise Here $10 a Month Designer Children
Never Pay Taxes Again HGH Domain name registration
Web Hosting and Dedicated Servers Insurance Affordable web-hosting


Web Design by PlatinumShore.com & Web Hosting by TradeWebHosting.com