Project: moodle
Issue MDL-54915: Rendering concurrent Mustache templates with strings loses javascript
Using client-side rendering of multiple templates at once can cause any {{#js}} blocks in those templates to be lost, if the template needs to fetch language strings from the server. This is because there is a single shared templates module with global state containing the required javascript additions, and it is reset on every call to render(). *To reproduce:* * Create a plugin in {{local}} called mustacheproblems. * Create a template called {{problem.mustache}} {code:html} {{! @template local_mustacheproblems/problem Example context (json): {} }}

This is a template whose {{#str}} javascript, local_mustacheproblems {{/str}} has not been run

{{#js}}	require(['jquery'], function($) {	$('#some-span-{{uniqid}}').html('has been run');	}) {{/js}} {code} * Create a second template called {{problems.mustache}} {code:html} {{! @template local_mustacheproblems/problems Example context (json): {} }}

{{#js}} require(['jquery', 'core/templates'], function($, Templates) {	for(var i = 0; i < 5; i++) {	var promise = Templates.render('local_mustacheproblems/problem', {});	promise.done(function(html, js) {	$('#problems-{{uniqid}}').append(html);	Templates.runTemplateJS(js);	});	} }); {{/js}} {code} * Add the following strings to the {{lang/en/local_mustacheproblems.php}} {code:php} $string['pluginname'] = 'Mustache problems'; $string['javascript'] = 'Javascript'; {code} * View local_mustacheproblems/problems in the Template Library *Expected result:* All five divs should read "Javascript has been run" *Actual result:* Only the last div reads "Javascript has been run". If you select the template again, then with the required language string cached, all five divs read "Javascript has been run". *Notes:* I have marked this as 2.9.6 because that's the only system I've tested it on, however looking at the code for master shows that the bug is still present.
Story points: 4