Go Back   SitePoint Forums > Forum Index > Program Your Site > PHP > PHP Application Design
Newsletter FAQ Members List Calendar Mark Forums Read

New to SitePoint Forums? Register here for free!

SitePoint Sponsor
 
Reply
 
Thread Tools Display Modes
Old Jul 30, 2003, 02:38   #1
HarryF
SitePoint Wizard
gold trophysilver trophy
 
Join Date: Nov 2000
Location: Switzerland
Posts: 2,898
Simple Template

Alright, following on from this thread and the discussion that's happening here, here's Simple Template (hopefully lastcraft will excuse my riding on the back of the Simple Test name but this really is pretty simple).

The ZIP attached has all the code - 90% is examples plus there's an extensive README.

Here's the simplest example of Simple Template is use;

The controller;

PHP Code:

<?php

// Include the config
//     - this defines a single constant switching caching on or off
require_once('simplet/config.php');

// Include the Awesome Template Engine classes
require_once('simplet/ViewHandler.php');
require_once(
'simplet/Binder.php');

// Setup PEAR::Cache_Lite
// See: [url]http://www.devshed.com/Server_Side/PHP/PHP_Cache_Lite/print_html[/url]
$cacheOptions = array(
    
'cacheDir' => 'cache/',
);
$cache = & new Cache_Lite($cacheOptions);

// Create a ViewHandler for the template, passing it
// Cache_Lite, the name of the template file and a cache
// expiry time in seconds
$view = new ViewHandler($cache,'simple.php',10);

// If the view isn't cached, build it...
if ( !$view->isCached() ) {

    
// Instantiate the Binder: this class "parses" the template
    
$binder = new Binder();

    
// Create the BindData object. This is a store for "Model" data
    // and it "bound" to the template by the Binder
    
$model =& new BindData();

    
// Add some simple "Model" data to BindData
    
$model->title = 'A simple example';
    
$model->message = 'Hello World!';
    
$model->time = date ('H:i:s');

    
// Pass the "View" object to the binder
    
$binder->setView($view);

    
// Pass the "Model" object to the binder
    
$binder->setData($model);

    
// Bind the "Model" to the "View"
    
$binder->bind();

}

// Get the output from the View
$output = $view->toString();

// Output is only send to the browser here...
echo ( $output );
?>
The template;

PHP Code:

<html>

<head>
<title><?php echo ( $title ); ?></title>
</head>
<body>
<h1><?php echo ( $title ); ?></h1>
<p><?php echo ( $message ); ?></p>
<p>This page was cached at <?php echo ( $time ); ?> and expires within 10 seconds</p>
</body>
</html>
Yes that's real PHP in the template and IMO there's nothing wrong with that. The discipline in using Simple Template is to keep the templates purely to presentation logic - something that a web designer with a half day's intro to PHP should be able to manage. There's no security mechanism by which you can limit templates to particular functions etc. May consider looking at what SAFE MODE has to offer but really think it's not worth it.

Here's one more example of a template that has a loop in it;

PHP Code:

Dir time = <?php echo ( $time ); ?>

<?php
$alt
= '#fff';
?>

<h1>Directory Listing</h1>
<table>

<?php
while ( $entry = $dir->fetch() ) {
    
$alt == '#fff' ? $alt = 'silver' : $alt = '#fff';
?>

<tr style="background-color: <?php echo ( $alt ); ?>">
<td><?php echo ( $entry ); ?></td>
</tr>

<?php
}
?>
</table>
Anyway - hope that's interesting. I've tried to avoid creating a framework here but would be very interested to hear opinions from the point of view of using it.
Attached Files
File Type: zip SimpleTemplate.zip (33.4 KB, 200 views)
HarryF is offline   Reply With Quote
Old Jul 30, 2003, 02:55   #2
pippo
FreeBSD The Power to Serve
silver trophy
 
pippo's Avatar
 
Join Date: Jul 2001
Location: Italy
Posts: 4,568
Harry,
what do you think to use an object $obj so you will have something like:

PHP Code:

<html>

<head>
<title><?php echo ( $obj->getTitle() ); ?></title>
...

Andrea
__________________
Mr Andrea
Former Hosting Team Advisor
Former Advisor of '03
pippo is offline   Reply With Quote
Old Jul 30, 2003, 04:41   #3
HarryF
SitePoint Wizard
gold trophysilver trophy
 
Join Date: Nov 2000
Location: Switzerland
Posts: 2,898
Quote:
what do you think to use an object $obj
Think that's fine - getTitle() is meant to be output to a user. Don't want to tie anyone to using a particular variable name though (e.g. $obj ) - for me $obj would something from the Model layer bound to the template.
HarryF is offline   Reply With Quote
Old Jul 30, 2003, 04:54   #4
nucleuz
SitePoint Zealot
 
Join Date: Aug 2002
Posts: 191
IMHO: that's the way to go with templating and PHP - KISS .
I've been doing the same as this for my last project ( not OO, but the same concept ) and as Harry says: given a brief intro to PHP anyone doing design should be able to do this fairly quickly!
__________________
phpvolcano :: Blog :: wiki.cc/php :: wiki.cc/pecl :: wiki.cc/pear
nucleuz is offline   Reply With Quote
Old Jul 30, 2003, 06:29   #5
lastcraft
SitePoint Victim
 
lastcraft's Avatar
 
Join Date: Apr 2003
Location: London
Posts: 2,399
Hi.

Quote:
Originally Posted by HarryF
hopefully lastcraft will excuse my riding on the back of the Simple Test name but this really is pretty simple
MarCus doesn't mind at all . In fact I am kicking myself for choosing such a dumb name! Yours is much more appropriate.

yours, Marcus.
__________________
Marcus Baker
Testing: SimpleTest, Cgreen, Fakemail
Other: Phemto dependency injector
Books: PHP in Action, 97 things
lastcraft is offline   Reply With Quote
Old Jul 30, 2003, 07:35   #6
Dr Livingston
Non-Member
 
Join Date: Jan 2003
Posts: 5,788
HarryF - Thanks for sharing your scripts;

As to using objects in the Template this is exactly the idea I have myself, so you use getter's to get the data from an object passed from the MODEL.

I suppose there is no real way of avoiding the issue of having PHP in a Template other than using something like Smarty style tags which is an unnessacary overhead.

Myself, I suppose I just need to get used to this idea; either that or use my previous methods of an XML document and XSL stylesheet or use the DOM to dynamically create the page;

The first option is said to be slower and the second option is limited to the need to change the page structure for example; something a designer is unable to do

Umm... If only there was another option huh ?
Dr Livingston is offline   Reply With Quote
Old Jul 30, 2003, 07:38   #7
Captain Proton
SitePoint Guru
 
Join Date: Oct 2001
Posts: 666
You know what would make a template system like this perfect? If there were some sort of function in PHP that would enable safe mode for only one file. So the template engine could tell PHP that the template file can only use 'safe' PHP functions, such as foreach(), str_replace, etc and it would be banned from using functions such as exec().
Captain Proton is offline   Reply With Quote
Old Jul 30, 2003, 09:39   #8
marcoBR
SitePoint Zealot
 
marcoBR's Avatar
 
Join Date: Jun 2002
Location: Brazil
Posts: 146
Quote:
Originally Posted by Captain Proton
You know what would make a template system like this perfect? If there were some sort of function in PHP that would enable safe mode for only one file. So the template engine could tell PHP that the template file can only use 'safe' PHP functions, such as foreach(), str_replace, etc and it would be banned from using functions such as exec().
I agree.
marcoBR is offline   Reply With Quote
Old Jul 30, 2003, 11:09   #9
Mike Borozdin
SitePoint Wizard
 
Mike Borozdin's Avatar
 
Join Date: Oct 2002
Location: Edinburgh, UK
Posts: 1,750
Franly speaking, I don't like it. I dislike such loops mixed up with HTML. I like phpBB template system with
<!-- BEGIN BLOCK> and <!-- END BLOCK --> tags.
__________________
Microsoft Student Partner
My blog
Mike Borozdin is offline   Reply With Quote
Old Jul 30, 2003, 11:10   #10
Captain Proton
SitePoint Guru
 
Join Date: Oct 2001
Posts: 666
oh oh, there we go again.. :O
Captain Proton is offline   Reply With Quote
Old Jul 30, 2003, 11:13   #11
Mike Borozdin
SitePoint Wizard
 
Mike Borozdin's Avatar
 
Join Date: Oct 2002
Location: Edinburgh, UK
Posts: 1,750
I put repeatting blocks to sepearetes files, the I open them befre going thorugh a loop, in the loop, I parse that file and show it or assign to some other variable.

Anyway, Happy Birthday To You, Harry!!!
__________________
Microsoft Student Partner
My blog
Mike Borozdin is offline   Reply With Quote
Old Jul 31, 2003, 01:48   #12
ZangBunny
SitePoint Zealot
 
ZangBunny's Avatar
 
Join Date: Jul 2003
Location: Mainz, Germany
Posts: 122
Prettier Looping

We're using a modified AwesomeTemplateEngine on our project that has remarkable resemblance to your SimpleTemplate, so I thought I'd just share this little trick to keep the webdesigners happy:

To make the templates more readable, use PHP's "alternative" syntax for control structures. Your "Loop" example would then look like this:

PHP Code:

<?php 

while ( $entry = $dir->fetch() ) :
    
$alt == '#fff' ? $alt = 'silver' : $alt = '#fff';
?>
...
<?php
endwhile;
?>
This makes it easier for non-PHPers that are used to matching tags, but not to matching braces.

On a side-note: I prefer the "<?=" syntax for readability. Most servers have the short_open_tags set to on anyway, and I don't find that setting it to off gives me any advantage, because I still can't use "<?xml" inline or my script will break when put on a server with short_open_tags on.
ZangBunny is offline   Reply With Quote
Old Jul 31, 2003, 06:14   #13
Taoism
SitePoint Addict
 
Join Date: Aug 2002
Location: Ottawa, Ontario, Canada
Posts: 215
I prefer "<?=;?>" as well. As a matter of fact, every single embeded php "echo" type statement in all HTML code I have written at work uses the short syntax. It is simple, fast, and to the point ;p

I do however, disagree on using the alternative syntax instead of braces. But, that is what makes the world so great; we can disagree

Cheers,
Keith.
Taoism is offline   Reply With Quote
Old Jul 31, 2003, 07:31   #14
KnightE
SitePoint Member
 
Join Date: Jul 2003
Location: CN
Posts: 8
Quote:
Originally Posted by Taoism
I prefer "<?=;?>" as well. As a matter of fact, every single embeded php "echo" type statement in all HTML code I have written at work uses the short syntax. It is simple, fast, and to the point ;p

‘<?php echo ... ;?>' is safer and more reliable than'<?=...?>'(needn't ";")
especially in app with xml
also, depend on the php.ini config of host...


KnightE
KnightE is offline   Reply With Quote
Old Jul 31, 2003, 11:15   #15
marcoBR
SitePoint Zealot
 
marcoBR's Avatar
 
Join Date: Jun 2002
Location: Brazil
Posts: 146
Quote:
Originally Posted by README
That's not to say if/else shouldn't
be used in a template but should rather be restricted to tasks which relate
only to the rendering of output (such as rendering a table with alternating
row colors).
It seems HarryF always claims for total separation of logic from presentation, http://www.sitepointforums.com/showp...8&postcount=19, but now I'm very confused about his contradiction.
marcoBR is offline   Reply With Quote
Old Jul 31, 2003, 11:27   #16
Captain Proton
SitePoint Guru
 
Join Date: Oct 2001
Posts: 666
Separation of logic from presentation is not the same as separating PHP code from HTML, we've discussed that I-dunno-how-many times on these forums..
Captain Proton is offline   Reply With Quote
Old Jul 31, 2003, 11:38   #17
ZangBunny
SitePoint Zealot
 
ZangBunny's Avatar
 
Join Date: Jul 2003
Location: Mainz, Germany
Posts: 122
I think the distinction someone made somewhere else is very useful here: We don't want to separate logic from presentation (impossible IMHO), but rather separate business logic from presentation logic.
ZangBunny is offline   Reply With Quote
Old Jul 31, 2003, 16:01   #18
HarryF
SitePoint Wizard
gold trophysilver trophy
 
Join Date: Nov 2000
Location: Switzerland
Posts: 2,898
Quote:
We don't want to separate logic from presentation (impossible IMHO), but rather separate business logic from presentation logic.
Spot on. This simple template system (btw - think I accidentally saved the full readme in the simplet subdirectory) helps make that seperation possible.

Quote:
It seems HarryF always claims for total separation of logic from presentation, http://www.sitepointforums.com/show...18&postcount=19, but now I'm very confused about his contradiction.
You caught me being careless with words. For that post prepend the word "business" before logic. ASP.NET-like templates have the main advantage of being almost like HTML and easy for a drag and drop GUI to edit, hence very nice for designers.

The point is, whether your presentation logic looks like;

PHP Code:

while ( $row = $result->fetch() ) {

?>
<tr>
  <td><?=$row['username']?></td>
  <td><?=$row['email']?></td>
</tr>
<?php
}
Or

PHP Code:

<!-- Start:Loop:result -->

<tr>
  <td><!-- row:username --></td>
  <td><!-- row:email --></td>
</tr>
<!-- End:Loop:result -->
<?php
}
Or

PHP Code:

{loop:result}

<tr>
  <td>{username}</td>
  <td>{email}</td>
</tr>
{/loop:result}
<?php
}
Or

PHP Code:

<repeater id="result" runat="server">

<
tr>
  <
td><label id="username" runat="server" /></td>
  <
td><label id="email" runat="server" /></td>
</
tr>
</
repeater>
There's still logic in there but it should only be logic that deals with presentation (e.g. no db queries)
HarryF is offline   Reply With Quote
Old Jul 31, 2003, 20:48   #19
Taoism
SitePoint Addict
 
Join Date: Aug 2002
Location: Ottawa, Ontario, Canada
Posts: 215
Quote:
Originally Posted by KnightE
‘<?php echo ... ;?>' is safer and more reliable than'<?=...?>'(needn't ";" )
especially in app with xml
also, depend on the php.ini config of host...


KnightE
More reliable? I haven't had it not work on me once

I have the luxury of coding PHP in a corporate environment, and since I am the senior php programmer, I get have quite a bit of input into how things are set up (for PHP at least)

Cheers,
Keith.
Taoism is offline   Reply With Quote
Old Aug 1, 2003, 00:56   #20
prefab
SitePoint Zealot
 
prefab's Avatar
 
Join Date: Jan 2003
Location: Belgium
Posts: 133
I'd be interested in some opinions on my latest templating approach, inspired by http://simon.incutio.com/archive/200...pAndColdFusion , which in turn is inspired by the way ColdFusion CFML works.

It's based on pure XML templates (which is good, since it will force me to code XHTML compliant pages) and SAX parsing. I particularly focused on PEAR:DB_DataObject integration, as it offers a lot of interesting options to abstract the template tags. Next up is PEAR:DB raw SQL queries...

Also, apart from what is shown here, I won't mess with other logic constructs like if()/else() etc.

If anyone is interesting in developing this concept further don't hesitate to contact me...

- prefab

HTML Code:
<template id="test">
<doctype type="xhtml1strict" />
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>#title#</title>
</head>
<body>
<h1>#title#</h1>

include:<br/>
<include src="include.xml" parse="false" type="txt"/>
<hr/>

include(parsed):<br/>
<include src="include.xml" parse="true" type="txt" somevar="#title#" othervar="this is another variable"/>
<hr/>

ignore:<br/>
<ignore>ignore this text</ignore>
<hr/>

loop:<br/>
<loop sid="one" var="set"/>
<ul>
<output sid="one"><li>#_key_# :: #_val_#</li></output>
<else><li>no looping!</li></else>
</ul>
<hr/>

loop: (nested resultset)<br/>
<!-- #%# is a row counter, note #alternate# -->
<loop sid="one" var="nested"/>
<ul>
<output sid="one" alternate="red|black">
<li style="color: #alternate#">#%# :: #_key_# :: #name# :: #country#</li>
</output>
<else><li>no looping!</li></else>
</ul>
<hr/>

isset:<br/>
<isset var="title">this is the title : <i>#title#</i></isset>
<else><b>title not set</b></else>
<hr/>

PEAR:DB_DataObject:<br/>
<dataobject sid="obj" type="Rooms"/>
<output sid="obj">#nr# :: #description# :: #price#<br/></output>
<else>no room found..<br/></else>
<hr/>

PEAR:DB_DataObject:<br/>
<dataobject sid="obj" type="Rooms" price="60"/>
<output sid="obj">#nr# :: #pers# :: #description# :: #price#<br/></output>
<else>no room found..<br/></else>
<hr/>

PEAR:DB_DataObject:<br/>
<dataobject sid="obj" type="Rooms" where="price &lt;= 40" order="price ASC"/>
<output sid="obj">#nr# :: #pers# :: #description# :: #price#<br/></output>
<else>no room found..<br/></else>
<hr/>

PEAR:DB_DataObject:<br/>
<!-- note how the ID is assigned dynamicly from variable -->
<output sid="obj">#nr# :: #pers# :: #description# :: #price#<br/></output>
<else>no room found..<br/></else>
<hr/>

PEAR:DB_DataObject:<br/>
<!-- uses $_GET to supply filtering parameters 
(see PEAR:DB_DataObject:setFrom()) ex: script.php?price=40&pers=3 -->
<dataobject sid="obj" type="Rooms" scope="get"/>
<output sid="obj">
#nr# :: #pers# :: #description# :: #price#<br/>
</output>
<else>no room found..<br/></else>
<hr/>

PEAR:DB_DataObject:<br/>
<dataobject sid="obj" type="Rooms" scope="get"/>
<output sid="obj" alternate="red|black|white">
<span style="color: #alternate#">#nr# :: #pers# :: #description# :: #price#</span><br/>
</output>
<else>no room found..<br/></else>
<hr/>

</body>
</html>
</template>

Last edited by prefab; Aug 1, 2003 at 01:32..
prefab is offline   Reply With Quote
Old Aug 1, 2003, 01:43   #21
Chris82
SitePoint Wizard
 
Chris82's Avatar
 
Join Date: Mar 2002
Location: Osnabrück
Posts: 1,003
Harry, I preferred your approach to parse .Net files using phpHtmlLib.

I think, the discussion of wether to use PHP in the templates depends on the target audience of the script. Some People using a guestbook on their page are not so comfortable with php syntax and would prefer to use something like <%entry%> or some extended html syntax as prefab shows in his example. (Arguably, someone using the class should be able to handle this, but I would say that is not for the "masses".)

PHP Code:

<h1>Someone's Guestbook</h1>

<table>

<?php
while ( $entry = $dir->fetch() ) {
    
$alt == '#fff' ? $alt = 'silver' : $alt = '#fff';
?>

<tr style="background-color: <?php echo ( $alt ); ?>">
<td><?php echo ( $entry ); ?></td>
</tr>

<?php
}
?>
</table>
I think that this would be a bit too difficult for someone who just wants to have a guestbook. HTML feels a bit more "natural" to many people.

@prefab: how do you parse your template file?
Chris82 is offline   Reply With Quote
Old Aug 1, 2003, 02:34   #22
prefab
SitePoint Zealot
 
prefab's Avatar
 
Join Date: Jan 2003
Location: Belgium
Posts: 133
Quote:
Originally Posted by Chris82
@prefab: how do you parse your template file?
Parsing is simple, as the real magic happens in my 'cfm' class...

This is really a work in progress, as I just implemented alternating, and added the option to use $_GET or $_POST scope, while setting default parameters as atributes.

- prefab

like:
HTML Code:
<dataobject sid="obj" type="Rooms" where="price &gt; #min# AND price &lt;= #max#" order="#sorder# #sdir#"
scope="get" min="0" max="100" sorder="price" sdir="asc"/>
parsing with cfm:
PHP Code:

<?php


include('cfm.php');

$parser = &new cfm();

$parser->setVars(array(
    
'title' => 'Entries',
    
'roomid' => (int)$_GET['room']
    );


$set = array('k'=>'v', 'test'=>'val', 'a'=>1, 'b'=>2);
$parser->setVar('set', $set);

$new['fab'] = array('name'=>'fabien', 'country'=>'nl');
$new['lthl'] = array('name'=>'l2gx', 'country'=>'be');
$parser->setVar('nested', $new);

echo
$parser->parse(implode('', file('templates/cfm.xml')));

?>
prefab is offline   Reply With Quote
Old Aug 1, 2003, 06:18   #23
Taoism
SitePoint Addict
 
Join Date: Aug 2002
Location: Ottawa, Ontario, Canada
Posts: 215
Quote:
Originally Posted by prefab
I'd be interested in some opinions on my latest templating approach, inspired by http://simon.incutio.com/archive/200...pAndColdFusion , which in turn is inspired by the way ColdFusion CFML works.
LOL, one of the first things I did when I started my job a couple years ago was move as much development as possible away from CF. And now people are trying to make PHP look like CF, hehehe. To each their own I suppose. I just can't stand the way CF code looks... that's one reason I like PHP...it look like CODE, and not an HTML tag

Not running down what you are doing. If you like it, then good on ya, but it certainly isn't for me

Cheers,
Keith.
Taoism is offline   Reply With Quote
Old Aug 1, 2003, 06:22   #24
Taoism
SitePoint Addict
 
Join Date: Aug 2002
Location: Ottawa, Ontario, Canada
Posts: 215
Quote:
Originally Posted by Chris82
I think, the discussion of wether to use PHP in the templates depends on the target audience of the script. Some People using a guestbook on their page are not so comfortable with php syntax and would prefer to use something like <%entry%> or some extended html syntax as prefab shows in his example. (Arguably, someone using the class should be able to handle this, but I would say that is not for the "masses")
I would have to disagree with this to a certain extent. If people can learn HTML, and "special" tags like <%entry%>, then they should be intelligent enough to learn <?=$entry;?>...

C'est la vie, the great template debate continues.... Stay tuned for another episode of, "How the Template Parses!"

Cheers,
Keith.
Taoism is offline   Reply With Quote
Old Aug 2, 2003, 20:23   #25
Selkirk
SitePoint Guru
 
Join Date: Nov 2002
Posts: 846
All the good ones are taken.
Simple Template
__________________
Professional PHP Blog - twitter - about MVC
Selkirk is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread | Next Thread »

Thread Tools
Display Modes

 
Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

 
Forum Jump


All times are GMT -7. The time now is 09:23.


Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Copyright 1998-2009, SitePoint Pty Ltd. All Rights Reserved