homepage Welcome to WebmasterWorld Guest from 54.196.24.103
register, free tools, login, search, subscribe, help, library, announcements, recent posts, open posts,
Pubcon Platinum Sponsor
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




msg:3444824
 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"));

 

dreamcatcher




msg:3450410
 7:25 am on Sep 14, 2007 (gmt 0)

could you have a designer (not programmer) work on your site design?

Exactly. Think of if you were looking to create your own software to sell or download. Now lets assume someone isn`t PHP savvy and all they want to do is change the layout. Having all your PHP code embedded in the code would make it a virtually impossible task for a new developer to update the design without breaking the code. Having a template you can update in your WYSIWYG without breaking the code is very useful. For one, it would cut down on your support time answering questions about how to integrate designs.

Template engines are extremely useful.

dc

IanKelley




msg:3450418
 7:31 am on Sep 14, 2007 (gmt 0)

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

To answer for JonB... Conditional yes to both. There are WYSIWYG editors that won't mess with the PHP code. Non programmers can quickly learn to work around it. Besides, you won't find many web professionals that don't have a rudimentary understanding of PHP.

It's not the best answer for large websites with a lot of employees but for sites with a smaller number of technically savvy people saving the extra disk access, memory and CPU cycles is worth at least considering.

vincevincevince




msg:3450436
 7:54 am on Sep 14, 2007 (gmt 0)

Additional note for JonB... if you want to use that system (php directly amongst HTML) with a template which appears on multiple pages, then you will need to put your template PHP into a separate file and then run it with include().

gaouzief




msg:3450443
 8:03 am on Sep 14, 2007 (gmt 0)

vincevincevince: any way to add blocks and recursion with a few more lines? that would be perfect

hughie




msg:3450464
 8:33 am on Sep 14, 2007 (gmt 0)

hehe, vincevincevince, you've opened a can or worms here.

Pretty soon we're going to have the "WebmasterWorld engine"

vincevincevince




msg:3450536
 10:10 am on Sep 14, 2007 (gmt 0)

vincevincevince: any way to add blocks and recursion with a few more lines? that would be perfect

As a certified sucker for punishment... I've implemented recursion/loops for you. Blocks might come later, if I can find a way of doing it all in one line.

Remove the linebreaks... this should be on one line... just wanted to remove sidescroll

The engine itself
print preg_replace("/\{([^\{\}]*(\{?[^\{\}]*\}?)[^\{\}]*)\}/e",'((strlen(\'$2\'))? (eval("return preg_replace(array_fill(0,sizeof($"."$2),\"/\".preg_quote(\"$2\").\"/\"),$". $2,implode( array_fill(0,sizeof($"."$2),(\"$1\"))),1);")):($GLOBALS["$1"]))', file_get_contents("template.tpl"));

The above code is compatible with the previous usage, but adds support for nested placeholder as an indication of a loop.

Given an array (which could be from a database):
$color=Array("Red","Blue","Green");

Write your placeholder in template.tpl as follows:
{<div>{color} cars</div>}

The outer placeholder is the overall repeated string, the inner placeholder is that which is replaced differently each time.

The result of that bit of code would be:

<div>Red cars</div><div>Blue cars</div><div>Green cars</div>

Any takers for explaining the code? Note.... the line in this post is much less efficient than the previous version. It's also less secure - but then again - neither should be used with unsafe inputs.

g1smd




msg:3450568
 11:01 am on Sep 14, 2007 (gmt 0)

OK. This is about the best thread I have seen on WebmasterWorld in a while. I have never fully understood how any of that templating stuff worked. I attempted to digest a few tutorials last year, and they seemed to be written in a language that assumed that you already fully understood the concept. You explanation makes things a little more clear. This is something I am going to have to go away and play with, I think. The notes about how to implement it are far more important than the actual code. The code can be fantastic, but is of little use if no-one knows what to do with it. :-)

JS_Harris




msg:3450583
 11:48 am on Sep 14, 2007 (gmt 0)

You could I suppose, of course you site would end up being 1% code and 99% flash animation :)

Widgets are here to stay, portable pieces of software that jump from site to site with ease are everywhere. One line templates will continue pushing the dynamic envelope just like old coders continue pushing in the opposite direction for "proprietary applications".

One line open source to rule the world!

JS_Harris




msg:3450586
 11:50 am on Sep 14, 2007 (gmt 0)

Woops, I hit reply to the last topic on page 1. Where did this whole new page come from? :)

A good thread indeed.

Shadi




msg:3450601
 12:24 pm on Sep 14, 2007 (gmt 0)

This is one of the easiest and quickest way to output sites where you can work on design and coding completely independent of each other.

Perfect for those that want to produce sites quickly, once you have a template which you can edit in your favorite editor, making it as rich as you want, then your PHP engine will get the data, prepare it and place it into the template before output.

This method of usage is also perfect for maintaining tidy code on projects, anyone working on small projects should use a similar method to allow easier maintenance in the future for their code.

Nothing worse than a LARGE scripted PHP page covered in HTML and PHP all over the place.

Well done vince :)

Sylver




msg:3450630
 1:01 pm on Sep 14, 2007 (gmt 0)

Very nice for the first one!

For the recursive one, I having a hard time figuring out how it works.

A little help please?

For those who still don't understand the first one, here is a beginner explanation that might help:

A template is a document that contains the structure/appearance of a web page, but not the content. You may have noticed that on most websites, the general structure of all the pages is the same, but the content changes. So the general idea is to have a file which contains all the structure, and insert the content at the right spots.

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

preg_replace is a function that accept 3 parts:
1. a pattern - a code that is searched for
2. a replacement - something to replace what was found in "1"
3. the data in which the pattern is searched and replaced.(template)

It works like this:
1. "file_get_contents" get the template code
2. "preg_replace" finds the pattern inside the template
3. "preg_replace" replaces the pattern found by the replacement
4. "print" sends the result of the replace operation to the user's browser.

Now, if you look at the template code:

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

You see that it is just a regular HTML page but that instead of text, it contains placeholders like {title}. Using the template engine, PHP will replace the placeholders with the actual content

Here, preg_replace looks for a piece of text that starts with the symbol "{" followed by some text which is not a "{" (to avoid replacing more than expected) and ended with "}". (In the example above, {title}, {header} and {text}).

When it finds {title}, it will replace it with $title. Suppose $title = "My web page", the HTML code would now read:
<title>My web page</title>

So all you have to do is to define the variables $title, $header and $text, and the page will display the data.

With a system like this one, you can change the design of a single page, and all the pages reflect the new design.

vincevincevince




msg:3450693
 1:57 pm on Sep 14, 2007 (gmt 0)

Sylver, good simple explaination!

For the recursive one, I having a hard time figuring out how it works. A little help please?

Any takers? If not I'll write it up sometime tomorrow.

JonB




msg:3450988
 4:45 pm on Sep 14, 2007 (gmt 0)

hughie,there is no more "logic" in <?=$header?> than it is in {header} and it isnt any more complicated too. As designer ignores {header} so he can ignore <?=$header?>. Learning another "template language" like smarty for me is just adding another unneccesary step in the code. For example I am also using php framework codeigniter and my "templates" are basically pure html with <?=$variable?> ,just like {variable}.The logic is in "controler" and the structure is in "view". It is as simple as it gets :) So I am kinda using the template principle but i never really understood the need for adding another level between php and html,which,at least for me, only confuses everything.

vincevincevince - i think most modern editors have no problems with correclty embedded php - maybe they do it easier than correctly display smarty code.

dreamcather,maybe we didnt quite undestands eachother. My question was more in terms of why use additional .tpl system (especailly in vince3 example) when it can be done virtualy the same with pure html and php. Why cant designer design when he sees <?=$variable?> and has no problems when he sees {variable}? My codeigniter pages are completelly editable in dreamweaver etc since most of them have pure html with <?=$variable?> in it.

Sylver explained the template principle nicely but why additional .tpl level? <?=$variable?> works exactly the same, logic(can be programed in php and then included in the begining of "structure" document) is separated from structure,is redesignable etc...

maybe it is becasue of the simplicity of the examples but i still dont see any real benefitrs using tpl and {variable} system over just <?=$variable?> system. php itself is a kind of templating language and this is quite enough if you write quality code.

here is interesting (a bit critical to templating engines)link that also asks why not use the php alone(with examples)?
<snip>

[edited by: JonB at 5:14 pm (utc) on Sep. 14, 2007]

[edited by: dreamcatcher at 6:08 pm (utc) on Sep. 14, 2007]
[edit reason] no urls as per T.O.S [webmasterworld.com].Thanks [/edit]

kapow




msg:3451107
 6:39 pm on Sep 14, 2007 (gmt 0)

Thanks Sylver: For an explanation for the rest of us.

I have the feeling I'm missing something important here. As a small company creating and managing lots of small websites: We like templates a lot! Usually we us php-include for main sections of a page (Header, Menu, Footer etc). We have:
- The content in very plain html pages (many of them),
- Header, menu, footer... (Only one copy) using php-include.
- Any clever php scripts also stored once in a separate folder and included where required.

DreamWeaver is very good at not displaying php stuff in the visual display. All of this works very nicely and efficiently for us.

But what is this thread saying that I am sure I am missing?

JS_Harris




msg:3451280
 10:21 pm on Sep 14, 2007 (gmt 0)

It's saying that open source php + mysql coding is light years ahead of its nearest propriatary competitor. You mentioned Dreamweaver which is great, until you learn how powerful php can be, and then you'll silently cus when you need to work with a customer who used dreamweaver because of how clunky it will feel.

Thats not a poke at dreamweaver, it's a statement about how powerful what Vince mentioned is.

<?php
get_header();
if (have_posts()) :
while (have_posts()) :
the_post();
the_content();
endwhile;
endif;
get_sidebar();
get_footer();
?>

An entire wordpress blog anyone?

[edited by: JS_Harris at 10:25 pm (utc) on Sep. 14, 2007]

Gibble




msg:3451437
 3:47 am on Sep 15, 2007 (gmt 0)

js, you don't really need that if in there...I think

hughie




msg:3451591
 11:29 am on Sep 15, 2007 (gmt 0)

JonB, there is more logic, not a lot but there is. There are more things to go wrong and when you're working with WYSIWYG tools you see "php" rather than {header} or similar.

however at that level of simplicity we're splitting hairs. when things get more complicated php/html combo gets cluttered where as a good template engine keeps it nice an simple.

My designer has never been so productive since I switched over to smarty at the start of the year, and that is the crux of it. Template Engines increase productivity for both designers and developers.

vincevincevince




msg:3451606
 12:09 pm on Sep 15, 2007 (gmt 0)

For the recursive one, I having a hard time figuring out how it works.

As promised, an explaination. I'm going to break it down into bits. Beginner unfriendly I'm afraid.

print preg_replace("/\{([^\{\}]*(\{?[^\{\}]*\}?)[^\{\}]*)\}/e",'((strlen(\'$2\'))? (eval("return preg_replace(array_fill(0,sizeof($"."$2),\"/\".preg_quote(\"$2\").\"/\"),$". $2,implode( array_fill(0,sizeof($"."$2),(\"$1\"))),1);")):($GLOBALS["$1"]))', file_get_contents("template.tpl"));

Split up:
print preg_replace("/\{([^\{\}]*(\{?[^\{\}]*\}?)[^\{\}]*)\}/e"
Matches {....} pattern as before, nested inside it is an optional second {...} pattern. The first multi-character match of the pattern ([^\{\}]*) being greedy will eat the whole match so long as there's no { or } inside it. i.e. the second matched string will have zero length if there is no { }. As before the /e modifier causes the 2nd argument (replace argument) of preg_replace to be executed by PHP.

,'((strlen(\'$2\'))?
This is an inline-if. If you're not familiar with it, the format is (if)?(then):(else). Here I enclose the whole if in an additional redundant brace for clarity. The 'if' part checks the length of the 2nd matched string, i.e. the nested {...} pattern. If it is non-zero then this equates to true and we use the first branch of the if, otherwise we use the second.

(eval("return preg_replace(array_fill(0,sizeof($"."$2),\"/\".preg_quote(\"$2\").\"/\"),$". $2,implode( array_fill(0,sizeof($"."$2),(\"$1\"))),1);"))
$2 is the name of the nested {...}, i.e. the array name through which I loop. $1 is the string which I'll repeat. I use preg_replace($search,$replace,$source,$limit) with arrays for search and replace - in this mode it uses each matching search-replace pair in turn.

You'll notice everything is enclosed in an eval() and written as a string. This is very important; it forces the values of $1 and $2 to be substituted before the code within it is parsed. Otherwise, the nested preg_replace redefines $1 and $2, rendering it impossible to use the values from the outer preg_match in the inner preg_match. That is also why I broke the variable variables $$2 => $"."$2, etc. - otherwise I'd be trying to insert arrays into a string...

I'll expand upon each of the arguments below:

preg_replace(array_fill(0,sizeof($"."$2),\"/\".preg_quote(\"$2\").\"/\")
The search array is an array of identical entries, as I search for the same text to replace each time. To create this, I use array_fill() which will give me an indexed array starting at 0 and of the same length as the number of entries within the array named $2. To find this size, sizeof() combines with Variable Variables -> sizeof($$2). The string I search for is the field name $2, however I need to make this into a regular expression by surrounding it with / marks and passing it through preg_quote(). I don't use str_replace() because I cannot set a limit parameter for str_replace().

,$". $2
The replace array is just the array which is named $2, by variable variables that is referred to as $$2.

,implode(array_fill(0,sizeof($"."$2),(\"$1\")))
The $source text we pass into preg_replace() is string $1, the repeated string, ready-repeated by the number of items in the array named $2. To do this I use the same array_fill() method as for the $search array, but then I implode it all to mke one long string.

,1)
We add the optional fourth argument to preg_replace(), $limit, which we set to 1. That means we only replace one instance of $search[?] from $source... neatly filling in the replacements found in $$2 one at a time.

:($GLOBALS["$1"]))',
Back up at the inline-if, this is the else statement for where the pattern has no nested {....}. $GLOBALS["$1"] is equivalent to $$1, but due to the fact that when $2 is true, $1 is not a valid variable name, I use $GLOBALS["$1"] instead (otherwise it would be :($<div>{color} Cars</div>)... which would throw a fatal error). If you're going to have " within the outer {...} pattern, then you'll have to put in an addslashes() around that argument inside the $GLOBALS array.

file_get_contents("template.tpl"));
Finish off with the template itself for the top-level preg_replace()

Sylver




msg:3451708
 4:24 pm on Sep 15, 2007 (gmt 0)

Thanks a lot for the explanation, Vince!

This is quite brillant.

I will have to try it a few times to really get it, but now at least I understand how it works.

jaski




msg:3454085
 5:52 pm on Sep 18, 2007 (gmt 0)

Very nice stuff indeed.

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.
Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About
© Webmaster World 1996-2014 all rights reserved