Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-54915

Rendering concurrent Mustache templates with strings loses javascript

    XMLWordPrintable

    Details

    • Testing Instructions:
      Hide
      Setup
      1. Apply the attached patch to add the templates detailed in the description
      Testing
      1. With patch reverted (or not yet applied), navigate to the template library
      2. Search for the core/problems template and select it
      3. Observe that some of the strings do not match and say that they have not been run
        Note: you must refresh the page between attempts - this only fails when strings are not yet cached
      4. Apply the patch
      5. Refresh the page
      6. Load the same template
        1. Confirm that all strings say that they have been run
      Show
      Setup Apply the attached patch to add the templates detailed in the description Testing With patch reverted (or not yet applied), navigate to the template library Search for the core/problems template and select it Observe that some of the strings do not match and say that they have not been run Note: you must refresh the page between attempts - this only fails when strings are not yet cached Apply the patch Refresh the page Load the same template Confirm that all strings say that they have been run
    • Affected Branches:
      MOODLE_29_STABLE, MOODLE_30_STABLE, MOODLE_31_STABLE
    • Fixed Branches:
      MOODLE_30_STABLE, MOODLE_31_STABLE
    • Pull from Repository:
    • Pull 3.1 Branch:
    • 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.

        Attachments

          Activity

            People

            • Votes:
              2 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Fix Release Date:
                12/Sep/16