I develop my web applications using only PHP for the view files and I don't feel limited 开发者_如何学编程in any way, but I hear there's a consistent number of developers advocating "external" templating engines. So what do template engines offer that simple PHP lacks?
I'm looking for practical things, so I exclude the following:
- babysitting bad developers (i.e. use a template engine because it forces you to not mix code into presentation)
- conciseness of syntax (I have mappings in Vim for things like
<?php echo $stuff; ?>
, using curly braces wouldn't make any difference) - easier syntax for non programmers (I develop alone so that's not an issue)
New Syntax
Some people wont agree, but since I've been using Twig the "for ... else" feels right. It might not be a lot, but it keeps my templates that little bit cleaner.
{% for row in articles %}
Display articles ...
{% else %}
No articles.
{% endfor %}
Automatic Escaping
You can have the template engine automatically escape any output. This is great as you no longer have to repeat htmlspecialchars ... everywhere. Twig does this nicely.
{% autoescape on %}
Everything will be automatically escaped in this block
{% endautoescape %}
Template Inheritance
Another feature I like is the ability to extend base templates. Here's a basic example
base.html template
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
{% block head %}
<link rel="stylesheet" href="style.css" />
<title>{% block title %}{% endblock %} - My Webpage</title>
{% endblock %}
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %}
© Copyright 2009 by <a href="http://domain.invalid/">you</a>.
{% endblock %}
</div>
</body>
child.html template
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{% parent %}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}
<h1>Index</h1>
<p class="important">
Welcome on my awesome homepage.
</p>
{% endblock %}
A child template can override blocks for page specific styles, content, etc ... You can also notice the use of {% parent %} which grabs the parents content so you don't lose it all while overriding.
I recommend you give Twig a go. Extremely useful.
Separation of concerns.
This sort of things comes as standard when using a MVC/MTV approach - where the presentation of data is necessarily separated from the display of data, but not if you're using plain ol' PHP.
Using a template engine makes it easy to separate out what's being displayed from how it's being displayed.
I suppose you could argue that this falls under "babysitting bad developers", since a good developer ought to do this anyway, but in my view, a template engine makes it easier for good developers too.
Easy switching between views
With the current state of the web, I need to provide my information in different formats:
- A static html page
- A dynamically loaded view on another HTML page
- A JSON object of the data
- An XML feed of the data, used in my flash part
The information for these formats can be equal, only the view differs. Using some sort of template engine, I can quickly switch between these views.
With templates you can also delegate the resposibilitys of the presentation to designers. The designers can create templates, and the developers can work in the logic. It is also easier to keep the presentation consistent.
- I use my own "template" engine, quite basic stuff, assign
value
to[key]
and the sorts. - When I first looked for a template engine I found smarty, but it had so many security problems I ended up writing what I needed myself.
- You ask why ? because it has many features that can make your coding faster (stuff what you didn't think of and stuff you can delegate to the template system instead of your code)
- The majority of coders out there have chosen a template system and when working in a team you need to keep a standard.
If you'd like to develop applications that can be customized with a lot of different templates and layouts while keeping the design separated from the logic, e.g. for different customers, you may want to consider using a template system.
But if your applications just need one template and never change the layout a lot, then stick with what works for you, why change? :)
Some templating engines can compile templates leading to highly optimized transforms. Take for example the XslCompiledTransform in .NET.
Your non-answers look like real answers but phrased in a very condescending manner. For example:
babysitting bad developers (i.e. use a template engine because it forces you to not mix code into presentation)
I would call this an application of the Rule of Least Power. It makes your template much more useful for all users, not just "bad developers".
Restrictions are what make programming languages. PHP doesn't have an inline-assembly feature, and it's not because Rasmus thought you are all "babies".
I find myself using templating engines when I need sandboxing. for example, letting users of a hosted CMS edit templates.
First addressing the answers on here and the general background:
The primary reason people use them being is that that they usually make things a little more terse. It's questionable as to whether this is always a net benefit. The increased cogantive load of learning a new language and not having the flexibility of your host language at hand can eventually end up offerring more drawback than is offered by using a templating language. Twig in particular requires manually exporting core PHP functions to it. The best templating languages that seek to be terse would be better off instead extending PHP using the tokeniser.
Automatic escaping is another questionable feature. For a developer that codes very poorly, automatic escaping might be more secure but otherwise it weakens security, putting it out of mind and presenting the expectation that everything will be secure by default in any context. A really secure templating engine needs to know a lot about its context, sometimes this can't always be determined, only the programmer knows where something goes. If you need secure programming you need to have a developer that is not reliant on automatic escaping, period. This is also something that PHP actually can do, if you tokenize the PHP file you can separate raw text from PHP and wrap the PHP parts in output bufferring then apply any filter you like, so this is not a templating language exclusive feature.
Some templating engines can make pregeneration a bit easier and pre-compilation to make them faster, but this can be achieved with native templates as well. There's a necessarity to parse templates which often makes them less efficient and the process more complex for using them. The added complexity templates introduce is significant. This can often be abstracted away from you but will eventually come to bight you, for example caching issues (stale entries), performans issues, significantly more flutter and clutter when debugging, more layers and more code being excuted with much more that can go wrong, etc.
Many features such as extending templates you again do not need to use twig to achieve that. Similarly for things such as htmlspecialchars most people will create short helper functions for all of the functions they are using very frequently.
So where should you definitely use templating languages such as Twig?
Baby sitting bad developers is sort of valid, although I'm not sure that they should be considered developers if you have to use something like twig to try to contain them. You'll also miffle good developers you'll wonder why they are being made to jump through hoops to achieve otherwise simple things.
You might want to give templates to parties where you might want the HTML to be worked on but to not expose system internals, etc. This might be where you have a CMS for example, with users that can edit templates but are not the same as your developers. This related to the above but it's a more genuine case where you might have some benefit and that might be justified.
A similar case is where you might want to use templates between systems, in this case a templating language can be a portable solution. This might not only be where you have multiple backends but where you have unusual architectural requirements such as the forward facing servers rendering views from data derived downstream. Take this further and you might want templates you can render frontend or backend. If you only have to ship data to frontend because it can render views itself, this can be more efficient. However you may also have to fallback to backend for various reasons.
Another case is static analysis including across multiple languages. Most languages template effectively by string concatenation and arn't aware of the language you're producing. In some cases a templating language can provide a benefit when you can parse it fully, the language and the HTML. Another way to achieve this is to do your templating using HTML itself as much as possible to denote things, as in using classes, etc and the facilities HTML provides that can allow you to attach behaviour to things. A templating language can also be more parsable than PHP even if you're not able to also parse the language you're templating in. This can be used for optimisation or having templates that are more easily transpiled.
Your language really isn't suited to creating HTML and other languages. PHP is a templating language so in most cases the use of a templating language does little but incur substantial drag. However if you're using something such as Java then you're very likely to desire a templating engine. Templating languages are a DSL, but if you already have a DSL that does what they do pretty well then it's YAGNI.
Bespoke templating. Where you have a certain output format and domain that would significantly benefit from a customised templating language. This depends on your output format.
All of these cases are situation specific and not sufficiently common that a templating language should be used by default. Templating languages only address these points with varying levels of success (for example, many aren't HTML aware). If I were to rank Twig 10 out of 10 for how well it does each the average wouldn't be far off 5.
You can convert Twig into PHP but not PHP into Twig. This can sometimes be useful but it comes as a considerable cost as you lose a lot of the flexibility of PHP.
Of the small amount of Twig internals I've been exposed to the quality has also been poor, or has imported bad standards. For example the parser doesn't or at least didn't support perserving whitespace when I first tried it five years ago. I had a scenario where I needed to refactor, which meant I needed to be able to parse Twig, modify and output it again to rewrite code across thousands of templates, twig didn't support it and I had to rumage through the parser myself.
Similarly I recently investigated escaping for Twig. In particular the JS escaping stood out which supported escaping JS strings and other strange things rather than simply using json_encode. It's likely the custom escaping you'll get like that in frameworks is wrong. It's usually more reliable and secure to do it yourself (as long as you know about things like what happens if you JSON encode a string containing and template it as a javascript literal without sufficient escaping, for example).
In most cases the hundreds, sometimes thousands of lines of magic templating systems and other related systems implement for escaping, sanitising, etc are terrible practice, trying to guess your scenario or trying to cater to every possible one, adding more scope for bizarre bugs with data corruption, adding more chance of security blunders, etc. Usually you'll find the things like that in frameworks can be replace with a one or two line function that's more secure. You'll have other silly things as well sometimes like processing something over and over just in case because the framework is naive as to what you're doing where as if you make the things yourself you know exactly what you're doing and don't then have things like ending up sanitising the same string over and over.
精彩评论