processContent in Aurelia 2

In Aurelia 1 there was the @processContent decorator, is there something similar in Aurelia 2?

I found the following, but processContent is not called. Could someone help me?

import { IPlatform, customElement, INode } from 'aurelia';

@customElement({
  name: 'products',
  template: '<span>id: ${id}</span>',
  processContent: (node: INode, platform: IPlatform) => {
    alert('test');
    console.log(node);
  },
})
export class Products {
  id = 100;
}

Hi @elitastic! It does work. Here is an example: process-content (forked) - StackBlitz

Note that processContent is a hook that is invoked during template compilation statically. That is when the CE (ce1) that has the processContent hook, is used statically in the template of another CE (ce2), during the template compilation of ce2, the ce2#processContent will be invoked. However, for router, we are dynamically adding and removing component to and from the viewport. Invoking processContent on such cases makes little sense, considering the use-case, processContent intend to solve in the first place.

Hi @Sayan751, thanks for your help. I was just playing around on StackBlitz with Au2, my use case was not well chosen. Sorry for that.

I took your example and modified it like:

import { INode, IPlatform } from '@aurelia/runtime-html';

export class FooBar {
  value = 'hooray';

  static processContent(node: INode, platform: IPlatform) {
    var span = document.createElement('span');

    span.innerHTML = '<span>${value}red</span>';

    node.appendChild(span);

    return true;
  }
}

Should this work or did I misunderstand “processContent”?

Actually, you want to use the processContent hook to adjust the declarative template passed from the usage side, to something more native to Aurelia. For example, when you are designing a tabs control, one way to do this can be to have 2 separate bindables for the tab header and content. Then you can do the following.

<tabs headers.bind content.bind></tabs>

But that would not offer any semantics. Rather than doing that, you can allow the following templating syntax.

  <tabs>
    <tab header="Tab1">
      <span>content 1</span>
    </tab>
    <tab header="Tab2">
      <span>content 2</span>
    </tab>
    <tab header="Tab3"> Nothing to see here. </tab>
</tabs>

With that, you offer more semantics for the user of the control. And in the background, you use the processContent hook to convert that template to something more manageable for Aurelia.

Here is an example of this: process-content v2 (forked) - StackBlitz

It seemed to me that you have tried to override the template of the foo-bar CE from the processContent hook. That is not a thing, for which you should use the processContent hook. Note also that when you are adding new children HTML nodes under the foo-bar node, these template changes happen in the context where the foo-bar CE is used. Thus, in your case, you are technically expecting a value property in the CE, that is using the foo-bar CE. Although this kind of expectation indicates not-sound designs, here is a modified version of your example, when we still pursue this: process-content v2 (forked) - StackBlitz

Note that the foo-bar CE now uses a slot.

Hope this explanation helps.

1 Like