homepage Welcome to WebmasterWorld Guest from 50.17.86.12
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Pubcon Platinum Sponsor 2014
Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
Forum Library, Charter, Moderators: coopster & jatar k

PHP Server Side Scripting Forum

This 50 message thread spans 2 pages: 50 ( [1] 2 > >     
The One Line Template Engine!
Just for fun...
vincevincevince

WebmasterWorld Senior Member vincevincevince us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 7:03 am on Sep 8, 2007 (gmt 0)

The engine itself:
print preg_replace("/\{([^\{]{1,100}?)\}/e","$$1",file_get_contents("template.tpl"));

Format of template.tpl file:
<html>
<head>
<title>{title}</title>
</head>
<body>
<h1>{header}</h1>
{text}
</body>
</html>

Setting variables:
$title="Example page";
$header="My Examples";
$text="See the placeholders replaced?";

If you're not comfortable with pulling variables out of the global scope, define them as $values['title']=".."; etc., and use:
print preg_replace("/\{([^\{]{1,100}?)\}/e","$values[$1]",file_get_contents("template.tpl"));

 

coopster

WebmasterWorld Administrator coopster us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 4:21 pm on Sep 10, 2007 (gmt 0)

Can you explain your regular expression logic for us? For example, why search for anything that is not another opening brace? And make it optional? A nice, simple little example here, by the way.

vincevincevince

WebmasterWorld Senior Member vincevincevince us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 3:31 am on Sep 11, 2007 (gmt 0)

"/\{([^\{]{1,100}?)\}/e","$$1"
I'm delimiting the regular expression with / / and using the modifier 'e' which causes the second argument to be evaluated by PHP.

The pattern looks for an opening curly-brace ( \{ ) - the end of the pattern is a closing curly-brace ( \} ).

In between the two braces I look for any character which isn't an opening curly-brace [^\{], avoiding mistaken nesting of tags.

I match between 1 and 100 of these non-{ characters by writing {1,100} and then I make the match non-greedy (try to find the shortest strings between { and }, not the longest) by adding a?. (? after *, + or {a,b} expressions changes them to non-greedy - in other situations? means 0 or 1 of the preceding).

The full string of non-{ characters is matched and stored as string $1 by surrounding that part of the pattern with brackets ().

Finally, the second argument of the preg_replace is "$$1", using variable variables. If the pattern encounters "{title}" then the matched string $1 is "title" and so $$1 is $title.

coopster

WebmasterWorld Administrator coopster us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 3:39 pm on Sep 11, 2007 (gmt 0)

Nice. Thanks for the explanation as it will be beneficial to future readers.

bsterz

10+ Year Member



 
Msg#: 3444822 posted 4:00 pm on Sep 11, 2007 (gmt 0)

That's really slick

whoisgregg

WebmasterWorld Senior Member whoisgregg us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 5:35 pm on Sep 11, 2007 (gmt 0)

Niiice. I especially appreciate the explanation of the regular expression. :)

dreamcatcher

WebmasterWorld Senior Member dreamcatcher us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 7:44 pm on Sep 11, 2007 (gmt 0)

what about using str_replace?

echo str_replace(array('{header}','{title}','{body}'),array('header','title','body'),file_get_contents("template.tpl"));

dc

dmorison

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 3444822 posted 7:48 pm on Sep 11, 2007 (gmt 0)

> why not use str_replace

Using regexp's makes it generic, so {anything} will be replaced with $anything etc..

Gibble

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 3444822 posted 7:49 pm on Sep 11, 2007 (gmt 0)

Depends which is faster.

Multiple string replaces (more than three) tend to be faster done with preg_replace, fewer replaces are quicker with str_replace.

Or so the benchmarks I recall seemed to indicate.

So it all depends how many things you plan to have in your template.

EDIT:
And yes, looking back, I notice the "generic" factor is huge.

[edited by: Gibble at 7:50 pm (utc) on Sep. 11, 2007]

vincevincevince

WebmasterWorld Senior Member vincevincevince us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 11:07 am on Sep 12, 2007 (gmt 0)

> why not use str_replace

Exactly as dmorison said - to make it generic. It's not normally expected that you have to list the tags which you're going to use. Although, if all fields are defined within an array such as $values['{title}'], $values['{header}'], etc. then you could use array_keys($values) and $values as the arguments to your str_replace making it more generic.

The str_replace would probably be faster for some cases, although it would depend upon the number of tags to be replaced. On the positive side for the str_replace, it would be more secure if you didn't have control over your .tpl file.

One difference in end result is that with the preg_replace method, a tag enclosed in {} but not matched by a variable will be removed ("Hello {name}!" => "Hello!"), whereas the str_replace method would leave that unreplaced tag in place ("Hello {name}!" => "Hello {name}!")

dreamcatcher

WebmasterWorld Senior Member dreamcatcher us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 12:41 pm on Sep 12, 2007 (gmt 0)

Thanks guys, just thought str_replace was worth mentioning as other people might have been thinking it. I`ve actually been using the str_replace method on some of my own dev stuff for a while now, but as you mentioned, ideal for only a few tags.

dc

russkern

5+ Year Member



 
Msg#: 3444822 posted 5:42 pm on Sep 12, 2007 (gmt 0)

This is very cool... thanks for the thread.. been wondering how to accomplish this for some time now...

Didn't understand all the Regular expression explanation, but I will in time...

Thanks again...

mooger35

5+ Year Member



 
Msg#: 3444822 posted 12:03 am on Sep 13, 2007 (gmt 0)

Is it possible to use include (ie include a dynamic PHP page) in place a variable? In this case maybe "text"?

EDIT: Figured it out.

function get_include_contents($filename) {
if (is_file($filename)) {
ob_start();
include $filename;
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
return false;
}
$text = get_include_contents(somefile.php);

vincevincevince

WebmasterWorld Senior Member vincevincevince us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 1:09 am on Sep 13, 2007 (gmt 0)

mooger35, you can do that - or there are two other options:

1) Inside 'somefile.php', everywhere you see 'print' or 'echo' change it to '$text.=' - this will mean you can just do include('somefile.php'); and $text will be filled with the output:

print "Good morning $name"; ==> $text.= "Good morning $name";

2) Use a http:// request to file_get_contents(). $text=file_get_contents("http://your.example.com/somefile.php"); - this runs it as a separate Apache instance and you get the full results to variable

Your solution is fine, apart from it being a whole extra function to define. Be careful though as your variable scope is still shared, e.g. if you set $a=7 in somefile.php, $a still equals 7 afterwards.

g1smd

WebmasterWorld Senior Member g1smd us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 8:24 pm on Sep 13, 2007 (gmt 0)

OK. But what does it DO? What do you use it for?

There must be plenty of beginners looking at it, that consider it would be easier to understand if written in Sanskrit or Swahili!

pageoneresults

WebmasterWorld Senior Member pageoneresults us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 9:17 pm on Sep 13, 2007 (gmt 0)

OK. But what does it DO? What do you use it for?

Me too! I'm interested as I'd like to see an asp version if possible.

There must be plenty of beginners looking at it, that consider it would be easier to understand if written in Sanskrit or Swahili!

That makes two of us, so far... :)

borntobeweb

5+ Year Member



 
Msg#: 3444822 posted 9:28 pm on Sep 13, 2007 (gmt 0)

Heh, i don't quite understand the usefulness of templates in PHP. I can see using templates in Perl or C++, but i've always thought of PHP, just like JSP, as a templating language in itself so i'm not sure what's gained by adding an extra level of complexity. To me, it's much more straightforward to shove all the relevant values in an associative array and include the php "template" file that generates the HTML based on this array. Can someone please explain the pros and cons of using templates in PHP?

Bennie

10+ Year Member



 
Msg#: 3444822 posted 9:29 pm on Sep 13, 2007 (gmt 0)

errr, what? Can someone break this down to a simple caveman lingo for those that have very limited php knowhow. What is it? A template for a dynamic webpage?

JS_Harris

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 3444822 posted 9:50 pm on Sep 13, 2007 (gmt 0)

I've been using global php based templates for years simply because it's the absolute easiest way to make changes to 10,000 pages at once. I was wondering what would happen to global templates now that phpBB forums switched to html, removing yet another way webmasters were being exposed this.

Dunno why I never brought it up here, good job vince!

henry0

WebmasterWorld Senior Member henry0 us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 10:10 pm on Sep 13, 2007 (gmt 0)

VinceVinceVince,
Asides well deserved applauds for a very lean tpl

I can’t say for how long I have been waiting for someone in the PHP forum
to post something that will make the WebmasterWorld top page

More and more when so nicely written in “Swahili!” :)

jimbeetle

WebmasterWorld Senior Member jimbeetle us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 10:18 pm on Sep 13, 2007 (gmt 0)

g1smd
But what does it DO? What do you use it for?

P1R
That makes two of us, so far...

Bennie
What is it?

And now me: Duh?

Come on, guys, I know we're strangers in a strange land and don't speak the language, but somebody in here has to be able to translate for us ;-)

BlueYon

10+ Year Member



 
Msg#: 3444822 posted 11:36 pm on Sep 13, 2007 (gmt 0)

This is the one class template engine:

<?php
class Template {
var $data = array();

function __construct($directory) {
$this->directory = $directory;
}

function set($key, $value = NULL) {
if (!is_array($key)) {
$this->data[$key] = $value;
} else {
$this->data = array_merge($this->data, $key);
}
}

function fetch($filename, $directory = DIR_TEMPLATE) {
$file = $directory . $this->directory . '/' . $filename;

if (file_exists($file)) {
extract($this->data);

ob_start();

include($file);

$content = ob_get_contents();

ob_end_clean();

return $content;
} else {
exit('Error: Template ' . $file . ' not found!');
}
}
}
?>

MattAU

5+ Year Member



 
Msg#: 3444822 posted 12:54 am on Sep 14, 2007 (gmt 0)

What It Does: It enables you to run a basic templating system to save time, make changes occur easily etc.

Ideally you'd be using it with a database, but you could also just go old-school and make your own pages manually in a couple of different ways.

eg. (building on vince's original example)

Format of template.tpl file:

<html>
<head>
<title>{title}</title>
</head>
<body>
<h1>{header}</h1>
{text}
</body>
</html>

Your 'main' file, let's call it index.php:

<?php
// Figure out which page to load
$page = 'index';
if(!empty($_GET['page']) && ctype_alnum(trim($_GET['page'])))
$page = trim($_GET['page']);
// Get the variables for the page to be loaded
if($page == 'index')
{
$title = 'Index Title';
$header = 'The Great Header';
$text = '<p>all the page\'s text and info</p>';
}
elseif($page == 'about')
{
$title = 'About Us';
$header = 'Info About Us';
$text = '<p>We are the greatest, yada yada</p>';
}
else
{
$title = 'Error: Page Doesn\'t Exist';
$header = 'Sorry, the page you requested doesn\'t exist';
$text = '';
}
// Run the template engine
print preg_replace("/\{([^\{]{1,100}?)\}/e","$$1",file_get_contents("template.tpl"));
?>

The first part checks if a page argument exists, and if it's in a valid alpha-numeric format to keep the hackers out.

The next bits define the variables for each page (including an error page which is displayed if the page argument is in a valid format but isn't actually a page), then you include the template and you're done!

You call the pages by going to:

example.com/index.php or example.com/index.php?page=index
example.com/index.php?page=about

The other way to do it is to put each page in it's own file:

index.php

<?php
$title = 'Index Title';
$header = 'The Great Header';
$text = '<p>all the page\'s text and info</p>';
print preg_replace("/\{([^\{]{1,100}?)\}/e","$$1",file_get_contents("template.tpl"));
?>

about.php

<?php
$title = 'About Us';
$header = 'Info About Us';
$text = '<p>We are the greatest, yada yada</p>';
print preg_replace("/\{([^\{]{1,100}?)\}/e","$$1",file_get_contents("template.tpl"));
?>

Then just load the pages as normal - example.com/index.php, example.com/about.php

HTH

[edited by: MattAU at 1:09 am (utc) on Sep. 14, 2007]

vincevincevince

WebmasterWorld Senior Member vincevincevince us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 2:28 am on Sep 14, 2007 (gmt 0)

Heh, i don't quite understand the usefulness of templates in PHP.

One template, many pages of content. Similar deal to templates used by Dreamweaver etc. but done server-side. Keep your template free of PHP code and you can edit it by nad, or using Dreamweaver, Frontpage or Microsoft Word etc. Just put {} around the things you want to be dynamic (i.e. titles, text, menu,?).

Your PHP file can then be just about PHP code...

contact.php might be just:
$title="Contact us";
if (!$_POST) $text="<form ....> etc...";
else {
$text="Thanks for your contact";
mail("to@example.com","Contact",......);
}
print preg_replace("/\{([^\{]{1,100}?)\}/e","$$1",file_get_contents("template.tpl"));

index.php might be just:
$title="Welcome to Widget Site";
$text="All about widgets ....";
print preg_replace("/\{([^\{]{1,100}?)\}/e","$$1",file_get_contents("template.tpl"));

i.e. every page should be setting $variables matching the {placeholders} you put into the HTML template file (named template.tpl in this example). At the bottom of the PHP file, you call the 'one line template engine' and the magic happens.

Front page thread? Wow!

JS_Harris

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 3444822 posted 5:33 am on Sep 14, 2007 (gmt 0)

It's more powerful than just being a "one page" template honestly. You can create different sections of a page and call on them independantly at will. Basicaly an endless variety of pages are possible with just a few lines of code. Php + SQL is worth learning.

pixeltierra

5+ Year Member



 
Msg#: 3444822 posted 6:03 am on Sep 14, 2007 (gmt 0)

Quite slick, indeed. For me however, I've found that Smarty is quick, robust and pretty full-featured.

Not that I don't see the use of creating your own templating system. My first 4 years of programming I spent re-inventing the wheel. That's how I cut my teeth. The last 3 years of programming I've spent trying to learn how to use the many wheels that came before me. And boy are there a lot of them. Just Zend, Pear, Cake, can fill your learning plate for months.

For those who are unfamiliar with the notion of templates (not a la dreamweaver) this page might be useful: [smarty.php.net...]

IanKelley

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 3444822 posted 6:09 am on Sep 14, 2007 (gmt 0)

Elegant :-)

Significantly less elegant, and untested, alternate using MySQL for greater efficiency:

list($tpl) = mysql_fetch_row(mysql_query("SELECT tpl FROM templates WHERE page = '$self'",mysql_connect($dbh,$dbu,$dbp)));
print preg_replace("/\{([^\{]{1,100}?)\}/e","$$1",$tpl));

Non Swahili translation of greater efficiency: More pages served before you have to buy more hardware.

JonB

10+ Year Member



 
Msg#: 3444822 posted 6:15 am on Sep 14, 2007 (gmt 0)

nice example but personally,I am not a fan of "template" engines - this first example could be done like this and keep it pure php and html, no need to bring the "third" language (saved as .php):

<html>
<head>
<title><?=$title?></title>
</head>
<body>
<h1><?=$header?></h1>
<?=$text?>
</body>
</html>

Setting variables:
$title="Example page";
$header="My Examples";
$text="See the placeholders replaced?";

less code,less files,more understandable and quicker in execution. Or maybe I am missing the "point" of the using template in this particular example? :)

[edited by: JonB at 6:30 am (utc) on Sep. 14, 2007]

hughie

10+ Year Member



 
Msg#: 3444822 posted 6:58 am on Sep 14, 2007 (gmt 0)

The whole point of the template engine is to keep the logic and the design seperate (or in the case of smarty create a clean happy medium). Yes JonB your example pretty much does the same thing, but your rellying on some basic syntax there that might not be understood by a designer.

vincevincevince

WebmasterWorld Senior Member vincevincevince us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 3444822 posted 7:03 am on Sep 14, 2007 (gmt 0)

JonB... your example works, but can you edit it with a WYSIWYG editor? i.e. could you have a designer (not programmer) work on your site design?

This 50 message thread spans 2 pages: 50 ( [1] 2 > >
Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved