EJS Element (v1.0 npm release)
So I began using the following pattern to snuggle an EJS template directly into HTML files; putting the template in a script tag inserted just outside of a given target element so that by reading said HTML it is fairly obviously implied that that template will be output there.
<html>
<body>
<p>This is my HTML page</p>
<div id="badThingsContainer"></div>
<script id='badThingsTemplate' type='text/ejs'>
<h1>bad things:</h1>
<ul>
<? badThings.forEach(function(thing) { ?>
<li class="red"><?= thing ?></li>
<? }) ?>
</ul>
</script>
</body>
</html>
Then your render call looks like this:
var template = document.getElementByID('badThingsTemplate').innerHTML,
document.getElementByID('badThingsContainer').innerHTML = ejs.render(template, {badThings: badThings})
A little cleaner and better separated, however - this is still a bit clunky if you have to deal with several different templates on a given page (having to keep track of IDs and render them individually etc).
So then I came up with this little wrapper function to help automate things:
var renderEJS = (baseName, data) => {
var template = document.getElementById('#' + baseName + 'Template')
document.getElementById('#' + baseName + 'Container').innerHTML = ejs.render( template, data )
}
//to render then, simply call:
renderEJS('badThings', {badThings: badThings})
(your HTML / EJS template can remain the same as in the previous example; note the required '...Container' and '...Template' ids)
Enter EJS Element
We can condense this further & make it a lot more intuitive to use by simply allowing the use of EJS directly. Here is the way to do it using my new module EJS Element now available on npm / Github.
In your HTML page:
<bad-things>
<h1>bad things:</h1>
<ul>
<? badThings.forEach(function(thing) { ?>
<li class="red"><?= thing ?></li>
<? }) ?>
</ul>
</bad-things>
then in your JS:
var ejsElem = require('ejs-element')
ejsElem.init('bad-things', {badThings: badThings}, true)
Done! Your element will work in any static HTML page; just load this library, call the init function above and you are good to go.
If you need to render that element again later you can simply call:
ejsElem.render('bad-things', moreBadThings)
Where moreBadThings
is your updated state. Or omit the state parameter and it will fallback to the previously supplied state.
Check the docs for complete details - and if you encounter any issues, feel free to post them on the tracker.
p.s. - the parsing logic is rather inefficient - so plenty of room for improvement! Suggestions or pull requests are welcomed.
For example, performance will be slow if doing a high volume of elements. And there are edge cases for what kind of JS you can use inside the element that can break parsing (resulting in an unrendered/broken element on your page; typically with a corresponding EJS error in the console) so keep that in mind if you intend to do complex operations in your template; if you do spot one of such cases please post the issue or try your luck at updating the parsing code to accommodate for your needs.