Monday, September 21, 2009

Template Driven PHP Architecture

Introduction

Much thought went into writing the first line of this article. I thought about a lot of things to say that would probably sound smart or at least vaguely intelligent--then I thought better if it. You are here to learn about templating, aren't you? Let's get right to it then.

What I am confronted with every day is the clash between designers and developers. This is more of a metaphorical one than a real thing, but it exists. The problem is that the two worlds cannot meet on solid ground.

The designer thinks in terms of style, shapes, layouts, while the developer thinks in terms of code, structure and architecture. But there is some point--albeit shaky--where the two meet, and that is called HTML.

The designer has a final result that is HTML. At the end of the day his work becomes an HTML layout complemented by CSS.

The developer starts with the HTML that the designer has created and then makes his code render it dynamically. So it is here, at this meeting point that is HTML that we must find a way for designer and developer to meet and do what they both need to do without stepping on each other's toes.

Assume for a minute that a designer has designed a simple HTML Table that will display the details of members on a website in a simple list display.

What if we could let the designer simply tell us where he wanted the developer to insert the dynamic content and simply leave it to him? What if, rather than having to explain complex concepts, the designer could simply say:


Username Email Password


So now the developer knows exactly what data needs to go where. All he has to do is write a script to handle this type of thing. This might take the form of:



What we now have is a PHP script that will substitute definite values for the comments that the designer inserted into the HTML in the first place.

Thus we now need to finish the parser that will make sure that the code we have just written will actually do what the designers intended.

function get_template($template_name, $rules, $recordset_array) 
{ 
    $FLAG = 0; 
    $start=0; 
    $end=0; 
    $res_arr=""; 
    $xcontents = file (TEMPLATES_PATH . $template_filename); 
    while (list ($line_num, $line) = each ($xcontents)) 
    { 
        if ($FLAG == 0) 
        { 
            if(ereg('', $line)) 
            { 
                $FLAG = 1; 
                $start = $line_num; 
            } 
        } 
        else 
        { 
            if (!ereg ('', $line)) 
            { 
                $res_arr .= $line; 
            } 
            else 
            { 
                $FLAG = 0; 
                $end = $line_num; 
            } 
        } 
    } 

    $tmp_res_arr = ""; 
    $n = count($data_array); 

    for ($x=0; $x<$n; $x++) 
    { 
        $tmp = $res_arr; 
        for ($y=0; $y < count($rules); $y++) 
        { 
            $a = $rules[$y][0]; 
            $b = $rules[$y][1]; 

            if (ereg ("<$n; $x++) 
    { 
        $y = $start + ($x - $end) ; 

        if (($x >= $start) and ($x < $end)) 
        { 
            if ($contents[$start] == "") 
                $contents[$x] = $res_arr; 
        } 
        elseif ($x > $end) 
            $contents[$y] = $xcontents[$x]; 
        else 
            $contents[$x] = $xcontents[$x]; 
    } 

    return ($contents); 
} 


Ok, so lets take a look at this in a bit of detail.


$xcontents = file (TEMPLATES_PATH . $template_filename); 
    while (list ($line_num, $line) = each ($xcontents)) 
    { 
        if ($FLAG == 0) 
        { 
            if(ereg('', $line)) 
            { 
                $FLAG = 1; 
                $start = $line_num; 
            } 
        } 
        else 
        { 
            if (!ereg ('', $line)) 
            { 
                $res_arr .= $line; 
            } 
            else 
            { 
                $FLAG = 0; 
                $end = $line_num; 
            } 
        } 
    }

What we are doing here is looking for the spot that the designers said we need to include our files. Once we find where we start, we look where we need to end.

How do we actually look for the start and end points, you may ask? Ever heard of the built in PHP function ereg()? What this does it search through our code until it finds something that matches our start and end tags. When it finds the match it RETURNS TRUE.

Note that this function has been removed from PHP 6, but for our purposes it still works quite well. If you really are a stickler and want to use the PHP6 functions, you need to look at PREG_MATCH(). You can see some of this HERE.


for ($x=0; $x<$n; $x++) 
    { 
        $tmp = $res_arr; 
        for ($y=0; $y < count($rules); $y++) 
        { 
            $a = $rules[$y][0]; 
            $b = $rules[$y][1]; 

            if (ereg ("

Here we loop through the data array looking for the specific tags (USERNAME-DATA, etc), again using ereg(); Then here and in the next code we replace those tags with the content.

for ($x=0; $x<$n; $x++) 
    { 
        $y = $start + ($x - $end) ; 

        if (($x >= $start) and ($x < $end)) 
        { 
            if ($contents[$start] == "") 
                $contents[$x] = $res_arr; 
        } 
        elseif ($x > $end) 
            $contents[$y] = $xcontents[$x]; 
        else 
            $contents[$x] = $xcontents[$x]; 
    }


On the whole the process is simple. What happens here is that PHP is actually taking the HTML and replacing the comment tags between the START and END comments with variables drawn from the database.

This might be a little more complex than the MVC template files of the format .phtml, but the complexity might actually be worth it in the long run if you are not really willing to go the MVC route and have a MODEL, VIEW and CONTROLLER for the website or application you are building.

Until Next Time - Happy Templating!

No comments:

Post a Comment