Custom Attribute Directives With TLX

A number of front-end libraries and even HTML 5 itself support the creation of custom HTML elements. A logical extension is custom attribute directives, but until now, only three libraries I am aware of make custom attribute directives available, Angular 2, Vue and hyperHTML. This capability is now available in Tlx, at 3.9K compressed and gzipped a library far smaller than Angular 2 or Vue and slightly smaller than hyperHTML.

If you have not read Direct HTML Templating With TLX, you might want to read it first.

For those unfamiliar with attribute directives, they allow you to use attribute values to control the rendering of content in sophisticated ways. One of the most popular of these is to loop over content to create a table. The syntax varies slightly between Vue, Angular and Tlx, but the below illustrates the point, e.g.

<table id="foreach" t-foreach="${['a','b','c']}">
<tr>
<td>${index+1}</td><td>${value}</td>
</tr>
</table>

will produce the HTML

<table id="foreach" t-foreach="['a','b','c']">
<tr>
<td>1</td><td>a</td>
</tr>
<tr>
<td>2</td><td>b</td>
</tr>
<tr>
<td>3</td><td>c</td>
</tr>
</table>

Although the attribute directives in Vue and Angular can respond to a number of lifecycle events, defining them also adds some complexity to your codebase. For the first release in Tlx, we focused on a minimalistic approach that can require as little as one line of code. In fact, here is the code for the t-if directive that is delivered with Tlx out of the box:

"t-if": (bool,model,actions,render) => {
if(bool) return render(model,actions);
}

Tlx custom attribute directive handler functions take as their first argument the attribute value, their second the model/state associated with the element in which the attribute resides, the actions available, an automatically generated render function and an object, directive, describing the directive. The directive code is free to do any logic it wants and return either the results of renderor directive.element, which will be an HTMLElement and stop processing of children, a custom HTML element (which will replace the original element), true,which will continue processing of child elements. If a falsy value if returned, then the element will be dropped from the DOM.

Tlx itself is enhanced by assigning the directive name as a key to tlx.directives with the handler as an argument. The directive below will change the case of content. Although this could probably be accomplished with CSS, it is a simple way to illustrate the power of custom attribute directives.

tlx.directives["my-case"] = function(toCase,model,actions,render) {
switch(toCase) {
case "upper": {
return render(model,actions).innerHTML.toUpperCase();
};
case "lower": {
return render(model,actions).innerHTML.toLowerCase();
};
default: return render(model,actions);
}
}

You can see the my-directive example in action on JSFiddle.

Although the custom attribute directives in Vue and Angular can support a range of lifecycle events and Tlx’s first generation do not, the Tlx ones can still cover a broad range of use cases.

The functionality of many custom attributes, and certainly those show above, can be replicated with JSX code in React, Preact or hyperApp, but the intent of this article is not to debate the pros and cons of attribute directives vs lower level script. In fact, the intent of Tlx is to be as un-opinionated as possible and let you choose. You could also produce the same functionality in Tlx string template literal scripts.

Give Tlx a try and give this article a clap if you like what you see.

You might also wish to read Direct HTML Templating with TLX or HTML Injection Protection With TLX.