{"id":21410675,"url":"https://github.com/dondido/express-es6-template-engine","last_synced_at":"2025-05-15T18:10:25.954Z","repository":{"id":3091874,"uuid":"48415464","full_name":"dondido/express-es6-template-engine","owner":"dondido","description":"Rendering engine for Express that uses ES6 javascript string templates as syntax.","archived":false,"fork":false,"pushed_at":"2024-10-22T06:33:57.000Z","size":358,"stargazers_count":200,"open_issues_count":2,"forks_count":21,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-07T23:11:39.877Z","etag":null,"topics":["html-template","isomorphic","javascript","partials","precompilation","template-engine"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dondido.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-22T06:48:30.000Z","updated_at":"2025-01-26T03:51:08.000Z","dependencies_parsed_at":"2024-11-22T21:33:40.077Z","dependency_job_id":null,"html_url":"https://github.com/dondido/express-es6-template-engine","commit_stats":{"total_commits":119,"total_committers":7,"mean_commits":17.0,"dds":0.2100840336134454,"last_synced_commit":"684615ce70e86d75da9aaf6ed2dd9d71217beabe"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dondido%2Fexpress-es6-template-engine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dondido%2Fexpress-es6-template-engine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dondido%2Fexpress-es6-template-engine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dondido%2Fexpress-es6-template-engine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dondido","download_url":"https://codeload.github.com/dondido/express-es6-template-engine/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254394724,"owners_count":22063984,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html-template","isomorphic","javascript","partials","precompilation","template-engine"],"created_at":"2024-11-22T17:41:02.981Z","updated_at":"2025-05-15T18:10:25.911Z","avatar_url":"https://github.com/dondido.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Express ES6 string template engine\n======\n\nES6 Renderer is simple, super fast, and extendable Template Engine for Node and Express applications which uses pure ES6 Javascript syntax.\nIt works by scanning files in a working directory, then reading the contents of the files and converting them from plain strings to ES6 template strings. ES6 template strings are string literals enclosed by the back-tick. They feature String Interpolation, Embedded Expressions, Multiline strings and String Tagging for safe HTML escaping, localisation, etc. Once convertion is completed its then compiled to plain text by the V8 engine, harnessing 100% of its power. Being less than 1kb, ES6 Renderer offloads a lot of the processing directly to the V8 interpreter, which compiles the code and runs as fast as the rest of the Express App. In fact, ES6 Renderer shouldn't add any overhead to the project at all! It should also allow us to implement any functionality we like within the bounds of Javascript.\n\nMinimum requirements Node.js `v4.0.0`.\n\n[![Package Version](https://img.shields.io/badge/npm-4.0.0-blue.svg)](https://www.npmjs.com/package/express-es6-template-engine)\n\n### Benchmarks\n\nTesting ES6 Renderer performance was a great opportunity to see how it stacked-up beside others. Our speed test compiled one main template containing an array of string, an object literal and conditional statements.\n\n![Benchmarks](benchmark.png)\n\n### Playground\n\nThis template engines is essential tools in web development that allows you to generate dynamic HTML content by combining templates with data. Explore ES6 Renderer [Playground demo](https://dondido.github.io/express-es6-template-engine/) to learn how to use it.\n\n### Installation\n\n```bash\n$ npm i express-es6-template-engine --save\n```\n\n### Features\n\n* No Dependencies\n* Fully Configurable\n* Compiled and interpreted by V8 (Super Fast)\n* Learning new syntax is not required\n* Partials Support\n* Conditional Support\n* Iterators Support\n* Native Javascript Support\n\n### Usage\n\n#### Prerequisites\n\nList of used html files in the `views` folder:\n\n`index.html`\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003cbody\u003e\n    \u003ch1\u003e${title}\u003c/h1\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n`template.html`\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003cbody\u003e\n    \u003ch1\u003e${title}\u003c/h1\u003e\n    \u003cmain\u003e${partial}\u003c/main\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n`partial.html`\n\n```html\n\u003cp\u003eThe fastest javascript template string engine!\u003c/p\u003e\n```\n\n`partial-conditional.html`\n\n```html\nES6 Renderer is ${maintainedBy ? `a template engine maintained by ${maintainedBy}` : 'not maintained anymore'}.\n```\n\n`partial-iteration.html`\n\n```html\n\u003cdl\u003e\n  ${features.map(f =\u003e `\n    \u003cdt\u003e${f.dt}\u003c/dt\u003e\n    \u003cdd\u003e${f.dd}\u003c/dd\u003e\n  `).join('')}\n\u003c/dl\u003e\n```\n\n#### Setup with Express\n\nThe basics required to integrate ES6 renderer in your app are pretty simple and easy to implement:\n\n```javascript\nconst express = require('express'),\n  es6Renderer = require('express-es6-template-engine'),\n  app = express();\n  \napp.engine('html', es6Renderer);\napp.set('views', 'views');\napp.set('view engine', 'html');\n\napp.get('/', function(req, res) {\n  res.render('index', {locals: {title: 'Welcome!'}});\n});\n\napp.listen(3000);\n```\n\nBefore Express can render template files, the following application settings must be set:\n\n- views, the directory where the template files are located. Eg: app.set('views', './views')\n- view engine, the template engine to use. Eg: app.set('view engine', 'html')\n\nHTML template file named `index.html` in the views directory is needed (the content of the file can be found in the prerequisites section). Route to render the html file is expected. If the view engine property is not set, we must specify the extension of the view file. Otherwise, it can be safely omitted.\n\n```javascript\napp.render('index', {locals: {title: 'ES6 Renderer'}});\n```\n\nExpress-compliant template engines such as ES6 Renderer export a function named __express(filePath, options, callback), which is called by the res.render() function to render the template code. When a request is made to the home page, the index.html file will be rendered as HTML.\n\n#### Setup without Express\n\nTo get up and running without having to worry about managing extra libraries one only needs the following:\n\n```javascript\nconst es6Renderer = require('express-es6-template-engine');\nes6Renderer(\n    __dirname + '/views/index.html',\n    { locals: { title:  'ES6 Renderer' } },\n    (err, content) =\u003e err || content\n);\n```\n\nThe content below will be rendered on the client side as a response from both setups:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003cbody\u003e\n    \u003ch1\u003eES6 Renderer\u003c/h1\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n#### Rendering a template\n\nWithin your app route callback, call `res.render`, passing any partials and local variables required by your template. For example:\n\n```javascript\napp.get('/', function(req, res) {\n  res.render('template', {\n      locals: {\n        title:  'ES6 Renderer'\n      },\n      partials: {\n        partial: 'partial'\n      }\n  });\n});\n```\n\nPartial with a file name `partial.html` (see the content of the file in the prerequisites section above) will be injected into `template.html`:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003cbody\u003e\n    \u003ch1\u003eES6 Renderer\u003c/h1\u003e\n    \u003cmain\u003e\u003cp\u003eThe fastest javascript template string engine!\u003c/p\u003e\u003c/main\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nAll templates files paths are defined as absolute to the root directory of the project.\n\n#### Compiling a string\n\nES6 Renderer rendering functionality has separate scanning, parsing, string generation and response sending phases. Compilation is pretty much the same but without the response sending phase. This feature can be useful for pre-processing templates on the server.\nCompiling has the following syntax:\n\n```javascript\nconst titleTpl = '${engineName} - The fastest javascript template string engine!';\nconst cb = (err, content) =\u003e err || content;\n\n// sync - second parameter is a string representation of an array of variable names.\n// The returned function is called with a string representation of an array of variable values.\nconst compiled = es6Renderer(titleTpl, 'engineName')('ES6 Renderer');\n// async - second parameter is an object and third parameter is a callback function\nes6Renderer(titleTpl,{ template: true, locals:{ engineName: 'ES6 Renderer' } }, cb);\n```\nBoth methods will result in the following output:\n\n```\nES6 Renderer - The fastest javascript template string engine!\n```\nThe template engine allows both synchronous and asynchronous method invocations. If string is rendered as in the examples provided above a 'template' option needs to be set to true. The preceding synchronous invocation returns an output immediately in response to the function execution. Alternatively, you can specify partials and omit template parameter to force file lookup and content reading and invoke the function asynchronously. \n\n\n#### Compiling a template\n\nThe two functions `app.render` and `es6Renderer` are almost identical, but they require slightly different parameters to be passed. While `app.render` uses an absolute path, or a path relative to the views setting, `es6Renderer` expects a path relative to root folder.\nThey both return the rendered content of a view via the callback function. The callback function which is provided as a third parameter is called once the asynchronous activity is completed. The output in the two examples provided below is the same:\n\n```javascript\napp.render('template', {\n  locals: {\n    title:  'ES6 Renderer'\n  },\n  partials: {\n    template: __dirname + '/views/partial'\n  }\n}, (err, content) =\u003e err || content);\n```\n```javascript\nes6Renderer(__dirname + '/views/template.html', {\n  locals: {\n    title:  'ES6 Renderer'\n  },\n  partials: {\n    template: __dirname + '/views/partial.html'\n  }\n}, (err, content) =\u003e err || content);\n```\nOn average `es6Renderer` yields slightly better performance than `app.render`. Async function invocation of `es6Renderer` also returns a promise, which enables us to chain method calls:\n```javascript\nconst compile = es6Renderer(__dirname + '/views/template.html', {\n  locals: {\n    title:  'ES6 Renderer'\n  },\n  partials: {\n    template: __dirname + '/views/partial.html'\n  }\n}, (err, content) =\u003e err || content);\ncompile.then(output =\u003e res.send(output))\n```\n\n#### Compiling a nested template\n\nTemplate nesting is currently not supported by the engine. A simple workaround to this issue would be to perform multiple template compilations:\n\n```javascript\nconst renderPage = (err, content) =\u003e res.render('template', {\n  locals: {\n    partial: content\n  }\n});\nes6Renderer(__dirname + '/views/partial-conditional.html', {\n  locals: {\n    maintainedBy:  'Good Samaritans'\n  }\n}, renderPage);\n```\n#### Precompiling\n\nES6 Renderer allows us bypassing Express view rendering for speed and modularity. Compiling a template is much slower than rendering it, so when it comes to speed, we should precompile our templates as part of the optimisation process. The result of precompilation can be stored to an object:\n```javascript\nconst text = '${engineName} - The fastest javascript template string engine in the whole ${place}!';\nconst precompiled = es6Renderer(text, 'engineName, place');\n```\nand then invoked whenever needed:\n```javascript\nconsole.log(precompiled('ES6 Renderer', 'multiverse'));\n```\nTo make use of this precompilation, templates should be compiled with names that the compiler would expect and the result function called with an argument list that consists of values relative to the names. If no property name is defined a default one is created with a value of '$': \n```javascript\nconst text = '${$.engineName} - The fastest javascript template string engine in the whole ${$.place}!';\nconsole.log(es6Renderer(text)({ engineName: 'ES6 Renderer', place: 'multiverse' });\n```\nThis allows us to create an application that is more flexible, independent from a framework, easier to understand and better performing.\n\n\n\n#### Conditional statements\n\nES6 Renderer dynamically evaluates code in JavaScript. If the argument is an expression, ES6 Renderer evaluates the expression. If the argument is one or more JavaScript statements, the engine executes the statements. A simplified example of using conditional statement is presented below.\n\nA route path on the server side:\n\n```javascript\nres.render('partial-conditional', {\n    locals: {\n      maintainedBy:  'Good Samaritans'\n    }\n  });\n```\n\nWill result in the following:\n\n```html\nES6 Renderer is a template engine maintained by Good Samaritans.\n```\n\n#### Iterators\n\nIterating over arrays and objects is quite straight forward and intuitive (knowledge of basic javascript here is essential). An object literal is passed to a html template:\n\n```javascript\nres.render('partial-iteration', {\n    locals: {\n      features:  [\n      { \n        dt: 'Multi-line strings', \n        dd: 'Any new line characters inserted in the source are part of the template string.' \n      },\n      { \n        dt: 'Expression interpolation', \n        dd: 'Template strings can contain placeholders. These are indicated by dollar sign and curly braces.' \n      },\n    ]\n    }\n  });\n```\n\nThe following is received by the client side:\n\n```html\n\u003cdl\u003e\n    \u003cdt\u003eMulti-line strings\u003c/dt\u003e\n    \u003cdd\u003eAny new line characters inserted in the source are part of the template string.\u003c/dd\u003e\n    \u003cdt\u003eExpression interpolation\u003c/dt\u003e\n    \u003cdd\u003eTemplate strings can contain placeholders. These are indicated by dollar sign and curly braces.\u003c/dd\u003e\n\u003c/dl\u003e\n```\n\n#### Error Handling\n\nES6 Renderer catches and processes errors that occur both synchronously and asynchronously. ES6 Renderer comes with a default error handler so you don’t need to write your own to get started.\nErrors that occur in synchronous code require no extra work. If synchronous code throws an error, then ES6 Renderer will catch and process it. For example.\n\n```javascript\nconst text = '${engineName} - The fastest javascript template string engine in the whole ${place}!';\nconst err = es6Renderer(text, 'engineName')('ES6 Renderer', 'multiverse');\nexpect(err instanceof Error).to.equal(true);\n```\n\nFor errors returned from asynchronous functions, you must pass them to the callback function, where ES6 Renderer will catch and process them. A viable alternative will be to use native promise catch or reject methods. The example underneath handles both cases simultaneously:\n\n```javascript\nes6Renderer(\n    __dirname + \"/index.html\",\n    { locals: { engineName: \"ES6 Renderer\", footer: \"MIT License\" } },\n    (err) =\u003e expect(err instanceof Error).to.equal(true);\n).then((err) =\u003e expect(err instanceof Error).to.equal(true));\n```\n\n### License\n\nMIT License\n\nCopyright (c) 2015 Dian Dimitrov\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdondido%2Fexpress-es6-template-engine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdondido%2Fexpress-es6-template-engine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdondido%2Fexpress-es6-template-engine/lists"}