Art template template engine

@

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

art-template (aui.github.io)



2, Use art template in NodeJS

① Basic steps:

  1. Use the NPM install art template command in the command line tool to download
  2. Use const template = require ('art template ') to introduce the template engine
  3. Tell the template engine the data to be spliced and where the template is. const html = template('template path ', data);
  4. 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

  1. 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>
    
  2. 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>
    
  3. 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'});
    
  4. 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>
    
  5. 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
graph LR A [value to be processed] - parameter -- > b [filter function] - return value -- > C [output new value]

  • 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:
    	template.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>
    	*/
    
    Using filter functions in templates
    <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;
}

exec()
replace()


④ 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>

Keywords: node.js

Added by siropchik on Sun, 30 Jan 2022 01:15:17 +0200