<div class= "Face info" > <div class= "Info-kind" >
Implementing the template Replacement tool
How to implement a tool like this? In fact, the principle is very simple, is to run in node in the JS read file, will use the Fs.readfilesync method, and then the resulting string with regular matching, through <%%> as a delimiter, JS can be divided into what is the direct output, which needs to be calculated, Finally, the output is done using the Fs.writefilesync method. Because you've implemented a complex DOM selector before, you'll want to use regular break special characters and then put them in an array to traverse.
To create a new Rtt.js file:
var fs = require (' FS '); Get the FS module var srchtml = Fs.readfilesync (' a.src.html '); Read a.src.html file data srchtml = srchtml.tostring (' utf-8 '); Converts the read binary data into a string srchtml = Srchtml.replace (/[\r\n\t]+/g, "); Remove the line and tab//can be merged with the above, convenient to watch the separate write, remove the HTML and js comments srchtml = srchtml.replace (/<!--. *?-->|\/\*.*?\*\//g, ");// Disconnect srchtml with <%%>//if abc<% alert (1),%>def will output [' abc ', ' <% alert (1);%> ', ' def ']var arr = Srchtml.match (/<%={0,2}.*?%>|. *? (? =<%) |. *? (? =$)/g)
So get arr is similar to [' <div> ', ' <% data.name%> ', ' </div> ', ' <% data.age%> ', ' <ul> ' ...]
Finally, we need to pass eval to read the JS statement in <%%>, so we need to set up an S variable for eval, and the res variable in s variable will eventually be eval out and iterate over the array to output
var s = "res="; "; For (var i=0, m=arr.length; i<m; i++) {/ * When iterating through an array, it is a JS statement if it is the beginning of the <%, if not the direct output */if (Arr[i].indexof (' <% ') = = = 0) { if (Arr[i].charat (2) = = = ' && arr[i].charat (3)!== ' = ') { ///If it is a JS variable, s + = ' res+= ' + arr[i] + '; '; } else { //JS statement when s + = Arr[i]; } } else { S + = ' res+= ' + arr[i] + ' "; '; }} Eval (s); Generate res variable and execute fs.writefilesync (a.html, res); Output the RES variable to the target file
Now, a simple template replacement tool is finished, each time the arr[i] also need to test, escaped here will not repeat, declare a function call.
Add an include function to introduce additional file content
The above template substitution allows only substitution variables, generating multiple specified labels through an array, but we often need to introduce some external module files, PHP require and include are very useful, but now is Nodejs.
For example, the introduction of m.tpl.html in A.src.html, M.tpl.html introduced X.tpl.js and y.tpl.html, y.tpl.html was introduced.
The principle is not that difficult, first encapsulate the above code into a function.
/*SRC---Source file path dest---Generate file path datapath---JSON data path dataname object name in---src file delimiter---delimiter */function rtt (SRC, dest, data Path, Dataname, delimiter) { //Set object name defaults to DataPath filename dataname = Dataname | | datapath.split ('/') [ Datapath.split ('/'). Length-1].replace (/\.[ A-z0-9]+$/gi, "); The set delimiter is <%%> by default, and then separated in the middle is saved as [' <% ', '%> '] delimiter = Delimiter | | ' <%%> '; Delimiter = (function () { var n = math.floor (DELIMITER.LENGTH/2); return [Delimiter.substr (0, N), Delimiter.substr (-N)]; }) (); Call the Replace function, the final output is replaced by the string, generated to the Dest file //Here Most of the replacement logic has been encapsulated in replace, replace only read the source file generation target final string // Because the various variables in the RTT are used in replace, the fs.writefilesync (dest, replace (SRC)) is written using the closure form; Console.log (' compile finished! '); print ' compile finished ' function replace (SRC) {
Pass in a SRC path, return the replaced string ... }
Replace most of the same as the previous interview, just encapsulated into a function, and then the include extension:
function replace (SRC) {eval ("var" +dataname+ "=" + data); var s = "res="; ", FS = require (" FS "), location = GetLocation (SRC); Read the source file HTML and get the string, and then put the string in \r\n\t var srchtml = Fs.readfilesync (src). toString (' Utf-8 '). Replace (/[\r\n\t]+/g, '); Remove the HTML comment, JS comment/**/type srchtml = Srchtml.replace (/<!--. *?-->|\/\*.*?\*\//g, '); Split the string in the HTML file var reg = new RegExp (delimiter[0] + "={0,2}.*?" +delimiter[1]+ "|. *? (? = "+delimiter[0]+") |. *? (? =$) "," G "); var arr = Srchtml.match (reg); For (var i=0, m=arr.length; i<m; i++) {if (Arr[i].indexof (' <% ') = = = 0) {if (Arr[i].charat (2) = = = ' = ' & amp;& Arr[i].charat (3)!== ' = ') {//JS variable when s + = ' res+= ' + trim (arr[i]) + '; '; } else if (Arr[i].charat (2) = = = ' && Arr[i].charat (3) = = = ') {//js variable, if two < replace it with < Replace > to > s + = ' res+= ' + eshtml (Trim (arr[i])) + '; '; } else if (/^<%\s*include\ (. *\) \s*;? \s*%>$/.test (Arr[i])) {//If it is recognized as an include (' abc.html ') type format, recursively calls the Replace function, passing in abc.html var NewPath = Genpath (src, arr[i].replace (/.+[' "] (. +) ['"].+/g, function (A, b) {return B;})); s + = ' res+= ' + es (replace (newpath)) + ' "; ';} else{//JS statement when s + = Trim (Arr[i]); }} else{S + = ' res+= ' + es (arr[i]) + ' "; ';}} Eval (s); Returns the variable that was obtained by Eval res return res;}
The Replace function above uses the recursive implementation of multi-layered references, but there is a problem, if the a.src.html reference tpl/b.html, tpl/b.html and refer to the./css/c.css, then the path will be problematic, because the referenced file, referencing its The path to his file is relative to himself, and node reads the file location where the src file is located:
When node executes to the include (' css/c.html '), it will read the/css/c.css file according to the location of the src file, so there will be an error, so it is necessary to use a function to generate a new path relative to SRC in order to get the/tpl/css/c.css file
Pass in a file path, returning the directory where function getLocation (src) {if (Src.charat (src.length-1) = = =/') return Src;else if (src.indexof ('/') = = = 0) return './'; else if (Src.indexof ('/') < 0) return './'; Else{var temp = src.split ('/'); Temp.pop (); return Temp.join ('/') + '/';}}
You will then need to generate a function for the new path:
Pass in the current file path, and the file path of include, generate relative path relative to index function Genpath (cur, dest) {if (Dest.charat (0)!== '. ' && Dest.charat (0)!== '/') {return getLocation (cur) + dest.replace (/^\//, ');} else if (dest.indexof ('./') = = = 0) {return getLocation (cur) + dest.replace (/^\.\//, ');} else{//if the target path is: /.. /.. /a/b/c.html type var cur = getLocation (cur). Match (/[^\/]+\//g); var m = Cur.length;var n = dest.match (/\.\.\//g). Length;if (M >n) {return Cur.slice (0, M-n). Join (') + dest.replace (/\.\.\//g, ');} else if (m = = = N) return './' + dest.replace (/\.\.\//g, '); else if (M < n) {for (var res= ", i=0; i<n-m; i++) res+= '. /'; return res + dest.replace (/\.\.\//g, ');}}}
At this point, a template that can reference other files has been completed and can be installed via NPM install RTT--save-dev, then create a new Replace.js file and enter:
var RTT = require (' RTT '); RTT (' a.src.html ', ' a.html ', ' Data.json ');
It can be said that the a.src.html source file <%%> contains the use of the data namespace output to a.html, allowing multiple layers to introduce files, note: <%include (");%>
Since I study Nodejs time is not long, have any questions please point out, thank you
Write a simple JS template replacement tool RTT----Replace templete tools