Aurelia 2, the latest incarnation of the Aurelia framework, is packed with improvements and new features. Among these, the revamped template compiler stands out for its potential to significantly boost your productivity. This article takes a deep dive into the template compiler, focusing on functionality that allows developers to intercept and modify the compilation process of an application’s templates.
Introduction to the Template Compiler
Aurelia’s template compiler operates behind the scenes, processing templates and providing hooks and APIs that allow developers to modify their default behaviour. One critical use case for the template compiler is the ability to preprocess a template before it’s compiled. This could be for reasons such as accessibility validation, the addition of debugging attributes, or even the injection of custom attributes or elements.
Harnessing the Power of Template Compiler Hooks
Currently, the primary hook provided by the template compiler is compiling
. This hook gets invoked before the template compiler starts compiling a template, allowing you to modify it before its compilation.
Hooks can be declared globally (at startup) or within a local container (at runtime or via convention-based imports).
Let’s take a look at an example of declaring a global hook using the decorator approach:
import Aurelia, { templateCompilerHooks } from 'aurelia'; @templateCompilerHooks class GlobalHook { compiling(template: HTMLElement) { template.querySelector('table').setAttribute(someAttribute, someValue); } } Aurelia.register(GlobalHook);
In this example, the compiling
hook modifies a table
element within the template. The querySelector
method targets the table
element, and then the setAttribute
method adds or modifies an attribute.
You would globally register this inside of main.ts
Practical Examples of Template Compiler Hooks
Now that we’ve covered the basics let’s delve into more advanced practical examples of using template compiler hooks.
Enforcing Image Accessibility
A compelling use case for the compiling
hook is enforcing the inclusion of alt
tags for all img
elements, enhancing accessibility.
Here’s how to do it:
import Aurelia, { templateCompilerHooks } from 'aurelia'; @templateCompilerHooks class ImageAltHook { compiling(template: HTMLElement) { const images = template.querySelectorAll('img'); images.forEach(image => { if (!image.hasAttribute('alt')) { image.setAttribute('alt', 'placeholder alt text'); } }); } } Aurelia.register(ImageAltHook);
In this code, we’re selecting all img
elements within the template. For each image, we check if an alt
attribute exists. If it doesn’t, we add one with placeholder text. You can even add inline styles to flag components that must be addressed.
Injecting Custom Attributes
Another advanced use case is injecting custom attributes into specific elements. For instance, you may want to add a my-custom-attr
attribute to all div
elements:
import Aurelia, { templateCompilerHooks } from 'aurelia'; @templateCompilerHooks class CustomAttrHook { compiling(template: HTMLElement) { const divs = template.querySelectorAll('div'); divs.forEach(div => { div.setAttribute('my-custom-attr', 'custom value'); }); } } Aurelia.register(CustomAttrHook);
Here, we’re selecting all div
elements and adding a my-custom-attr
attribute with a value of custom value
.
Injecting as-element Directives
You can also use the compiling
hook to inject as-element
directives into your template. For example, if you want to treat a specific div
as a custom element, you could do the following:
import Aurelia, { templateCompilerHooks } from 'aurelia'; @templateCompilerHooks class AsElementHook { compiling(template: HTMLElement) { const targetDiv = template.querySelector('div#target'); if (targetDiv) { targetDiv.setAttribute('as-element', 'my-custom-element'); } } } Aurelia.register(AsElementHook);
In this example, we’re selecting a div
with the id target
and adding the as-element
attribute to it, effectively treating it as my-custom-element
. In a real-world example, you might want to replace buttons with custom elements or add attributes to add behaviours to certain elements.
Conclusion
With its powerful hooks, Aurelia 2’s template compiler opens up possibilities for preprocessing and adjusting templates before compilation. This article hopefully provides you with a deeper understanding and practical examples of using this feature. As the Aurelia community continues to explore and innovate, we can expect to see even more creative uses for template compiler hooks in the future.