juice
juice copied to clipboard
Unable to use FreeMarker template tags as juice.codeBlocks
Issue
I'm using FreeMarker templating tags inside an email template. However, when I try to exclude these using the juice.codeBlocks
global, it still parses them.
juice.codeBlocks = {
start: '<#',
end: '>'
};
juice('<#list myObject.values as value></#list>');
Expected result
<#list myObject.values as value></#list>
Actual result
<#list myObject.values="" as="" value=""></#list>
Example https://runkit.com/587926812ee9040013e6cc04/587926812ee9040013e6cc05
The way this is documented is misleading, please see below for a working sample. Note that using >
as the end tag is probably best replaced by </#
since that token might not be parsed correctly.
https://runkit.com/58798a6d4936050013759c0c/58798a6e09267a001378ddde
Some more comments for anyone looking at this in the future. The reason @ryanwalters example wasn't working is because:
- codeBlocks was formatted incorrectly -- it should follow the format:
{
EJS: { start: "<%", end: "%>" },
HBS: { start: "{{", end: "}}" },
}
Note the immediate children are strings, so it can support multiple languages
- you shouldn't overwrite codeBlocks directly, you should modify the reference in place, for example using Object.assign()
Object.assign(juice.codeBlocks, {
FM: {
start: '<#',
end: '</#'
}
});
const content = juice('<#list myModel.values as values></#list>');
console.log(content);
Output:
<#list myModel.values as values></#list>
Example https://runkit.com/wdonnell/5c1285a063adcd0016f35a36
I'm also using juice on freemarker templates -- using </#
as your end tag as @jrit suggested works for one liners, but HTML inside freemarker blocks won't be parsed by juice:
Object.assign(juice.codeBlocks, {
freeMarker: {
start: '<#',
end: '</#'
}
});
const content = juice(`
<style>.red{color:red;}</style>
<#list myModel.values as values>
<p class="red">this is some text</p>
</#list>`);
Output
<#list myModel.values as values>
<p class="red">this is some text</p>
</#list>
The freemarker tags aren't mangled, but the <p>
inside the list doesn't have its style inlined, either.
I've had good results by setting separate codeBlocks for starting and ending tags, like this:
Object.assign(juice.codeBlocks, {
freeMarkerStart: {
start: '<#',
end: '>'
},
freeMarkerEnd: {
start: '</#',
end: '>'
}
});
const content = juice(`
<style>.red{color:red;}</style>
<#list myModel.values as values>
<p class="red">this is some text</p>
</#list>`);
Output
<#list myModel.values as values>
<p class="red" style="color: red;">this is some text</p>
</#list>
Example https://runkit.com/wdonnell/5c127b91305cdd00133e2d5d
Now, the styles are correctly inlined and the freemarker templates still work as intended
@wdonnell if you have any interest in opening a PR to integrate that bit about separate start/end blocks especially into the readme that would be rad
Juice by default supports HandleBars and EJS templates. Is there any reason why we can't add FreeMarker by default?
It seems that template configs are hardcoded in https://github.com/Automattic/juice/blob/1f823792e78e455760a4fce3b67c0450d7bc4e2d/lib/cheerio.js file.