While I have been reading through countless posts about using PHP as a template engine (using output buffering), I'm still trying to make a case for it.
As I'm wondering if I could use PHP as a template engine for a web app (users will be able to change the layout themselves) -- I still don't find any info regarding the following:
Store the templates in a MYSQL database
Eval them
BUT only include functions that are whitelisted (to give them only access to a limited set of functions -- while, foreach, etc ...)
Anybody looking for the same solution, but can chime in with a bit more information? That would be quite nice.
If you can't trust the user editing the template, you are better off using a separate templating language.
Note that many template languages like Smarty provide code execution functions as well. You may need to disable those in the engine's configuration.
Disabling all potentially dangerous functions in PHP is a very arduous task, and easy to screw up. See Exploitable PHP functions
PHP is not suitable as a template engine for your purpose. You should use a proper template engine with sandboxing support for that: Twig.
That is probably a quite difficult (but interesting, if you are into the topic) task, because it involves building a small PHP parser, which can flawlessly identify any function call or method call (because if you miss one, you're screwed/hacked/...) and then check if all your matched function identifier tokens are in your whitelist, and otherwise deny eval-ing. For generating your Parser, you might want to check out the PHP_ParserGenerator, which unfortunately does not seem to be maintained anymore, or lemonPHP/JLexPHP, which may be more up to date, but you need to use Java to generate the Parser.
Because of all this is a quite tedious task, most people resort to using a custom (made-up) template language, which is similar to PHP, but not identical.
Popular PHP template engines are, among others:
Smarty
Twig
PEAR Template Engine
Savant
More can be found here and here
Related
I'm using PHP as a template engine in an MVC-style application. However, we now have the need for the templates to be edited via the web-front end. Is there a way to make this safe and secure, so a user who has the rights to edit a template then doesn't have the ability to run dangerous code on the server? Or, should using PHP as a template engine be abandoned, and use one of the many other templating engines, such as Smarty?
I highly recommend twig. Twig is very nice in that it is very modular an extensible, so you will end up with a template engine that's as simple and as complicated as you wish.
It is also very fast with caching turned on in production. It is also very safe in that it cleans and filters what is displayed to the user, so no arbitary PHP code can be executed by the person editing the template.
If you really like to make it secure: don't use PHP for your templates.
There is no clean way to treat those templates different from your application code.
What you are looking for in fact is a template engine like Smarty or FLOW3's FLUID (I prefer the latter) as they have been built for exactly this demand (amongst others).
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I am building a website in php with lot of pages and we are a team of 9 working on it. So just want to explore that when should we use PHP template engines and when we shouldn't. So I'm interested in pros and cons of using PHP Template engines so I can make a decision whether to use it in my case or not.
PHP is a template language.
In my experience so far with various template systems, the conclusion was pretty simple: use none.
Instead, write PHP as it should be written! Never do anything inside a .html besides echo and for/foreach. If you write the code based on a design pattern like MVC this becomes even more obvious: just echo and foreach inside and explain the frontends they should never mess with the code inside <?php and ?>.
It worked for me ever since. It usually was harder for me to explain them Smarty than to explain to never mess with php.
Template systems also add weight to your server (sometimes is just a bit, sometimes you may feel it). It may seem over-optimization at first, but I prefer to keep it as simple as it can be.
Note:
Smarty, for example, is HARDER to spot in a .html file because the only Smarty syntax highlighter I know is a NetBeans plugin and it's pretty beta. PHP, on the other hand, has it syntax highlighted in any decent editor. Also easier for the frontends to spot and not mess with.
Wrap up
Cons (for using template system)
Increases server load (lighter or heavier, doesn't matter - you can see it)
Induces bad practice (logic wrapped inside template language syntax)
No syntax highlighting for template languages' syntax - harder to spot (for coder and frontend)
Time spent learning it and teaching it to the frontends
Harder to explain to the frontend team (I've taught basic PHP to frontends several times - while many more were already able to write their own 'beginner-level' PHP; I have never taught a frontend Smarty so they can do something other than {$var} )
Makes you avoid the REAL problem: logic and presentation separation!
Adds extra weight to your project
Pros (for using template system)
Extreme boredom (probably the only valid argument)
Template system replacement
Logic and presentation separation (I'd suggest MVC for this task and for the pros it provides for other fields of development: easier maintenance, abstract database and so on)
Force yourself to write in the view only echo and iteration for echoing: foreach and for should accomplish 99% of the iteration needs; you can also use while and do while
For me, when deciding if a separate template engine should be used or to just use PHP for the templating, it always boils down to this:
When to use template engine
When you must restrict (sandbox) the code that can be run in the templates.
When not to use template engine
All the other times.
The PHP purists will tell you that PHP is itself a template engine. I consider myself a purist on this matter, and recommend just using PHP. It even has an alternate syntax for if and loop blocks that are pretty much designed for template-style readability.
Some people, however, still prefer using template engines, such as Smarty. There are a number of things to consider if you do choose that route:
Who's going to be maintaining the template? If the person maintaining the templates already knows PHP, there's no point in making them learn a new, pseudo-PHP template engine. If they don't know PHP, then it's still questionable, depending on their background, since most template engines just implement a syntax not unlike PHP tags (such as <% %>)
How complicated will your templates get? Some template engines are extremely restrictive in what you can do in the templates (forcing you to put everything in the controller, some almost to the point of uselessness or unnecessary hoop-jumping), while others are about as permissive as raw PHP (which many would argue defeats the purpose of a template engine).
How much does efficiency and speed matter? Template engines add overhead. Period. Converting the custom tags to PHP tags takes resources. How much they add and how much it matters depends on a number of factors (including the engine itself). If you need more speed from your site, then I'd vote the template engine as among the first to go.
As I said, I also recommend using PHP as your template "engine," but do be aware of some of the pitfalls. Mainly, it's really easy to add more logic than necessary into your templates. Make sure you have a rule to only include echo, for/foreach, and basic if blocks (such as if is_admin() and the like), and make sure to enforce it.
There is absolutely no reason to use a php template engine.
The seperation of logic and view is a obligation. This does NOT mean using a template engine.
With a template engine you have to learn things that have nothing to do with php or to do with anything else. Each person who have to modify the sources of smarty or an other template could be annoyed about that crap of anything useless and hindering mess.
PHP enpowers your templates an give you all possibilities in each way you use it.
With a dozen of advices PHP ist secure enough. Don't feel secure by using a template engine without knowledge of the tricks behind. Smarty can not secure public editable templates.
Look for Designpatterns. View Helper and MVC. Hold your code simple and well structured is meaning being smarter than smarty/any-template-engine ...
I would suggest using some method of good separation between your display logic and other data fetching maniuplation. Implementing MVC is a great way of doing this and most of the PHP frameworks provide an MVC framework.
This allows everyone to work on much cleaner code and allows the templates to remain simple so that those less technical (front-end designers for example) are able to go in and edit them.
A template engine should be used when there is a great deal of presentation that is duplicated across multiple web pages and you have a desire to separate business and application programming and logic from presentation.
Benefits of this separation are:
tighter, more readable and error free application logic
alter presentation without altering core logic files
altering presentation dynamically at run time
While it is technically true that php is itself a template language it is more accurate to describe it as a web programming language with built in templating. On the other hand it is also true that most template engines consume templates with programming directives built in. This implies that a reasonable balance exists between too much template within php and too much programming within a template. The better the balance the easier your coding and the more flexible and extensible your application will be.
Take for example php code that retrieves your last 10 blog posts and writes them out to a DIV tag on your blog when that code is invoked. If that same code was duplicated to create an RSS feed you would have the same code in two places requiring the need to maintain it in multiple places when the logic changes.
If rather the exact same code is invoked under the control of a template engine then you have the same code writing to two different forms of output based on whether an RSS/XML or HTML template was provided. If the template engine is written well the php code neither knows nor cares what type of template is provided to it. The php could just as well be outputting HTML, XML, SQL, PDF, or text!
Having implemented many websites in Classic ASP and PHP over time I found that a good template engine saved me many long hours of programming and debugging and because there was no real template engine for Classic ASP I wrote KudzuASP to address the problem. You can find the related project KudzuPHP on my website and it is free. There is also a plugin for Wordpress based upon it.
You should always use some mechanism for separating markup from code just like you shouldn't embed CSS in your HTML. There are too many options to give you a flat answer. There are template engines like smarty or fasttemplate, then there are frameworks with templating systems (like cake, code igniter, etc). You should evaluate them individually based on your needs
I would just use php for your template engine. No extra overload from having something like smarty. They just need to know basic php. You can signify the template files with a .phtml file extension...Why would you want to use a templating engine?
Just to be clear, there should only be echos and foreachs inside the .phtml template files, no core code should be done inside of there.
Have you tried Stamp Template Engine?
It still increases server load; however I think it fixes the other cons of template engines. Unlike Smarty and all the other template engines for PHP, StampTE is completely logic-less. You only mark regions with proper HTML comments (most designers and front-end engineers already have these markers just for readability). It relies on these markers to offer cut-and-paste functionality to back-end developers. Back-end PHP programmers can copy-and-paste these regions from the template (like paper models) and construct website and web application GUIs with it. Also, they have a very friendly API themselves. For instance to cut a region like:
<!-- cut:siteMenu -->
<nav>
<ul>
<li>...</li>
</ul>
</nav>
<!-- /cut:siteMenu -->
They can use object oriented notation:
$template->getSiteMenu()->setLink( ... ); etc..
I think this is really cool.
http://www.stampte.com
Indeed, separation and reuse are the keywords here.
The best way to develop and to segment the work load within a team, is when the Web Designer (integrator/html-ist and so on) has no chance of breaking down the programming part (database, files, sessions, syntax errors and so on).
I recommend using the FigDice Template Engine, which operates a very neat separation between the Logics (program, database, files, algorithms, etc.) and the Presentation (the views and the information they present) in total security.
FigDice supports of course macros (reusable parts of a file), inclusion, iterations, and many more features, and also provides an exclusive approach to the Presentation/Logics separation, with the inversion of control of the data-providers (the Views pull the information they need to display, rather than letting the controllers push the data into the templates, as is usually the case with virtually every template engine).
This makes it possible to the HTML Designer to really decide what he wants to present and when and how, without any risk of breaking down the code.
I would be happy to get feedback and comments.
Thanks
Some years ago I created a small website in PHP that now has grown and as you can probably guess it's quite a bit of a mess. Although I do have a separate template that does the final outputing of the html, I still end up having do handle a lot of the html in the 'business logic' part of the code.
My main problem is that the page contains various widgets (like 'latest entries', ads, etc.) that change from page to page and thus their html-(template-)code can't be hardcoded into the template. In fact even the main-content-container is a widget since the page-structure (or layout) is always the same.
So I end up having an array with $templateData['mainContent'], $templateData['widget1'], $templateData['widget2'], etc. that is generated in the business-logic part of the code.
How do I solve this?
Having looked around for a while there seem to be 2 ways to solve this:
The obvious way would be to use a dedicated template language with inheritance and includes like django does, but given how complex these languages are I'm not really willing to learn yet another one of them. Also what I noticed during the time I spend with django was that it's not particulary fast (especially because it tempts one to use that templating for css and javascript too).
The other option would be to use the templating features that PHP itself provides. But that would mean that every widget would have its own php-template and would generate its html-code by including the template-file and trap the result using output buffering. Is this a good idea? Since I still end up with HTML inside of the variables inside the logic-part. Also, doesn't this abuse output buffering for something that it wasn't intended for? And what about performance? (where is the buffer that I'm writing/reading/flushing from? How expensive are calls to ob_* functions?)
From what I've seen there are advocates for both variants. Personally I like option 2 more (since it's sort of what I'm already doing), but the html-in-variables feels very wrong and I doubt wether I would be solving anything this way.
Is there maybe another option? How have you solved this problem?
Why not to let each widget just include it's template?
So, you will have to just call widgets from your main template.
I had this problem before and I had almost the same ideas/questions that you currently have. I obliged myself to learn a template language. Enter Twig a lightweight template language that is influenced by Django's template language. It has a very small footprint, almost invisible in terms of memory usage.
Give yourself some time to get used to it and then decide if you want it or not.
assign those nice arrays to smarty and learn to iterate them on the tpl files.
it's easier than it seems.
when you need to include many times the same piece of html/php you just re include it.
http://www.smarty.net/
is smarty fast and reliable? yes
One idea would be to create template-driven / view-driven pages accessing a web service or an API serving all the data you need.
You could link URLs to templates, and the templates call data retrieval functions either via web service (AJAX style) or statically.
The business logic part is then limited to processing of inputs and preparing generic retrieval and provide mechanisms for e.g. filtering or sorting, while the templates determine how to filter, how to sort or how to paginate etc.
I suggest that you use a proper object-relational mapping (ORM) framework / ActiveRecord pattern (see here on StackOverflow, or in Wikipedia) that allows you to use generic retrieval objects that can be re-configured by the template to suit its needs (such as the aforementioned filtering and sorting).
The actual retrieval would then be done in the template when needed by calling a special method like find(), load() or similar on the retrieval objects.
EDIT:
Regarding template frameworks as others suggested, I do not like them very much as they often duplicate functionality already found in PHP, reinventing the wheel by adding yet another parser layer; a benefit you get from any decent template framework however is caching (there may be some PHP-based templating engines out there that also support caching).
Multiple options
There are several ways to do it.
Here's a couple of strategies worth considering :
Use plain PHP views that you encapsulate (include) in a method of a PHP object. This is how CakePHP implements its views.
Load a HTML file with placeholders like <% %> as plain text and use regex to replace the content
Load an HTML file and parse it as XML or HTML. Then, you can use something like Symfony's CssSelector component to add, remove or replace content the same way you'd do it with jQuery. Then, render it back to plain text and echo it.
Use one of the following popular template engines :
Smarty
Twig
Latte
Mustache
...
Best option?
Which option is best? I guess it depends on your use case :
Plain PHP will always give you the best performance, but it's also the least readable option.
If you like to go through your HTML code the same way you do things with jQuery, you might want to use a library like DOM-Query.
If you're looking for a well-tested templating engine that can be used both in backend and frontend, Mustache is the way to go!
...
I want to limit what PHP functionality my users have access to.
For instance there is an object $data and the user likes to use if for and echo.
Obviously allowing him to write PHP would be a serious vulnerability.
Is there any way to run this PHP in a sandbox or would you recommend any lightweight PHP template engine?
If you don't have your own server you probably don't have runkit. But what you do have (probably) is Tokenizer! Using the Tokenizer you may look through the given source code and abort if you find an invalid token. Here an example how to validate an array using this. You could do same for your purpose. The PHP documentation has a list of tokens. If you need help deciding which tokens to allow or to disallow, please say so.
€dit: And obviously I do recommend to use Twig, too. It is so nice - and has sandboxing!
The only one I know so far is runkit.
The runkit extension provides means to
modify constants, user-defined
functions, and user-defined classes.
It also provides for custom
superglobal variables and embeddable
sub-interpreters via sandboxing.
Update:
I could find these two links regarding zend and runkit you should take a look at:
http://framework.zend.com/wiki/display/ZFPROP/Zend_Http_Server+-+Mat+Scales
http://www.dunfy.me.uk/?p=38
Along the lines of smarty, give twig a try!
There is also a very robust extension system which allows you to allow/disallow built-in or custom tags, token parsers, nodes, etc in the template language itself. This way, users can have basic logic (conditional statements, "functions" (blocks) and iterators) without resorting to the evils of eval.
Tried Smarty? http://www.smarty.net/
The PECL runkit extension does provide sandboxing, but it's possibly a bit overkill for what you want to do
PHP Fat-Free Framework has a template engine that prohibits the use of PHP code and allows you to define which functions can be used inside HTML templates.
There's also a real sandboxing feature that makes functions and include files independent of others, i.e. variables/functions in one include file are not known to others, so you can have a function with an identical name as another include file. This may be of some use for (dysfunctional) developer teams.
I found that using Smarty with PHP, sometimes extra time will need to be used for
1) using quite different syntax than PHP itself
2) need to check small cases, because documentation doesn't give finer details, such as for "escape"
http://www.smarty.net/manual/en/language.modifier.escape.php
it doesn't say escape:"quotes" is for double quotes only or for single quotes as well, so you need to write code to test it. Also for the case of escape:"javascript" -- can't tell exactly what and how it is escaped.
3) for something complicated, need to write helper functions or modifiers, so it needs a creation of new files and ending up doing it in PHP again.
by the way, does using Smarty provide a good speed up over use PHP alone? thanks.
First, PHP is a templating language. Keep that in mind when you talk about using a template system for your PHP-based web applications.
The only 'real' argument that I've ever heard for using ANY templating engine was that they provide a simpler language for template manipulation which can be handy if you have template designers who don't know PHP and whom you don't trust to learn to use PHP judiciously.
Regarding these arguments, I would argue that if your template designers are not competent to learn enough PHP for template design, you should probably consider finding new template designers. Additionally, PHP itself provides a different syntax for control statements that you might use in a template versus in code. For example:
<? foreach($array as $key => $val): ?>
<?= $val ?>
<? endforeach; ?>
VS:
<?php
foreach($array as $key => $val) {
echo $val;
}
?>
Personally, I believe that templating engines arose in PHP because:
That's way that other languages do it
Better PHP programmers realized that they needed a way to enforce separation between presentation and application logic and templates were an easy way to do this.
The first reason is just kinda silly. The second reason can be overcome with a little self-control and even a rudimentary understanding of the necessity of separating layers in an application. The MVC design pattern is one way of approaching this problem. As far as exercising some self-control, my rule is that only necessary loops and if statements get used as well as functions that filter, escape, format the output for the screen.
Having used Smarty extensively, I can honestly say that it always presented me with more hurdles to get over than it did solutions. If anything, switching to PHP-based templates is what has actually decreased development time for both templates and code.
I don't like templating engines. I find them very lossy and resource-intensive for PHP.
With MediaWiki, around version 1.6.x we backed off using Smarty by default and just use PHP's built-in templating, with a great improvement in performance.
I've found that most of what people want to do with a templating system (add links, change colors, remove text or sections of the page) are better done with a simple system of event hooks.
Laconica, the open microblogging platform, doesn't do any templating by default. We have a plugin for people who are crazy for templating.
Smarty is certainly one of the best template engines out there. In my experience though people would be well advised to think their use cases through more thoroughly before they use any templating engine on top of PHP at all.
First, PHP itself is perfect for templates. Pretty much the only justification for using another templating engine is if you're allowing untrusted users to create or edit templates, since they could execute all kinds of badness. So, if your project has user-editable templates, use Smarty. If not, stick with PHP.
If your problem is separation of code and layout, I suggest you look into implementing a lightweight MVC-style execution model. Or, to put it more condescendingly, if you have deeper logic code in your template, it's probably time to do some refactoring.
Performance is another consideration. Yes, rendering a Smarty template comes with a cost. But after it's done, the output should be cached, leading you to improved execution times. Same goes for PHP templates. PHP allows you to implement all kinds of granular caching models through the use of its output buffers. But beware of premature optimization: do that only after you're code complete and have identified what the actual bottlenecks are!
The biggest cost when using Smarty or any other engine comes in the form of developer time. It's another layer of complexity and inevitably you will find yourself in situations where you have to trick the engine into doing what you could have accomplished within pure PHP all along.
I like template engines and think they should be used, but in the particular case of Smarty, I think it's waste of time, because it's not a significant improvement over PHP as templating language:
The new syntax is still based around old concept of special tags inserted in random places in the document.
Because Smarty does not understand HTML's syntax/structure, it cannot not help you to create valid/well-formed HTML. Smarty's tags violate HTML's syntax, so once you add them, other standard tools can't help you either.
Smarty's output, just like in PHP, is insecure (unescaped) by default and you have to remember to add |escape everywhere where you output data in HTML.
There's one particular PHP template engine that I've fallen in love with, which fixes all those problems: PHPTAL.
It's still something new you have to learn, and it's a depenency for your application, but I think having XSS and ill-formedness problems solved makes it worth the trouble.
PHPTAL just like Smarty is compiled once to PHP and cached, so performance is comparable to raw PHP.
Pros
No PHP in your HTML files (Allows both PHP and HTML identing)
Pipes {$var|default:"None selected"} {$var|urlencode}
Foreachelse: {foreach item=row from=$results}{$row.name}<br>{foreachelse}No results{/foreach}
Themable websites/pages (Using only CSS has it limits)
Cons
Other language syntax
Not always obvious code {"Y-m-d"|strftime:$timestamp} {$array|#var_dump}
Slight overhead
I can highly recommend the "template" approach(mVc), but both Smarty and plain PHP are up for the task.
As far as I know Smarty is one of the best template engines speed wise. Maybe it takes a while to get used to it. But if you are not working on the system alone and the amount of html and style files is huge it speeds up the development significantly.
While working on my last project the design was changes a couple of times but logics was the same. I guess that's the best example when Smarty or any other template engine helps a lot.
Personally I use Blitz for templating. On the site the author claims it is the fastest templating engine and provides a (biased?) chart over performance between different templating systems for PHP. I haven't used smarty myself, but this may give you some hints on its performance.
http://alexeyrybak.com/blitz/blitz_en.html
Using Smarty as a templating engine will probably not be as performant as not using it, as it is an extra layer of software, i.e., a templating language on top of a, erm, another templating language. On the other hand, if you use the caching feature properly you could realise overall performance gains.
Smarty templates are pre-compiled before being output to the browser, which involves writing temporary files to disk. This step surely penalises performance, at least a little.
If you are confident in your ability to keep implementation and presentation separate, and have no real interest in server-side caching, you should probably just use pure php templating. Some MVC frameworks such as Zend Framework have their own PHP-like templating systems.
On the other hand, smarty is a decent way to enforce a neat separation of presentation from implementation, particularly where it's unclear as to what belongs where. It might help discipline you to enforce this necessary separation.
That said, I use Smarty in most of my PHP projects, as it reminds me of Java-Server Tag Libraries (JSTL), which I'm very, very used to, and fond of.
Using a Smarty or not is more or less a philosophical position.
I use it, although I don't use much functionality. Using it this way, templates tend to be be very simple. Pass an associative array with parameters, iterate through its components and insert required elements in the result page. This keeps templates clean and (hopefully) free of business logic.
Additionally, extending Smarty is quite simple.
As an example, I added a styles parameter to the fetch() to have a fetchUsingStyle(). This allows me to switch between different layouts of a site quite easily.
Furthermore, my fetchUsingStyle() searches various locations for a template: First tries to find the current style. If not found, it tries to load the template using a default style. Last, it tries to locate a pure static dummy file, a placeholder for something to be implemented later.
Try to Use Smarty with MVC pattern such as Codeigniter , Its better than core PHP
Why use a template engine when you can just use your html files and inject php code where you need it? you can do this with Psttt! templating engine for php
full source code here http://github.com/givanz/psttt