Skip to end of metadata
Go to start of metadata

About

Dust is a JavaScript templating engine designed to provide a clean separation between presentation and logic without sacrificing ease of use. It is particularly well-suited for asynchronous and streaming applications, and inside its core Dust offer a set of filters that can be used in specific scenarios like to force HTML escaping, but there are not filters for all the possible scenarios, in this post I will show you how you can easily extend Dust filters using jQuery. 

Note: Dust documentation makes the following assertion when you use filters: "all output values are escaped to avoid Cross Site Scripting (XSS) unless you use filters.", but only applies to the default filters that brings Dust. If you create your own filters, they are still protected against XSS unless used in conjunction with the default Dust filters.

First, If you look into Dust source code you will find that the next filters are already defined:

dust.filters = {
  h: function(value) { return dust.escapeHtml(value); },
  j: function(value) { return dust.escapeJs(value); },
  u: encodeURI,
  uc: encodeURIComponent,
  js: function(value) { if (!JSON) { return value; } return JSON.stringify(value); },
  jp: function(value) { if (!JSON) { return value; } return JSON.parse(value); }
};

In order to extend Dust filters without touching the source code I will use jQuery extend, you can use others frameworks like Underscore.js ( _.extend function ) too, but I feel very comfortable with jQuery so, here we go.

 

jQuery extend description: Merge the contents of two or more objects together into the first object. When two or more object arguments are supplied to jQuery.extend(), properties from all of the objects are added to the target object. Arguments that are null or undefined are ignored.

That means that is possible to read dust.filters object with jQuery.extend and merge it with a new object (my new filter):

dust.filters = jQuery.extend({
    my_filter: function(value){ 
            //your code
        }
}, dust.filters);

If you are going to add more than one filter, you can created a separate object as the container of your new filters and pass it to jQuery.extend instead of create them inside jQuery extend.

 

Don't forget to call the Dust filters extension after Dust is already called.

<script type="text/javascript" src="dust-full-1.2.5.js"></script>

<script type="text/javascript" src="my_filters.js"></script>

 

Now you can use you new filter in the same way as the original Dust filters:

<div class="title">
	{title|my_filter}
</div>

 

As I mentioned before, If you create your own filters they are still protected against XSS, but be careful, Dust filters can be chained, that means that you can use more of one filter at the same time, as the next example:

<!-- source data -->
<td class="title"><script>alert('hello world');</script>Sports 1</td>

<!-- template -->
<div class="title">
	{title|my_filter|s}
</div>

In this particular case title is NOT LONGER protected again XSS since the filter --> " |s " suppresses auto-escaping, so, be careful in the way you chain filters, specially with the default filters.

 

Also, is possible to replicate the same functionality as a helper:

dust.helpers.my_filter = function (chunk, ctx, bodies, params) {
    var my_parameter = dust.helpers.tap(params.name_parameter, chunk, ctx),
    //your code
    return chunk.write(/* output */);
}

 

Your template will looks like:

<div class="title">
    {@my_filter name_parameter="{title}" /}
</div>

Hope you find this information useful!

 

About the author

Enterprise Web Developer
Joaquin is an Enterprise Web Developer at Base22 with over seven years of experience designing and developing web solutions for enterprise clients. He is a well rounded web developer with skills building interfaces in IBM WebSphere Portal and WCM, IBM Connections, and many others. He is an Oracle Certified Java Developer and a Microsoft Certified Visual Studio Developer. He blogs at http://j-arellano.com