@
First, the basic concept of template engine.
1. Template engine
The template engine is a third-party module.
Let developers splice strings in a more friendly way, making the project code clearer and easier to maintain. For example:
// Writing without template engine var ary = [{ name: 'Zhang San', age: 20 }]; var str = '<ul>'; for (var i = 0; i < ary.length; i++) { str += '<li>\ <span>'+ ary[i].name +'</span>\ <span>'+ ary[i].age +'</span>\ </li>'; } str += '</ul>';
<!-- How to write using template engine --> <ul> {{each ary}} <li>{{$value.name}}</li> <li>{{$value.age}}</li> {{/each}} </ul>
2. Art template template engine
2, Use art template in NodeJS
① Basic steps:
- Use the NPM install art template command in the command line tool to download
- Use const template = require ('art template ') to introduce the template engine
- Tell the template engine the data to be spliced and where the template is. const html = template('template path ', data);
- Use template syntax to tell the template engine how to splice templates and data
In vscode, art files are not regarded as html files by default, which requires additional settings: Blog reference
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> {{ name }} {{ age }} </body> </html>
//Introduce the art template template and actually return a method const template = require('art-template'); const path = require('path'); const views = path.join(__dirname, 'views', '01.art'); /* template(Parameter 1, parameter 2) Parameter 1: art template file path (absolute path is preferred) Parameter 2: data used by art template file, object type Return art template file string (html) */ const html = template(views, { name: 'Zhang San', age: 20, }) console.log(html);
Operation results:
PS D:\...\template> node app.js <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> Zhang San 20 </body> </html>
② Syntax of template engine
Art template supports two kinds of template syntax at the same time: standard syntax and original syntax.
The standard syntax can make the template easier to read and write, and the original syntax has strong logical processing ability.
1. Output
Output some data in the template. The standard syntax and original syntax are as follows:
- Standard syntax: {data}}
- Original syntax: <% = Data% >
In the output syntax, you can output variables, object attributes, ternary expressions, logic or, addition, subtraction, multiplication and division and other expressions.
<!-- Standard grammar --> <h2>{{value}}</h2> <h2>{{a ? b : c}}</h2> <h2>{{a + b}}</h2> <!-- Primitive grammar --> <h2><%= value %></h2> <h2><%= a ? b : c %></h2> <h2><%= a + b %></h2>
2. Original output
If the value value to be output contains the HTML tag structure, the original output syntax needs to be used to ensure that the HTML tag is rendered normally.
The default template engine will not parse the label, but will escape it and output it.
Standard original output syntax: {{@ data}}
Original text output syntax: <% - Data% >
<!-- Standard grammar --> <h2>{{@ value }}</h2> <!-- Primitive grammar --> <h2><%- value %></h2>
3. Condition judgment
<!-- Standard grammar --> {{if condition}} ... {{/if}} {{if Condition 1}} ... {{else if Condition 2}} ... {{/if}} <!-- Primitive grammar --> <% if (Condition 1) { %> ... <% } else if (Condition 2) { %> ... <% } else { %> ... <% } %>
Note: native js syntax is supported inside the original syntax output character
4. Circulation
Standard syntax: {each data}} {{/each}}
Original syntax: <% for() {% >... <%}% >
<!-- Standard grammar each: Template cycle identifier target: Data to cycle $index: Index of the current circular item $value: The value of the current loop item --> {{each target}} {{$index}} {{$value}} {{/each}} <!-- Primitive grammar Primordial js grammar --> <% for(var i = 0; i < target.length; i++){ %> <%= i %> <%= target[i] %> <% } %>
5. Sub template
Using the sub template, you can pull the public blocks of the website (such as the header and bottom label blocks) into a separate file.
The sub template (public template) is introduced into other templates by using include
- Standard syntax: {{include 'child template relative path'}}, where include represents an identifier
- Original syntax: <% include ('sub template relative path template ')% >, where include represents a method
<!-- Standard grammar --> {{include './header.art'}} <!-- Primitive grammar --> <% include('./header.art') %>
include introduces the sub template address
{{include './common/header.art'}}
The address in the common part syntax introduced into the template file is the relative path. This relative path is parsed by the template engine, which is the path relative to the current template file, not the current request address
6. Template inheritance
Template inheritance means that other templates can inherit some public templates, similar to sub templates, but using template inheritance can separate the website HTML skeleton into a separate file, and other page templates can inherit the skeleton file.
Syntax:
In other templates, use {{extends' relative path of inherited template '}} to inherit the public template
Template inheritance can specify some parts of the inherited template according to the needs of the current template
- In the inherited template, use {{block 'reserved empty name'} {/ block}} to set the reserved empty name
- In other templates, use {{block 'reserved empty name'}} to specify content {{/ block}} to fill the reserved hole
Simple case:
<!-- Common skeleton template layout.art --> <!doctype html> <html> <head> <meta charset="utf-8"> {{block 'title'}}{{/block}} {{block 'link'}}{{/block}} </head> <body> {{block 'content'}}{{/block}} </body> </html>
<!--index.art Home page template--> {{extend './layout.art'}} {{block 'title'}} <title>This is the home page</title> {{/block}} {{block 'link'}} <link rel="stylesheet" href="custom.css"> {{/block}} {{block 'content'}} <p>This is just an awesome page.</p> {{/block}}
Command line output
PS D:\...\template> node 05.js <!doctype html> <html> <head> <meta charset="utf-8"> <title>This is the home page</title> <link rel="stylesheet" href="custom.css"> </head> <body> <p>This is just an awesome page.</p> </body> </html> PS D:\...\test\template>
7. Template configuration
Import variables into the template
/* template: The art template template template engine module imported from the current js file */ template.defaults.imports.Variable name = Variable value;
After the statement is executed, the variable can be used in the linked template
dateformat
Usage scenario: format date data in template
Reference to third-party modules: dateformat - npm
{{dateformat(time, 'yyyy-mm-dd')}}
const template = require('art-template'); const path = require('path'); const dateformat = require('dateformat'); const view = path.join(__dirname, 'views', '06.art'); //! Import template variables template.defaults.imports.dateformat = dateformat; const html = template(view , { time: new Date(), }); console.log(html);
Command line output
PS D:\...\template> node 06.js 2021-09-01
Set template root directory
Render multiple templates through multiple templates (), but you have to manually set the template address each time
const view1 = path.join(__dirname, 'view', '01.art'); const view2 = path.join(__dirname, 'view', '02.art'); console.log(template(view1,{})); console.log(template(view2,{}));
This will cause code redundancy
By setting the template root directory, you only need to specify the template file name every time you call template() to render the template, and let the template engine automatically find the specified template file in the template root directory
/*Set the root directory of the template template: The art template template template engine module imported from the current js file */ template.defaults.root = path.join(__dirname, Root directory name);
Simple case
const template = require('art-template'); // Set the root directory of the template template.defaults.root = path.join(__dirname, 'views'); console.log(template('06.art', { msg: '06.art The template file is automatically found and rendered' }))
Set template default suffix
By setting the default suffix of the template:
// Configure the default suffix of the template //Template: the art template template template engine module imported from the current js file template.defaults.extname = '.html';
Specify the template file name directly when template() renders the template (no suffix is required):
console.log(template('07', { msg: 'The template engine automatically finds the template in the root directory "07.html" Template file and render' }));
Of course, if the full name of the template file is specified (including the suffix), the template engine will automatically go to the root directory to find the specified file and render.
③ Request address of external chain resources of template file
The external chain resource path in the template file is not relative to the current template file,
Instead, the relative path is relative to the request path in the address bar.
such as
Enter localhost/admin/login in the address bar, and the server responds to a template file and parses it to the browser through the engine
The browser parses the path as follows. It goes back to the login file in the / admin directory. Therefore, the last part is actually the specified file rather than the directory
login. The external chain resource path under the art template file is the request path / admin relative to the current template, such as
<link rel="stylesheet" href="css/base.css">
The actual request address of this link tag is: localhost / admin / CSS / base css
If we visit login The request path of art is changed to localhost/abc/login, so that the template file can be accessed normally, but the external chain resources inside are still relative to the path of / abc. However, at this time, the static resources are stored under / admin, and the external chain resources will fail to respond.
Solution: change the request address of external chain resources in the template file into an absolute path through '/', then the request address of external chain resources has nothing to do with the request address of the current browser, as shown below
<link rel="stylesheet" href="/admin/css/base.css">
At this time, the actual request address of the external chain resource is localhost / admin / CSS / base css
3, Use art template in browser
① Basic usage steps
- download art-template-web.js Template engine library files and import and store files in HTML pages
<!-- Note: the path here should be absolute, otherwise it will be relative to url Path to address, If url Address following Dang html If the address of the file does not match, an error will be reported --> <script src="/js/template-web.js"></script>
- Prepare art template template
The basic template syntax is supported in the template, which is the same as that in nodeJS.<!-- id: id Name, which is used to distinguish different templates type: stay<script>Need to be specified in html type --> <script id="tpl" type="text/html"> <div class="box"></div> </script>
- Tell the template engine which template and which data to splice
/* template: Method provided by template library file parms1: Template id name parms2: Incoming template data return: Returns a string of specific characters according to the template */ var html = template('tpl', {username: 'zhangsan', age: '20'});
- Tell the template engine how to splice data and html strings through template syntax
<script id="tpl" type="text/html"> <div class="box"> {{ username }} </div> </script>
- Add the spliced html string to the page
document.getElementById('container').innerHTML = html;
② Filter
- brief introduction
A filter is a function that handles special values and returns the desired result
-
grammar
{{value | filterName}}
The filter syntax is similar to the pipeline operator, with the previous output as the next input.
The basic syntax for defining filters is as follows:template.defaults.imports.filterName = function(value){/*return Results of processing*/}
- give an example
Define a filter for formatting time. dateFormat is as follows:
Using filter functions in templatestemplate.defaults.imports.dateFormat = function(date) { var y = date.getFullYear() var m = date.getMonth() + 1 var d = date.getDate() return y + '-' + m + '-' + d // Note that the filter must return a value at the end } var html = template('tpl',{regTime: new Date()}); console.log(html); /* <div>2021-10-2</div> */
<script type="text/html" id="tpl"> <!--equivalent <div>{{dateFormar(regTime)}}</div> --> <div>Registration time:{{regTime | dateFormat}}</div> <script>
② Simple template engine for customization
explain
Using the regular string operation, the user-defined template function is realized
Implementation steps
① Define template structure
<!-- Define template structure --> <script type="text/html" id="tpl-user"> <div>full name:{{ name }}</div> <div>Age:{{ age }}</div> <div>Gender:{{ gender }}</div> <div>Address:{{ address }}</div> </script>
② Pre call template engine
//Define data var data = {name: 'Zhang San', age: 20, gender: 'male', address: 'Shenzhen'} //Call custom template function var htmlStr = template('tpl-user', data) //Render html deconstruction document.getElementById("user-box").innerHTML = htmlStr
③ Encapsulate template function
//Custom template function template js function template(id, data){ var str = document.getElementById(id).innerHTML var pattern = /{{\s*([a-zA-Z]+)\s*}}/ var patternResult = null while(patternResult = pattern.exec(str)){ str = str.replace(patternResult[0], patternResult[1]); } return str; }
④ Import and use a custom template engine
If the custom template function is in other files, you can also import it
<head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Custom template engine</title> <!-- Import custom template engine --> <script src="./js/template.js"></script> </head>