Abbreviation:
- CE: custom element
- CA: custom attribute
Terminologies:
- Consumer template:
A consumer template of a CE/CA is a template where a CE/CA is used). For example, the following is a consumer template of CEname-tag
:<!-- app.html --> <template> First Name: <input value.bind="firstName" /> Last Name: <input value.bind="lastName" /> <name-tag name="${firstName} ${lastName}"></name-tag> </template>
How it looks like
Sometimes, you may come across a tutorial or a code block of Aurelia that looks like this
@processContent(...)
export class Example {
}
Notice decorator usage @processContent
, it defines some metadata for the class (CE/CA) of how to process the content in consumer template. So what is / are the content?
- For CE: Content is the children elements / nodes of the CE element in consumer template. For example, suppose we have CE named
panel
, in the following template:
content will be all child nodes of<template> <panel> <header></header> <div class="panel-body"></div> </panel> </template>
<panel>
element - For CA: Content is the children elements / nodes of the element that the CA resides. For example, suppose we have CA named
selectable
, in the following template:
conent will be all child nodes of<template> <div id="selectable-div" selectable> <div repeat.for="item of selection">${item}</div> </div> </template>
<div/>
with idselectable-div
What is it for
@processContent
is used for ensuring the content of a target element to a more suitable template form.
For example, a <ux-select/>
CE should only accept 2 CE in its content: <ux-option/>
and <ux-optgroup/>
. However, the user of <ux-select/>
may accidentally supplied a <div/>
, which will cause the widget to function incorrectly or even break:
<template>
<ux-select>
<ux-option>...</ux-option>
<div>oops gonna break</div>
</ux-select>
</template>
With @processContent
, author of <ux-select/>
can define a function that helps remove all invalid child nodes before progressing further, to either issue a warning so either developers can fix the template, or prevent the widget from breaking. processContent
function takes 4 parameters:
-
compiler
: the view compiler instance being used for compilation -
resources
: the view resources instance being used for resources lookup during compilation -
node
: the element where the content of it needs to be processed -
instruction
: the behavior instruction instance that is associated with either CE/CA in the consumer template
Back to our example above with the troublesome <div/>
, we can use @processContent
to remove it:
import { ViewCompiler, ViewResources, BehaviorInstruction, processContent } from 'aurelia-framework';
@processContent((
compiler: ViewCompiler,
resources: ViewResources,
node: Element,
instruction: BehaviorInstruction
): boolean => {
// remove every child element that is not either `<ux-option/>` or `<ux-optgroup/>`
// ... real code to remove ... ex. node.removeChild(node.lastElementChild)
return true;
}
)
export class UxSelect {
}
Notice the return true
at the end of the function, by returning true, we are signaling the compiler to continue the compilation process for the content, as it was paused when it hit a CE or an element with CA on it. Some examples of advanced usage:
- combining
@processContent
withreturn false
to extract the content and compile into a factory, marked with an ID to use later. Everyone can go pretty clever & creative with this. - combining
@processContent
withreplace-part
&<template/>
to targetreplaceable
template in CE
Live example
- official
<ux-select/>
element: https://github.com/aurelia/ux/blob/master/packages/select/src/ux-select.ts#L505-L526 - … to be updated
If you have an example of @processContent
you would like to share to help folks better understand it, please leave a link and I’ll incorporate it in live example section