与仅使用 PHP 相比,模板引擎的真正优势是什么?
我仅使用 PHP 作为视图文件来开发 Web 应用程序,并且我不觉得受到任何限制,但我听说有越来越多的开发人员提倡使用“外部”模板引擎。那么模板引擎提供了哪些简单 PHP 所缺乏的功能呢?
我正在寻找实用的东西,所以我排除了以下内容:
- 照顾糟糕的开发人员(即使用模板引擎,因为它迫使你不要将代码混合到演示文稿中)
- 语法的简洁性(我在 Vim 中有映射,例如
< ;?php echo $stuff; ?>
,使用大括号不会有任何区别) - 对于非程序员来说更简单的语法(我单独开发,所以这不是问题)
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
新语法
有些人不会同意,但由于我一直在使用 Twig,所以“for ... else”感觉是对的。它可能不是很多,但它使我的模板更加干净。
自动转义
您可以让模板引擎自动转义任何输出。这很棒,因为您不再需要到处重复 htmlspecialchars ...。 Twig 做得很好。
模板继承
我喜欢的另一个功能是扩展基本模板的能力。这是一个基本示例
base.html 模板
child.html 模板
子模板可以覆盖页面特定样式、内容等的块...您还可以注意到使用{% Parent %} 获取父级内容,这样您在覆盖时就不会丢失所有内容。
我建议您尝试一下Twig。非常有用。
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.
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.
Template Inheritance
Another feature I like is the ability to extend base templates. Here's a basic example
base.html template
child.html template
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.
关注点分离。
使用 MVC/MTV 方法时,此类事情是标准的 - 其中数据的呈现必须与数据的显示分开,但如果您使用普通的 ol' 则不然PHP。
使用模板引擎可以轻松区分显示内容和显示方式。
我想你可能会说这属于“照顾糟糕的开发人员”,因为优秀的开发人员无论如何都应该这样做,但在我看来,模板引擎也让优秀的开发人员变得更容易。
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.
在视图之间轻松切换
根据当前的 Web 状态,我需要以不同的格式提供信息:
这些格式的信息可以是相同的,只是视图不同。使用某种模板引擎,我可以在这些视图之间快速切换。
Easy switching between views
With the current state of the web, I need to provide my information in different formats:
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.
value
分配给[key]
和排序。value
to[key]
and the sorts.如果您想开发可以使用许多不同的模板和布局进行自定义的应用程序,同时保持设计与逻辑分离,例如针对不同的客户,您可能需要考虑使用模板系统。
但是,如果您的应用程序只需要一个模板并且从不大量更改布局,那么坚持使用适合您的模板,为什么要更改呢? :)
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? :)
一些模板引擎可以编译模板,从而实现高度优化的转换。
以 .NET 中的 XslCompiledTransform 为例。
Some templating engines can compile templates leading to highly optimized transforms.
Take for example the XslCompiledTransform in .NET.
您的非答案看起来像真正的答案,但措辞非常居高临下。例如:
我将其称为 最小权力规则。它使您的模板对所有用户更有用,而不仅仅是“糟糕的开发人员”。
限制造就了编程语言。 PHP 没有内联汇编功能,这并不是因为 Rasmus 认为你们都是“婴儿”。
Your non-answers look like real answers but phrased in a very condescending manner. For example:
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".
当我需要沙箱时,我发现自己使用模板引擎。例如,让托管 CMS 的用户编辑模板。
I find myself using templating engines when I need sandboxing. for example, letting users of a hosted CMS edit templates.
首先解决这里的答案和一般背景:
人们使用它们的主要原因是它们通常使事情变得更简洁。这是否总是净收益值得怀疑。学习一门新语言的认知负担增加,并且手头没有宿主语言的灵活性,最终会带来比使用模板语言更多的缺点。 Twig 特别需要手动将核心 PHP 函数导出到其中。寻求简洁的最佳模板语言最好不要使用标记器来扩展 PHP。
自动转义是另一个有问题的功能。对于编码很差的开发人员来说,自动转义可能更安全,但否则会削弱安全性,将其抛在脑后,并呈现出在任何情况下默认情况下一切都是安全的期望。一个真正安全的模板引擎需要了解很多关于它的上下文的信息,有时这并不总是可以确定的,只有程序员知道某些东西去了哪里。如果您需要安全编程,您需要有一个不依赖自动转义的开发人员,就这样。这也是 PHP 实际上可以做的事情,如果您标记 PHP 文件,您可以将原始文本与 PHP 分开,并将 PHP 部分包装在输出缓冲中,然后应用您喜欢的任何过滤器,因此这不是模板语言独有的功能。
一些模板引擎可以使预生成更加容易,预编译可以使它们更快,但这也可以通过本机模板来实现。有必要解析模板,这通常会降低模板的效率并且使用它们的过程更加复杂。模板引入的复杂性增加非常重要。这通常可以从你身上抽象出来,但最终会给你带来困扰,例如缓存问题(陈旧的条目)、性能问题、调试时明显更多的抖动和混乱、更多的层和更多的代码被执行,更多的可能会出错等等。
许多功能,例如扩展模板,您再次不需要使用 twig 来实现。类似地,对于诸如 htmlspecialchars 之类的东西,大多数人都会为他们经常使用的所有函数创建简短的辅助函数。
那么,您一定应该在哪里使用 Twig 等模板语言呢?
照顾不好的开发人员是有道理的,尽管我不确定如果你必须使用像 twig 这样的东西来试图遏制他们,他们是否应该被视为开发人员。你也会让优秀的开发人员感到困惑,你会想知道为什么他们要为了实现其他简单的事情而费尽心思。
您可能希望将模板提供给您可能希望处理 HTML 但不暴露系统内部结构等的各方。例如,这可能是您拥有 CMS 的地方,用户可以编辑模板但不能编辑模板。和你的开发者一样。这与上述内容相关,但这是一个更真实的情况,您可能会获得一些好处,并且这可能是合理的。
类似的情况是您可能希望在系统之间使用模板,在这种情况下,模板语言可以是一种可移植的解决方案。这可能不仅是您拥有多个后端的地方,而且是您有不寻常架构要求的地方,例如前端服务器渲染来自下游数据的视图。更进一步,您可能需要可以渲染前端或后端的模板。如果您只需将数据发送到前端,因为它可以自行渲染视图,那么这可能会更有效。但是,由于各种原因,您可能还必须回退到后端。
另一个例子是静态分析,包括跨多种语言。大多数语言通过字符串连接有效地模板化,并且不知道您正在生成的语言。在某些情况下,当您可以完全解析模板语言、语言和 HTML 时,模板语言可以带来好处。实现此目的的另一种方法是尽可能使用 HTML 本身来表示事物,例如使用类等以及 HTML 提供的工具来将行为附加到事物上。即使您无法解析正在使用的模板语言,模板语言也可以比 PHP 更易于解析。这可以用于优化或拥有更容易转译的模板。
您的语言确实不适合创建 HTML 和其他语言。 PHP 是一种模板语言,因此在大多数情况下,使用模板语言几乎没有什么作用,而且会带来很大的阻力。然而,如果您使用的是 Java 之类的东西,那么您很可能需要一个模板引擎。模板语言是一种 DSL,但如果您已经有一种 DSL 可以很好地完成它们的工作,那么它就是 YAGNI。
定制模板。如果您拥有特定的输出格式和域,则可以从自定义模板语言中受益匪浅。这取决于您的输出格式。
所有这些情况都是特定于情况的,并且并不常见,因此应该默认使用模板语言。模板语言仅以不同程度的成功来解决这些问题(例如,许多语言不支持 HTML)。如果我将 Twig 的表现评为 10 分(满分 10 分),那么平均值不会相差 5 分。
您可以将 Twig 转换为 PHP,但不能将 PHP 转换为 Twig。这有时很有用,但代价相当大,因为您会失去 PHP 的很多灵活性。
我接触到的少量Twig内部的质量也很差,或者进口的标准不好。例如,当我五年前第一次尝试时,解析器不支持或至少不支持保留空格。我有一个需要重构的场景,这意味着我需要能够解析 Twig,再次修改并输出它以重写数千个模板的代码,Twig 不支持它,我必须自己翻阅解析器。
同样,我最近调查了 Twig 的逃跑。特别是 JS 转义很突出,它支持转义 JS 字符串和其他奇怪的东西,而不是简单地使用 json_encode。您在框架中得到的自定义转义很可能是错误的。自己做通常更可靠、更安全(例如,只要您了解以下情况,例如,如果您对包含的字符串进行 JSON 编码并将其模板化为 JavaScript 文本而没有足够的转义,会发生什么情况)。
在大多数情况下,成百上千行的魔法模板系统和其他相关系统实现转义、清理等都是糟糕的做法,试图猜测你的场景或试图迎合每一种可能的场景,为奇怪的错误增加更多的范围通常您会发现框架中的类似内容可以用更安全的一两行函数替换。有时您还会遇到其他愚蠢的事情,例如一遍又一遍地处理某些事情,以防万一,因为框架对于您正在做的事情很天真,就好像您自己制作这些东西一样,您确切地知道自己在做什么和不做什么。然后就会出现诸如一遍又一遍地清理同一条字符串之类的事情。
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.