- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
I spent a few days working to get client side js based templates to work in our CMS. I wanted to share with everyone how I made that work.
1. The templates will have to be embedded in the DOM under script tags.
2. The template syntax will require using the Jelly tags for special characters, and some interesting 2 stage parsing to clean up the mess jelly leaves in the templates
this includes replacing the "&", "<" and ">" characters with jelly equivalents: ${AMP}, ${LT}, ${GT}
3. Jelly mangles the special characters contained in HTML attributes, which is the reason for a wierd second stage string replace in the client
// do a global replace for the html character codes jelly produces for brackets
// second pass required for any brackets encased in html attributes
templ_str = _.unescape($templ.html()).replace(/&lt;/g, '<').replace(/&gt;/g, '>');
4. jQuery is used to pull the templates out of the DOM and the HTML contained in the script tag is passed to the underscore template engine
1. two dynamic blocks are used, one acts as a container for all client side templates
wrapper
<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<!-- sysid: ******************************* -->
<div class="hidden" data-descr="template container for underscore.js client side templates">
<!-- large search auto-complete hints -->
<g:content_block type="content_block_programmatic" id="128c***********************a1549"/>
<!-- search - catalog items -->
<g:content_block type="content_block_programmatic" id="e1cb***********************a1528"/>
<!-- search - knowedge base articles -->
<g:content_block type="content_block_programmatic" id="e79e***********************a150d"/>
</div>
</j:jelly>
client side template - search
<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<!-- sys_id: *************************** -->
<script>
${LT}% if(data.length){ %${GT}
<div class="col-sm-12 padding-left-0 padding-right-0" data-category="${LT}%= category_name %${GT}">
<div class="row">
<div class="col-sm-12 header padding-top-2pct padding-bottom-1pct">
<h3 class="h3">Knowledge Base</h3>
</div>
</div>
<div class="row">
<div class="col-sm-12 request_list" data-delegate-bound="true">
<ul class="styled_link">
${LT}% _.each(data, function(obj, key){ %${GT}
<li data-sys-id="${LT}%= obj.sys_id %${GT}">
<div class="title">
<a target="_new" href="#">
<span>${LT}%= obj.descr %${GT}</span>
</a>
</div>
<div class="short-description">
<span>${LT}%= obj.intro %${GT}</span>
</div>
</li>
${LT}% }); %${GT}
</ul>
</div>
</div>
</div>
${LT}% } %${GT}
</script>
</j:jelly>
Client script function to parse template from DOM
/**
read underscore.js formatted js template from DOM, and convert to a template function
@method _getTemplate
@param {str} tmpl_id DOM id of the template
@returns {function} underscore template fx
@link http://stackoverflow.com/questions/4778881/how-to-use-underscore-js-as-a-template-engine
*/
_getTemplate : function(tmpl_id){
var result;
var context = this;
// prevent jQuery and prototype collision with an IIFE
(function($){
try{
if (!(_.isString(tmpl_id) && tmpl_id.length)){
throw new Error('Invalid parameter "template id"');
}
// pull up the template and correct for the html encoded brackets
var $templ = $('#'+tmpl_id);
var templ_str = '';
if ($templ && $templ.length){
if ($templ.html().length){
// do a global replace for the html character codes jelly produces for brackets
// second pass required for any brackets encased in html attributes
templ_str = _.unescape($templ.html()).replace(/&lt;/g, '<').replace(/&gt;/g, '>');
//log.info(templ_str);
result = _.template(templ_str);
}
else{
throw new Error('Template "'+tmpl_id+'" is empty. No HTML found to render');
}
}
else{
throw new Error('Template "'+tmpl_id+'" not found in the DOM');
}
}
catch(e){
log.error('Error: '+e.message+' - _getTemplate::'+context.type);
}
})(jQuery);
return result;
},
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.