Advanced Template System

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
User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

Advanced Template System

Post by phice »

I'm looking for a more advanced template system, where I can use if/elseif/else (and possibly foreach) functions inside a template.

Nicknamed "HTML Logic" or "Logic HTML", it looks something like this:

Code: Select all

{if variable == "12"}
   hi, im twelve!
{/if}
{else if variable == "16"}
   hi, im sixteen!
{/else if}
{else}
   hi, im {variable}
{/else}
If the above code could be better modified, post please.

Now, onto the "simple" template system that I have now.

Template Class:

Code: Select all

// Template Engine
	class Template

	{
		// Define class variables
		var $usable_vars	= array();
		var $_TEMP		= array();
		var $template_file	= '';
		var $template_handle	= '';
		var $template_content	= '';
		var $cache_path		= '';
		
		
		
		// function: Start template engine
		function template()
		{
			global $_CACHE;
			global $_USER;
			
			$this->cache_path = $_CACHEї'setting']ї'docroot'] . $_CACHEї'setting']ї'template_dir'] . $_USERї'template'] . "/";
		}
		
		
		
		// function: Write variables to cache
		function add_variables($variables = array())
		{
			if(count($variables) > 0)
			{
				foreach ($variables as $key => $value)
				{
					$this->useable_varsї$key] = $value;
				}
			}
		}
		
		
		
		// function: Open template file
		function parse_template($template_file)
		{
			global $_CACHE;
			
			$this->template_handle	= @fopen ($this->cache_path . $template_file, r);
			if ($this->template_handle)
			{
				$this->template_content	= @fread ($this->template_handle, filesize ($this->cache_path . $template_file));
				@fclose ($this->template_handle);
				
				if(count($this->useable_vars) > 0)
				{
					foreach ($this->useable_vars as $key => $value)
					{
						$this->template_content = eregi_replace($_CACHEї'setting']ї'reghandler_front'] . $key . $_CACHEї'setting']ї'reghandler_back'], "$value", $this->template_content);
					}
				}
				
				print $this->template_content;
			}
			else
			{
				print "Cannot find specified template file ('" . $this->cache_path . $template_file . "').<br />\n";
			}
		}
	}
It adds the variables from an array, loads the file, and replaces the given variables with their value.

Next, the actual template file:

Code: Select all

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
 <title>{site_title}</title>
 <script type="text/javascript" src="./scripts/global.js"></script>
 <link rel="stylesheet" href="./templates/{template_folder}/styles.css" type="text/css">
</head>
<body>

<center>
Now, to run it:

Code: Select all

// Template: site_header
	$template = new Template;
	$template->add_variables(array(	'site_title' => $_CACHE['setting']['site_title'],
					'template_folder' => $_USER['template']));
	$template->parse_template("site_header.tpl");
Output:

Code: Select all

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
 <title>BlastMB Dev Board</title>
 <script type="text/javascript" src="./scripts/global.js"></script>
 <link rel="stylesheet" href="./templates/default/styles.css" type="text/css">
</head>
<body>

<center>
It works exactly how it should, but as stated earlier, it's very simple. Have any of you made, or know of, an advanced template engine (that I can use in commercialware, and preferably not Smarty)? I'm trying to keep it very fit, clean and run extremely fast.

All I need is the base idea of how you would do it, and any example code if available.

Thanks,

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

Post by McGruff »

WACT might be worth a look. Specs sound interesting although I haven't yet found time to look at it in detail.

Incidentally, to anyone else reading this, there's a lot of interesting material about application design here.
User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

Post by phice »

It looks like that's too bloated with stuff I don't really need, but it does what I want it to.

I'll keep looking around and if I find something I like, I'll post a link to it.
Image Image
User avatar
markl999
DevNet Resident
Posts: 1972
Joined: Thu Oct 16, 2003 5:49 pm
Location: Manchester (UK)

Post by markl999 »

Savant might be of interest, not used it myself but it looks like an alternative to Smarty.

"Savant is a powerful but lightweight PEAR-compliant template system for PHP. It is non-compiling, and uses PHP itself as its template language so you don't need to learn a new markup system. It has an object-oriented system of template plugins and output filters, so it sports almost all of the power of Smarty with almost none of the overhead."
User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

Post by phice »

I found something that I could probably modify and get what I wanted (using a different sceme of html logical if statements, but it works :)). You may find it here (click on "LMan_Template").

I'll post my code later, along with examples if I get everything working how I want it.
Last edited by phice on Tue Jun 29, 2004 11:50 pm, edited 1 time in total.
Image Image
User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

Post by phice »

Originally posted by EricS (deleted his topic, he meant to post in here)

Before I start, it does not use if else logic (and I do this for a reason), but it does support repetition. So if if/else is a must, then ignore the rest.

My template system works a little backwards from the way yours does, in that you load the template in first, then modify it as you progress through your code. This allows me to do all my if/else logic outside of the template and it also allows me to completely seperate PHP code from HTML.

As I mentioned earlier, there is no php in the templates themselves. You just insert a tag with any name you like into the template that will be replaced by the template engine. I happen to use a hybrid comment tag to inclose my tags. So if I wanted to replace a name tag, my tag would be <!--%%name%%-->

I've chosen this hybrid mostly because it doesn't interfere with the HTML WYSIWYGs I use like Dreamweaver and GoLive. It just shows up as a comment.

As I mentioned before, it does support repetition as well as inserting text in individual instances of the repetition.

To do a repetition, you simple inclose any item you want to replicate inside identical tags so let's say I want to repeat a row in a table. The HTML would look something like this (I went a head and threw the name tag inside so I could do an example of text insertion in each row):

Code: Select all

&lt;table&gt;
&lt;!--%%row-container%%--&gt;
&lt;tr&gt;&lt;td&gt;&lt;!--%%name%%--&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;!--%%row-container%%--&gt;
&lt;/table&gt;

Code: Select all

// instantiate the template object - yes it's OO
$template = new Template();
// set the template
$template->setTemplate('some_file.htm');
// set the repeat region
$template->setNewRepeatRegion('row-container');
for ($i = 0; $i < sizeof($nameArray); $i++) {
     // create a working copy of the repeat region
     $template->setNewRepeatInstance();
     // insert the name in this instance of the repeat
     $template->modifyRepeatInstance('name', $nameArray[$i]);
     // save the repeat instance
     $template->saveRepeatInstance();
}
// save all the repeat instances to the template
$template->saveRepeatRegion();
// display the template to the user
$template->display();
Out put might look like this

Code: Select all

&lt;table&gt;
&lt;tr&gt;&lt;td&gt;Mike&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Eric&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Bob&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Bill&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Jake&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Jill&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Liz&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Katey&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
And that's a simple example of how I handle my web output in my applications.
Image Image
User avatar
Skrol29
Forum Newbie
Posts: 4
Joined: Wed Jun 30, 2004 5:55 pm

Post by Skrol29 »

Hello,

I'm a developer of the TinyButStrong Template Engine.
I think it does what you ask for.
It has conditional display for both fields and blocks.

The the web side for examples and demo:
http://www.tinybutstrong.com
User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

Post by phice »

Skrol29: How is a 100kb php file "Tiny"?
Image Image
User avatar
Skrol29
Forum Newbie
Posts: 4
Joined: Wed Jun 30, 2004 5:55 pm

Post by Skrol29 »

'Tiny' because it's only 1 file, 1 class with 8 methods and 2 properties.

Why 'tiny' and why 'strong' are explained at the page:
http://www.tinybutstrong.com/index.php?page=descr

PS: TBS is 92kb unziped.
crabyars
Forum Commoner
Posts: 37
Joined: Thu Jun 17, 2004 8:24 pm

Post by crabyars »

I had a long look at TinyButStrong (and Savant actually) a few months ago, and even started an implementation. In the end I gave up and reverted to Smarty. I wish I could recall exactly why. I think it had something to do with the "block" system, merging etc.., which was becoming laborious. Also I wanted to use my the EZSQL database abstraction, which made redundant some of the better aspects of the TBS package.

Although TBS is the best contender to Smarty IMO, I felt like I was learning yet another abstraction on top of PHP. For the site I ended up going back to Smarty, since it is widely supported and has a much more establised user base (and therefore documentation/forums/etc)

Savant is a nice concept, but it's not far off "rolling your own".

I have in the meantime gone back to pure PHP. Still haven't found a templating system that speaks to me, but Smarty and TBS are close.

One question for you templating gurus.. Is there any system that will allow me to WYSIWYG templates *without* having to resort to absolute URL's or duplicate directories to display the images?
Last edited by crabyars on Wed Jun 30, 2004 7:37 pm, edited 2 times in total.
crabyars
Forum Commoner
Posts: 37
Joined: Thu Jun 17, 2004 8:24 pm

Post by crabyars »

BTW Skrol, congrats on TBS, it's a really nice clean package..
User avatar
Skrol29
Forum Newbie
Posts: 4
Joined: Wed Jun 30, 2004 5:55 pm

Post by Skrol29 »

Crabyars: that is probably not the good thread to describe TinyButStrong but this is the occasion for me to answer to some of your points.
the "block" system, merging etc.., which was becoming laborious
Blocks laborious with TBS ??!!
You can define a block with only 1 tag if you want. Example: [blk;block=tr] and the block "blk" is defined on the table row.
Also I wanted to use my the EZSQL database abstraction, which made redundant some of the better aspects of the TBS package.
TBS is able to retrieve data from a SQL statement. If you use a unified connectivity tool for database like ezSql, then this part is redundant. But TBS can also connect to the tool you want to retrive data. Then, TBS becomes only a "bridge" for reading data when merging blocks.
I felt like I was learning yet another abstraction on top of PHP
Each template system needs at least a small syntax for the Template structure. But TBS has no programming logic on the Html side. It is only design logic (placing fields and blocks with parameters). There is no "for each" in the template, for example.
Is there any system that will allow me to WYSIWYG templates *without* having to resort to absolute URL's or duplicate directories to display the images?
TBS is the only template engine I know that enables you to build WYSIWYG templates.
But I don't see what you mean with "resort to absolute URL's or duplicate directories".
BTW Skrol, congrats on TBS, it's a really nice clean package.
Thanks :)
User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

Post by phice »

If you wish to continue this discussion, create a thread in another forum and I'll move these posts to the new thread.

Now, how would any of you suggest starting something like this from the source given above? Obviously something with regular expressions.
Image Image
Post Reply