Page 1 of 1

Advanced Template System

Posted: Tue Jun 29, 2004 3:17 pm
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

Posted: Tue Jun 29, 2004 9:28 pm
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.

Posted: Tue Jun 29, 2004 10:56 pm
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.

Posted: Tue Jun 29, 2004 11:06 pm
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."

Posted: Tue Jun 29, 2004 11:44 pm
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.

Posted: Tue Jun 29, 2004 11:48 pm
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.

Posted: Wed Jun 30, 2004 5:55 pm
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

Posted: Wed Jun 30, 2004 7:09 pm
by phice
Skrol29: How is a 100kb php file "Tiny"?

Posted: Wed Jun 30, 2004 7:26 pm
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.

Posted: Wed Jun 30, 2004 7:34 pm
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?

Posted: Wed Jun 30, 2004 7:36 pm
by crabyars
BTW Skrol, congrats on TBS, it's a really nice clean package..

Posted: Wed Jun 30, 2004 8:32 pm
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 :)

Posted: Wed Jun 30, 2004 8:50 pm
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.