Details
-
Type:
Bug
-
Status: Closed
-
Priority:
Blocker
-
Resolution: Fixed
-
Affects Version/s: 2.9.6, 3.0.4, 3.1
-
Component/s: JavaScript, Libraries
-
Testing Instructions:
-
Affected Branches:MOODLE_29_STABLE, MOODLE_30_STABLE, MOODLE_31_STABLE
-
Fixed Branches:MOODLE_30_STABLE, MOODLE_31_STABLE
-
Pull from Repository:
-
Pull Master Branch:
MDL-54915-master
-
Story Points:3.67
-
Sprint:3.2 Sprint 3
Description
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
{{!
|
|
@template local_mustacheproblems/problem
|
|
Example context (json): {}
|
|
}}
|
|
<div>This is a template whose {{#str}} javascript, local_mustacheproblems {{/str}} <span id="some-span-{{uniqid}}">has not been run</span></div> |
{{#js}}
|
require(['jquery'], function($) {
|
$('#some-span-{{uniqid}}').html('has been run');
|
})
|
{{/js}}
|
- Create a second template called problems.mustache
{{!
|
|
@template local_mustacheproblems/problems
|
|
Example context (json): {}
|
|
}}
|
<div id="problems-{{uniqid}}"> |
</div> |
{{#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}}
|
- Add the following strings to the lang/en/local_mustacheproblems.php
$string['pluginname'] = 'Mustache problems'; |
$string['javascript'] = 'Javascript'; |
- 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.