Skip to content

Instantly share code, notes, and snippets.

@badlee
Created September 4, 2024 11:04
Show Gist options
  • Save badlee/97712c8ceb2af81a3c2ba37c3e54c319 to your computer and use it in GitHub Desktop.
Save badlee/97712c8ceb2af81a3c2ba37c3e54c319 to your computer and use it in GitHub Desktop.
A javascript template engine that is simple, easy to use
import compiler from "template.js";
const title = "";
const list= [{ name: 'yan' }, { name: 'haijing' }];
// template JS
const script = `
<?js /* Comments */ ?>
<html>
<head>
<title><?js= title ?></title>
</head>
<body>
<ul>
<?js
for(var i=0; i < list.length; i++ ){
?>
<li><?js= list[i].name ?></li>
<?js } ?>
</ul>
</body>
</html>
`;
const templateCompiled = compiler(script);
console.log(templateCompiled({title, list}));
export default function compiler(str, parent ){
// Figure out if we're getting a template, or if we need to
// load the template - and be sure to cache the result.
var fn =
// Generate a reusable function that will serve as a template
// generator (and which will be cached).
new Function("obj",
"var p=[],print=function(){p.push.apply(p,arguments);};" +
"if (typeof obj !='object' || (typeof obj =='object' && !Array.isArray(obj))) obj = {};"+
"obj._ok_fn = null;"+
"parent._ok_fn = null;"+
// Introduce the data as local variables using with(){}
"with(this){" + // parent scope
"with(obj){p.push('" + // local scope
// Convert the template into pure JavaScript
str
.replace(/<\?(js)?[\n\t\r\s]*include[\n\t\r\s]+("[^;]+"|'[^;]+');?[\n\t\r\s]*\?>/ig,async function(match, jsTag, file){
file = file.trim().replace(/^("|')/,"").replace(/("|')$/,"").trim()
try {
if(fs.Exists(file)){
return fs.ReadFile(file)
}else {
return ""
}
} catch (error) {
return ""
}
})
.replace(/[\r\t\n]/g, " ")
.split(/<\?js/).join("\t")
.split(/<\?/).join("\t")
.replace(/((^|\?>)[^\t]*)'/g, "$1\r")
.replace(/\t=(.*?)\?>/g, "',$1,'")
.split("\t").join("');")
.split("\?>").join("p.push('")
.split("\r").join("\\'")
+ "');}}return p.join('');");
// Provide some basic currying to the user
return parent && typeof parent == 'object' && !Array.isArray(parent) ? fn.bind({}, parent ) : ( fn.bind({},{}));
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment