Gerenal Ideas behind templating

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
d3ad1ysp0rk
Forum Donator
Posts: 1661
Joined: Mon Oct 20, 2003 8:31 pm
Location: Maine, USA

Gerenal Ideas behind templating

Post by d3ad1ysp0rk »

As I hear more and more about it, and how it's so much better for the overall product, I've been wondering, what exactly is templating?
Obviously it's the seperation of HTML and PHP, but how exactly does it work?

Something like:
template_a.html:

Code: Select all

<html>
<body>
<div class="menu">{menu}</div>
<div class="body">{body}{/div>
<div class="ads">{ads}</div>
</body>
</html>
then engine.php:

Code: Select all

$page = include("templates/template_a.html");
$menu = getmenu();
$body = getbody();
$ads = getads();
$page = str_replace("{menu}",$menu,$page);
$page = str_replace("{body}",$body,$page);
$page = str_replace("{ads}",$ads,$page);
echo $page;
or am I totally off?

Please explain (with a small example if possible, or a tutorial you'd suggest). thanks :)
User avatar
Ixplodestuff8
Forum Commoner
Posts: 60
Joined: Mon Feb 09, 2004 8:17 pm
Location: Queens, New York

Post by Ixplodestuff8 »

In my own (crappily done) template class I use the curly braces (though there is an option to change them to anything you want) style in the template.

You feed variables to the thing and it figures out things on it's own.. It's kind of hard to explain in words soo here's an example of how I use my class

the template (template.tpl)

Code: Select all

<html>
<body>
<div class="menu">{menu}</div>
<div class="body">{body}{/div>
<div class="ads">{ads}</div>
</body>
</html>
the code

Code: Select all

<?php
include ( 'template.class.php' );
$template = new Template();

//by defualt it's { }, so it doesn't need to be set, but I set it here for an example of how I could change the tags
$template -> set ( 'template char', '{', '}' );

//in this array, the array key would be the things inside the braces, and it's value
$vars = array();
$vars['menu'] = 'this is a menu';
$vars['body'] = 'this is the body';

//adds the array made above
$template -> add_vars ( $vars );

//adds a single variable, no need for an array
$template -> add_var ( 'ads', 'these are the ads' );

//sets the template file to use
$template -> add_template_file ( 'template.tpl' );

//outputs page
$page_output -> compile_page ();
$page_output -> output_compiled_data();
?>
And that's how it does the setting up, and here are some code snippets from the class to see how it works


This gets the variables from the array and uses the keys to get the thingies

Code: Select all

<?php
	//obviously compiles page then destroys template files
	function compile_page ()
	{
		$page = $this -> _parse_string;
		$template_array = $this -> _template_array;
		
		if ( $this -> _loops == 'on' )
		{
			$page = $this -> _parse_loops ( $page );
		}
		
		$page = 'print ''' . $page;
		$page = $page . ''';';
		
		$page = str_replace ( $this -> _start_string, '''; print $template_array[''', $page );
		$page = str_replace ( $this -> _end_string  , ''']; print ''', $page );
		
		$this -> _compiled_page = $this -> _compiled_page . $page;
		$this -> destroy( 'template' );
		return true;
	}
?>
this is what would change some of the settings for the class

Code: Select all

<?php
	function set ( $setting, $option_one, $option_two = NULL )
	{
		//settings here
		switch ( $setting )
		{
			
			case 'template char':
				$this -> _start_string = $option_one;
				$this -> _end_string = $option_two;
				break;
			
			case 'loops':
				$this -> _loops = $option_one;
				break;
		}
		
		return true;
	}
?>
and the output is done with a simple eval() line

Code: Select all

<?php
	function output_compiled_data ()
	{
		$template_array = $this -> _template_array;
		eval ( $this -> _compiled_page );
		$this -> destroy( 'compiled data' );
		return true;
	}
?>
That's how my template class is set up (the full class is alot longer, and loops are too buggy to be used, but meh). Anytime I need templating I use it.

Your idea works too, but only if you already know beforehand what variables you want to be replaced by the engine. and I'm sure there are alot diffrent and better ideas than the one I use aswell.
User avatar
Sevengraff
Forum Contributor
Posts: 232
Joined: Thu Apr 25, 2002 9:34 pm
Location: California USA
Contact:

Post by Sevengraff »

Templates are great. They make it extreamly easy to change the look of your program without going into your core files. Some do not use a template engine, but rather use PHP itself, so your example would look like this:

Code: Select all

&lt;html&gt;
&lt;body&gt;
&lt;div class="menu"&gt;&lt;? echo $menu; ?&gt;&lt;/div&gt;
&lt;div class="body"&gt;&lt;? echo $body; ?&gt;&#123;/div&gt;
&lt;div class="ads"&gt;&lt;? echo $ads; ?&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
This works for some people, but I find it looks a bit odd. Also, if your program lets others determin how their page looks, you may not want to give them the full power of PHP.

For a template solution, I personally use Easy Template System. It would look like this:

Code: Select all

<?PHP
include 'ets.php';

// build a datatree
$ets->menu= 'Main Menu';
$ets->body = 'Body of page';
$ets->ads = 'Dont you just hate ads?';

printt( $ets, 'template_file.tpl' );
?>
It also does loops, but it's not cessecary to go into that.

I like ETS because it gives the users some nice features, but they aren't given total control.

There are many template engines for PHP. You might want to look at this benchmark page. ETS isn't there, and I am sure it would not score well. However, speed isn't everything.
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post by McGruff »

To start off with, maybe you could try the embedded echo's mentioned above. I've personally never found a need to do anything more complicated. Define a bunch of unformatted page vars, then include the template to print the page (or page block). Nothing to it.

With placeholders, you would read the template into a string then str_replace or regex to swap variable values for placeholders. Finally you'd print the processed string.

You'll have to figure out how to deal with rows within a page. You could cheat a bit and use output buffering to pass along a ready-made html string as a var - but that forces you to add html in the biz logic (ie a row sub-template).

Another option is to build an (unformatted) array with just the page vars for each row and, in the template, call a template function (with the array as arg) rather than a simple embedded echo. The template function would loop through the array applying a second, sub-template to each row.

You might need one or two other simple template fns: they'll suggest themselves as the need arises.
malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

Post by malcolmboston »

lol, ive noticed a huge amount of posts on these forums are about templating engines/classes/functions etc

ive never tried to do anything like this because frankly it bores me, but have built a rather complex CMS which ios completely dynamic (not just content), i might be getting some peoples back up here who are proud of there templating systems but if you want a simple templating system (which if you dont know initially how to build one, like yourself, i recommend) then just doing something as simple as mcgruff has stated is maybe a 2-3 hour job

search around the forums theres thousands of topics about this
Selkirk
Forum Commoner
Posts: 41
Joined: Sat Aug 23, 2003 10:55 am
Location: Michigan

Post by Selkirk »

You might find this page on the Template View pattern useful.
User avatar
PrObLeM
Forum Contributor
Posts: 418
Joined: Sun Mar 07, 2004 2:30 pm
Location: Mesa, AZ
Contact:

Post by PrObLeM »

McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post by McGruff »

Selkirk wrote:You might find this page on the Template View pattern useful.
You read my mind - couldn't find that link previously.
Post Reply