Introduction
MegaFon is a dynamic technology company whose work is not limited solely to the provision of communication services. For example, among our assets there are a large number of Internet sites where customers receive various information and services. As part of a project to improve and develop our web projects, we, among other things, create products that can be useful to other developers. Today we would like to present the first of them - Histone template engine, which is an opensource project distributed under the Apache Software License 2.0. But first things first.
What is Histone?
Many of you use different template engines when creating web applications. The situation when you need to generate some HTML code from a data set in a certain format using a template that sets transformation rules is ubiquitous. Several years ago, template engines were actively used to generate HTML-code on the server (
Smarty ,
FreeMarker ,
Velocity ), today it is becoming more and more necessary to generate HTML-code directly in the browser. Examples of such template engines include:
TrimPath templates ,
Mustache ,
Google Closure Templates , etc.
With all the variety of solutions designed to work on different platforms, there are not so many template engines that could be run simultaneously on the server and in the web browser. Each of them has its pluses and significant drawbacks. Some of these disadvantages, in our opinion, are critical, which does not allow you to fully enjoy all the benefits of a template engine that works both on the server and in a web browser.
')
The project “Histone” is an attempt to create a new open-source cross-platform template engine in implementations for Java, JavaScript and PHP. Before we started developing our own solution, we examined the advantages and disadvantages of the already existing cross-platform templating engines. We analyzed only popular template engines that are widely used for building modern web applications, and did not consider solutions that do not have at least two of the three implementations of interest (Java, JavaScript, PHP).
| pros | Minuses |
Google Closure Templates | - Template source code is compiled into JavaScript, which speeds up its processing. | - To use the template, it is necessary to pre-process it using a special utility. This greatly complicates the development of browser-based applications, since when you make any changes to the template, it must be recompiled.
- Too complicated syntax of templates that will be clear to programmers, but will inevitably cause difficulties for template designers.
- A complex mechanism for creating your extensions. It does not allow to increase the functionality of the JavaScript version, which makes the extension mechanism inapplicable in the case of cross-platform use of templates.
- No PHP version
|
Mustache | - Exists in all possible variations for a variety of programming languages. | - Unconventional syntax, difficult to understand template designers.
- The template language lacks a number of important constructions, which makes the use of this template system impossible (at least, non-trivial) in the context of some projects.
- The extension mechanism is very poorly documented.
|
After analyzing the existing products, our team decided to create a new template engine that would have the best sides of the products listed above, as well as correct the disadvantages and shortcomings that are critical for us. As a result, a list of the main ideas that formed the basis for the development was formed:
- One template is a set of template implementations. The syntax of the template is independent of the programming language used to process it. This is necessary so that the same templates can be processed both on the server and in the browser and thus receive the same result.
- Traditional and intuitive syntax. Constructions processed by the template engine are placed between the {{and}} delimiters, everything else falls into the result of processing the “as is” template.
- The inability to execute code directly from the template. Many template engines can execute the code of the corresponding programming language directly from the template. This does not allow the use of such a template with code inserts of a specific language in implementations in other languages. Therefore, this possibility in Histone is completely excluded.
- Easy to expand. Regardless of the programming language used to process the template, the provided API allows you to add a new function or property to use it in the template in order to meet the needs of any project.
- The ability to use a single data source for templates processed on different platforms. The universal data format, for which support in Histone there is everything you need, is JSON. Regardless of what type of data type the implementation language has, the template language allows you to work with a subset of the data types defined for the JSON format.
- Providing the template with information about the environment in which it is running. The template is provided with specific information about the platform on which it is processed. For example, in the case of processing in the browser, the template is available information about the screen resolution or the size of the browser window, and in the case of processing on the server, the template can get information about the operating system or server request headers.
- Cross-platform and easy porting. Implementations for JavaScript, Java, and PHP are available out of the box. Eliminating the use of specific external libraries along with the logical organization of the code allows for porting the Histone implementation to any other programming language, for example, C ++, Ruby, Objective-C, ActionScript, etc.
- Performance. Unlike Google Closure Templates, Histone does not convert the template code into the source code of the programming language in which it is planned to be processed. Instead, it is possible to compile the template source code into a form that will be executed using the special utility included in the product, bypassing the parsing and parsing stage (the most expensive operation). In addition, at this stage, those parts of the template that do not depend on functions, properties, and variables defined externally are executed.
Architecture
As part of the template engine, three interrelated components can be distinguished:
- Lexical analyzer. Parses a template string into tokens (sequences of characters of the source string, combined into groups). Created using the regular expression engine built into the implementation language.
- Syntactical analyzer. Parses a template string, which results in an abstract syntax tree reflecting the syntactic structure of the input sequence. Created using recursive descent algorithm.
- Interpreter. Executes instructions of the abstract syntax tree, during which the result of template processing is generated. The most important part of the template engine that performs arithmetic operations, function calls, reading properties, etc.
Obviously, the use of a lexical analyzer based on regular expressions and a recursive descent parser is not the most effective approach to building systems of this kind, but this is justified by the fact that our primary task was to ensure the maximum speed of the template interpretation process. Since in real conditions, working with the source code of templates will occur only during the project development process, while a web application in public access may use abstract syntax trees of templates instead of their source code, thereby completely excluding lexical analysis and parsing.
Pattern Syntax
A template is a text document with inserts of special template tags, the contents of which will be executed by the template engine during template processing. Template tags are constructs of the template language, enclosed between {{and}} characters. Fragments of a text document outside these characters will be transferred to the result of the template processing without changes.
Basics of syntaxDescription | Example |
Comments | {{* comment *}} |
Preventing processing | {{% {{2 * 2}}%}} |
Displaying property or variable values | {{myValue}} {{myProp.foo.bar}} {{myObject ["foo"]. bar}}
|
Calling Functions and Macros | {{loadText ("file.txt")}} {{global.min (10, 20, 30)}} {{myMacro ("foo", "bar")}}
|
Method call | {{"String" .toUpperCase ()}} {{123.isNumber ()}}
|
Data typesDescription | Example |
Value not defined | {{undefined}} |
No value | {{null}} |
Boolean | {{true}} {{false}}
|
Numbers | {{ten}} {{3.14}} {{12E-4}}
|
Strings | {{"String"}} {{'string'}}
|
Arrays | {{[1, 2, 3]}} {{["Foo": "bar"]}}
|
OperationsDescription | Example |
Addition | {{10 + 2}} |
Subtraction | {{10 - 2}} |
Multiplication | {{10 * 2}} |
Division | {{10/2}} |
Remainder of the division | {{10 mod 2}} |
Unary minus | {{-ten}} |
Equally | {{10 is 10}} |
Not equal | {{10 isNot 2}} |
More | {{10> 2}} |
Less | {{2 <10}} |
Greater than or equal to | {{10> = 2}} |
Less than or equal to | {{2 <= 10}} |
Logical "OR" | {{true or false}} |
Logical "and" | {{true and false}} |
Logical "NOT" | {{not true}} |
Ternary operator | {{true? true: false}} |
ConstructionsDescription | Example |
Variable declaration | {{var myVar = 10}}
{{var myVar}} ... {{/ var}}
|
Condition | {{if true}} ... {{elseif 42}} ... {{else}} ... {{/ if}}
|
Cycle | {{for value in values}} ... {{/ for}}
{{for key: value in values}} ... {{/ for}}
|
Macros | {{macro myMacro (arg1, arg2)}} ... {{/ macro}}
|
Import template | {{import "common.tpl"}} |
Calling a function or macro | {{call myProc ("arg1", "arg2")}} arg3 {{/ call}}
|
Conclusion
In this article we have tried to briefly describe the main features of the new cross-platform open source template engine. You have become familiar with the internal structure and basic syntax of patterns. If you are interested in a detailed description of the technologies on the basis of which Histone works, we will be able to tell it in the next post, in which we will look at how the lexical analyzer we use works.
You can take an active part in the development of the project and apply it in your resources. Our team will be happy to answer all your questions.
Links