[SOLVED] Handlebar not executed for dynamically loaded HTML

Given a template with a placeholder paragraph we intercept its id and substitute it with an external HTML file.
The HTML file contains some text and a handlebar expression which is not executed.

Context

Control Script

with the following handlebar defined:

Handlebars.registerHelper('verbo', function(tu, voi){
	sesso = this.Receiver__Sex
	
	if (sesso == 'M' || sesso == 'F'){
		return tu
	}
	
	if (sesso == 'S') {
		return voi
	}
	
	return 'KO DECLINAZIONE VERBO TU VOI'
})

Standard script

with the body selector, we then query the needed part using the built-in function.

results = query('#assistenza')

// carico lo snippet html esterno
assistenza = loadhtml(merge.template.parameters.rootRepository + "ol-connect/html/assistenza.html");

results.replaceWith(assistenza)

External HTML file

<p>
{{verbo 'Le' 'Vi'}} ricordiamo che il Servizio Clienti XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX (dall’estero) dal lunedì al venerdì dalle 8.30 alle 19.00 e il sabato dalle 9.00 alle 13.
</p>

Template

In the template we have the following paragraph:

<p id="assistenza"></p>

Result

As shown below the paragraph gets correctly replaces with the external HTML however the handlebar defined in the external HTML file is not executed.

Why a remote snippet isn’t suitable

This use case should be generally approached with a remote snippet, however given that the remote HTML file to be loaded follows certain logics we can’t hard code the loading path. That’s why I need to load it using a script.

I initially thought my issue was a duplicate of [Solved] Handlebar snippets rendered as text instead of html
but it isn’t. I have a handlebar inside a dynamically loaded HTML, while the other thread has un-rendered HTML inside the snippet.

Based on the assumption that handlebars registered in a ControlScript are also executed at the time the Control Scripts are executed I solved my issue by modifying the script with the addition of a call to Handlebars.render().


results = query('#assistenza')

// carico lo snippet html esterno
assistenza = loadhtml(merge.template.parameters.rootRepository + "ol-connect/html/assistenza.html");

assistenza = Handlebars.render(assistenza)

results.replaceWith(assistenza)

I don’t know if this is the right solution but feedback is welcome.

Using an external Handlebars snippet (*.hbs) instead of an external HTML snippet (*.html) should be sufficient.

Tip: See loadhtml() - OL Connect 2024.1 Help for more information about the loadhtml function.


Example

Print Section

<div id="example"><br></div>

External Handlebars snippet

<p>
	{{Example 'John Doe'}}
</p>

Control Script

Name: Helper

Handlebars.registerHelper("Example", function(name) {
	return "Hello " + name;
});

Standard Script

Name: Example
Selector: #example

var result = "";

result = loadhtml("file:///C:/Resources/Snippets/example.hbs");

results.html(result);

I’ve tried exactly as suggested with no success.

I’ve noticed you used results.html() instead of results.replaceWith(), if my understanding of the documentation is right the former puts the content of the snipped inside the HTML node returned by the selector, while the latter removes the node and in its place puts the content.

results.html() should construct:

<div id="example">
<p>
	{{Example 'John Doe'}}
</p>
</div>

results.replaceWith() should eliminate the original <div>:

<p>
	{{Example 'John Doe'}}
</p>

However, this shouldn’t be a big deal, in the hypothesis that loadhtml() with a .hbs perform the handlebar evaluation only on the direct child loaded I’ve tried both scenarios but with no success. The handlebar still isn’t executed.

EDIT - POSSIBLE CAUSE

I’ve noticed only now that you linked the 2024.1 docs, I’m on 2023.1 and indeed when loading the documentation for this version of that same page there is no mention of loading hbs. I suppose hbs evaluation has been added only later.

https://help.uplandsoftware.com/objectiflune/en/planetpress_connect/2023.1/designer/API/loadhtml.html

Yes, that’s correct.

As for OL Connect version 2023.1, you can use Handlebars.render() instead of loadhtml().

The loadhtml() function has been improved to enable loading Handlebars snippets in addition to HTML snippets. This replaces the lengthier Handlebars.render() notation.

Source: 2023.2.2 Release Notes - OL Connect 2023.2 Help

1 Like