Whats the best way to create my own template engine using php, to transfer html templates into actual websites, and replacing the placeholders with the actual data... well, let me solve my own question...
class Template{
$private $output = '';
public function Load_Template($template){
ob_start();
include($template);
$this->output = ob_get_clean();
}
public function Replace($data){
$this->output = str_replace(array_keys($data), array_values($data), $this->output);
}
public function Display($add_footer = true){
echo $this->output;
}
}
This would work for a simple Template like...
<div>{username}</div>
But what would be the best way to do it with loops in my template.
Lets say something like
<ul>
<li>{username}</li>//Loop this line for each user
</ul>
Also, I dont want to use a third party engine like smarty, I would just like to know how to do it myself. Thank you
How about use php itself?
<div><?php echo $username ?></div>
<ul>
<?php foreach($users as $user): ?>
<li><?php echo $user->username ?></li>
<?php endforeach ?>
</ul>
*note: Funky endforeach syntax explained here.
Honestly, if I had to whip up my own template engine in PHP, I'd just use PHP. Just restrict yourself to only using variable interpolation and loops within the "templates".
Writing your own template engine is a tricky thing. You're inventing an entirely new language, after all, albeit a simple one. For it to be very powerful (i.e., beyond simple string replacement), you'd probably have to write an actual stack-based parser rather than rely on str_replace.
You could do this with regular expressions, much as you could parse HTML with regular expressions, but it won't be very reliable, easy to read, easy to debug, or easy to extend.
You mention that you don't want to use a third-party engine like Smarty, but you are basically setting out to do the exact same thing that Smarty is doing.
Something that people often overlook when talking about templating in PHP is that PHP is a templating language. There's no reason you can't just use regular old PHP inside your templates. In fact, that's what it was originally designed for.
If you really want to build your own templating engine, then you're going to have to sit down and design a syntax for looping and whatever other templating structures you'll want to use. Something like [do 5 times] { loop code }. Make up whatever you want. Then you'll have to parse it with PHP, and modify the template to replace it with the looped structure.
It's a big job... using normal PHP would be much easier.
Well, most of the answer to your question is preg_replace_callback().
I agree with everyone in this discussion - I have never understood the use of proprietary languages for templating in PHP - you know PHP so just use that.
If you are disciplined (e.g. follow MVC architectural pattern) in keeping a clear difference between PHP scripts that do things, and PHP that display things, there won't be any problems.
A couple of ways that can help are calling your PHP template files .phtml, and using alternative PHP syntax which is a little easier to maintain in templateswhich contain both HTML and PHP:
<?php if ( $a == $b ) : ?>
<strong>True</strong>
<?php else: ?>
<strong>False</strong>
<?php endif; ?>
Related
I do not like spitting back html with php's echo, makes it hard to do and read nested elements. So I usually write conditions that write raw html and make it as readable as possbile when editing the file directly or viewing the output html through the browser. However, I cannot find a style that stays readable for long. Any suggestions?
<?
if($foo == $bar)
{
?>
<div>
<p>hello, world</p>
</div>
<?
}
?>
As you can see, it doesn't look too good. At least not to me, but it makes the browser output more readable so I can better check the it for any mistakes.
i dont want this:
<?
if($foo == $bar)
{
echo "<div>\n\t<p>hello, world</p>\n</div>\n";
}
?>
Is my approach incorrect to begin with? should I use php to output to a .html file? and just view from the browser for mistakes and do as much php as possible inside the php file?
Your right it's not nice, instead use proper alternative syntax, for content with a large amount of HTML:
<?php if($foo == $bar): ?>
<div>
<p>hello, world</p>
</div>
<?php endif ?>
I don't believe you need a seperate template language to write maintainable code, PHP is perfectly fine in outputting variables in HTML.
Really the problem is seperating your logic from your output which a template engine can't help with if your not structuring your code properly in the first place. For example stuffing it all in an index.php file or not using MVC whereas you don't put HTML with your logic.
If you have a large project or are overly concerned with separating your PHP from your views, or you want the features which come with a template engine like built in caching and slots etc, then use one. But maybe first look at learning a framework which will improve your overall codebase as most frameworks come with their own. Though essentially you can achieve the same thing including nesting partials and blocks/slots with a 20 line view class which uses ob_* functions, which doesn't require you to learn a new syntax.
Rant over.. :s
Use a templating system like Smarty so you can separate your logic from your display code.It also allows you to bring in a designer that can work with html and might not know php at all. Smarty templates read more like HTML than PHP and that can make a big difference when dealing with a designer.
Ansered by #boatcoder
You can learn here
Without the use of templating engine, your best bet is #Lawrence's answer or this littly modified syntax of your first exemple (trimminig space and php tag) :
<? if($foo == $bar) { ?>
<div>
<p>hello, world</p>
</div>
<? } ?>
I was always curious, is there any significant advantage or disadvantage of writing php inside html or vice versa
example:
echo '<ul>'
foreach ($items as $item)
{
echo "<li>$item</li>";
}
echo '</ul>
As opposed to:
<ul>
<? foreach($items as $item): ?>
<li>$item</li>
<? endforeach; ?>
</ul>
Since these essentially generate the same thing, when would you actually use one over the other?
Functionally they are the exact same and won't have an appreciable affect on performance, if any. It comes down to personal preference and readability - if one is clearer than the other and will be easier for others (or the future you) to understand, go with that one.
I personally find it better to use the latter if you actually have PHP in a mostly HTML file. The clear opening/closing tags match up visually with HTML easier. I find it can be hard to line up curly braces visually.
As an example, in the case of a MVC framework I would use the first way of outputting things in a controller or model context, while the second way in my view files. Some templating languages like smarty have similar looking constructs.
ie:
{ if [condition] }
{ /if }
The first one echoes meaningless strings from the IDE's point of view, whereas the latter one is a mix of HTML and PHP and will be handled properly by your editor. In other words, it's better to actually separate HTML from PHP as it allows your editor to parse HTML and provide some usefull features like syntax validation or autoclosing of HTML tags.
basically php is a server side scripting and html is client side scripting. So if it is php inside html then it generates faster response and you can format a better view. However for some scenario you might have to consider the other case for developing.
I am an MVC addict.
I have some views in plain PHP (not using any Templating Engine (TE) such as Smarty for getting good performance), but without Smarty my views are looking ugly and hard to code.
I'm wondering how can I make them look good (ie., human readable) without using any TE? At least I want to replace those <?php and ?> for sure, or if you have any other better idea?
It's just a start of my web application so please guide me to any better alternative if you have any.
Thanks.
In templates I use the alternatives of PHP like:
<?php if (true): ?>
<?php endif ?>
<?php foreach ($x as $y): ?>
<?php endforeach ?>
etc.
http://php.net/manual/en/control-structures.alternative-syntax.php
There's no PHP variation or syntax that allows you to replace <?php and ?> with { and }. If you want that, you'll need to use or write a custom parser for it, which means you're looking at a templating engine. No templating engine, no custom syntax.
So I've always developed PHP pages like this: <?php goes at the top, ?> goes at the bottom, and all the HTML gets either print()ed or echo()ed out. Is that slower than having non-dynamic html outputted outside of <?php ?> tags? I can't seem to find any info about this.
Thanks!
--Mala
UPDATE: the consesus seems to be on doing it my old way being hard to read. This is not the case if you break your strings up line by line as in:
print("\n".
"first line goes here\n".
"second line goes here\n".
"third line");
etc. It actually makes it a lot easier to read than having html outside of php structures, as this way everything is properly indented. That being said, it involves a lot of string concatenation.
I'm not sure about speed, but it's typically best practice to separate dynamic elements and the display of them.
Check out a framework like CodeIgniter: This has a "controller" and a "model" that grab data, sort it or do whatever you like with it, and then feed it to a "view" (some sort of template).
This paradigm is called MVC, and is a really, really valuable thing to learn about. I've found its chief advantage to be easier-to-maintain code. I don't end up with a monster document that I have to re-learn each time I approach it.
Resources:
CodeIgniter
MVC
The difference in speed is probably negligible, however, when **print()**ing out all of your HTML with PHP, the code can get very ugly, and makes it much harder to read than if you just have plain HTML.
Edit: Also, if you're are **print()**ing out static HTML that doesn't change, really what is the point? It gives you no added benefit.
Pros
None that I can see
Cons
Code that is hard to read
One more step in processing for the PHP engine, which although probably not noticeable, it is an extra step.
The speed is negligible - trust me, this will not be your bottleneck.
Along with any other MVC framework, you might want to check out a simple templating system, such as Smarty, which separates your PHP logic from your HTML and also does caching.
I don't know if it's slower or faster, but (in my opinion) it makes the code a lot more difficult to understand. Which I guess is why I don't typically do it.
It is almost the same from a performance point of view.
I would set the focus on the readability of the code. If you have a performance problem, figure out the bottleneck and cache it.
Is that slower than having non-dynamic html outputted outside of <?php ?> tags?
Well yes, it is... marginally. But that's not really the issue: it's all about the readability.
this way everything is properly indented
Your example isn't indented at all, which is fairly typical for the print-heavy, PHP I've unfortunately had to maintain!
Try this approach to keeping good, consistent indentation:
<ul>
<?php
// block of arbitrary code blah blah
//
$conditions= get_conditions_from_request();
$isadmin= $user->privileges>=PRIV_ADMIN;
?>
<?php foreach (select_things($conditions) as $thing) { ?>
<li>
<strong><?php h($thing->title); ?></strong>
<?php if ($isadmin) { ?>
<a href="/editthing.php?id=<?php u($thing->id); ?> (Edit) </a>
<?php } ?>
<?php h($thing->description); ?>
</li>
<?php } ?>
</ul>
(This presumes a function h that calls echo htmlspecialchars and u that does echo htmlspecialchars urlencode. Getting this escaping stuff right is essential to having a secure site, and is something that's almost always wrong in print-based PHP, as it tends to use "blah $var blah"-style templating without any escaping at all.)
Maybe not the best practice, but I choose to mix and match print() statements. For large chunks of layout code, I don't use print(), but if I'm rendering a complex if/else or for/while block and I'd be exiting the PHP block every other word, then I'll print out the non-dynamic text with the dynamic text.
Performance is very negligible at best. You can create a page, and put a timer on it. (Here is a tutorial on creating a script timer)
Output the exact same data both ways, and measure it with as many samplings as you can get, this should roughly tell you which is faster. I'm guessing very close to the same.
I have seen a lot of these pages with PHP embedded inside HTML, and I don't like it. As Alex Mcp suggested you should be thinking about a MVC model.
The problem with scripts embedded into html is the flow control and logic aren't easy to read, and there are some wierd problems that occur here and there. The best solution for me is usually to use Smarty or the Zend Framework to create template pages and then swap the data that goes in and out. Much easier to manage in the long run.
So we all know that you should always, not only in PHP, separate code from content/design/html. (I have seen people that say the opposite here today)
I mean, you don't want one of these in bigger projects, do you?
<?php
echo '<div id="blah"><b>'
. $username . '</b>'
. $stuff . '<more HTML mixed with PHP...>';
?>
But: What is a good approach to separate code from content?
I have been using a simple template system that replaces wildcards in templates mostly.
e.g:
<div id="blah"><b>%USERNAME%</b>%STUFF% <...>
(located in a single file)
Later you can just call a function similar to GetTemplate( 'myTemplate', array ( 'USERNAME' => 'Stranger' ) );
Finally, the questions:
Is this a good way of separating code and content?
How do you do that when not working with a framework?
Is there a better way?
you should realize that PHP itself is a templating language. your
<div id="blah"><b>%USERNAME%</b>%STUFF% <...>
differs from
<div id="blah"><b><?php echo $USERNAME; ?></b><?php echo $STUFF; ?> <...>
only very superficially. granted, PHP is quite stupid with its NOTICEs and WARNINGs instead of exceptions (a point Python has over PHP), and your custom implementation may more easily allow you to e. g. throw instead of producing a fatal error (oh the joys of Smarty) if putting logic into a template somewhere turns out to be the lesser of two evils (loops). you may want to throw if the template mentions an undefined variable (PHP would issue a NOTICE), etc.
Im not fan ov additional templating languages (that replace wildcards) instead i like to keep my templates pure php so my vertion of what you have done would be:
<div id="blah"><b><?php echo $username ?></b><?php echo $stuff ?><...>
echo GetTemplate( 'myTemplate.php', array ( 'username' => 'Stranger', 'stuff' => 'Stuff' ) );
function GetTemplate($templatePath, array $vars = array())
{
extract($vars);
ob_start();
include($templatePath);
return ob_get_clean();
}
I alos combine this with helper functions/object->methods as well for example:
<?php echo link_to($name, $url); ?>
function link_to($name, $url, array $attributes = array())
{
$attributes['href'] = urlencode($url);
foreach($attributes as $attrib => $value)
{
$attributes[$attrib] = $attrib."=\"$value\"";
}
return sprintf('<a %s>%s</a>', implode(" ",$attributes), $name);
}
I generally apply helpers like these to commonly used tags/structures as well as having a general purpose html tag one that looks something like content_tag($tag, $content, $attributes); This helps me avoid a php echo for tons of attributes for random tags. I obviously dont use it for every html tag i use only for ones where it makes for better readability than a ton of echos.
As far as templating engines go i dont really see the benefit as php is templating language. As far as non-programmers/coders they have to leanr the syntax for a loop and a variable any how so i dont see how changing it to wildcards or the {} syntax of smarty adds anything.
There is a tried-and-true Templating Engine for PHP called Smarty. It isn't part of a massive framework, which is a huge plus for me. Smarty supports caching and has other performance boosts over traditional find/replace templating due to it's "compilation" of template files.
Big projects like, phpBB work using templates. Its slightly more complicated as they also allow for (for)lists, including other templates and other advanced features. You definitely want to separate code and content.
As a bonus this allows non programmers to make your html.
The approach of the Zend Framework which uses PHP as the template language (which does not add an extra parsing overhead) seems like a good apporach
Another way I really like is the approach used by limonade framework which uses ob_start() and includes to actually handle the templates