diff --git a/admin/tool/templatelibrary/amd/build/display.min.js b/admin/tool/templatelibrary/amd/build/display.min.js index 4b5103c0186..0c75544343f 100644 --- a/admin/tool/templatelibrary/amd/build/display.min.js +++ b/admin/tool/templatelibrary/amd/build/display.min.js @@ -1 +1 @@ -define(["jquery","core/ajax","core/log","core/notification","core/templates","core/config","core/str"],function(a,b,c,d,e,f,g){var h=function(a,b){if(!a)return!1;var c="@template "+b,d=0,e=[];if(e=a.match(/{{!([\s\S]*?)}}/g),null!==e)for(d=0;d new external_value(PARAM_COMPONENT, 'component containing the template'), 'template' => new external_value(PARAM_ALPHANUMEXT, 'name of the template'), 'themename' => new external_value(PARAM_ALPHANUMEXT, 'The current theme.'), + 'includecomments' => new external_value(PARAM_BOOL, 'Include comments or not', VALUE_DEFAULT, false) ) ); } + /** + * Remove comments from mustache template. + * @param string $templatestr + * @return mixed + */ + protected static function strip_template_comments($templatestr) { + return preg_replace('/(?={{!)(.*)(}})/sU', '', $templatestr); + } + /** * Return a mustache template, and all the strings it requires. * @@ -65,17 +75,19 @@ class external extends external_api { * @param string $themename The name of the current theme. * @return string the template */ - public static function load_template($component, $template, $themename) { + public static function load_template($component, $template, $themename, $includecomments = false) { global $DB, $CFG, $PAGE; $params = self::validate_parameters(self::load_template_parameters(), array('component' => $component, 'template' => $template, - 'themename' => $themename)); + 'themename' => $themename, + 'includecomments' => $includecomments)); $component = $params['component']; $template = $params['template']; $themename = $params['themename']; + $includecomments = $params['includecomments']; $templatename = $component . '/' . $template; @@ -83,6 +95,11 @@ class external extends external_api { $filename = mustache_template_finder::get_template_filepath($templatename, $themename); $templatestr = file_get_contents($filename); + // Remove comments from template. + if (!$includecomments) { + $templatestr = self::strip_template_comments($templatestr); + } + return $templatestr; } diff --git a/lib/tests/output_external_test.php b/lib/tests/output_external_test.php new file mode 100644 index 00000000000..35acb97cff1 --- /dev/null +++ b/lib/tests/output_external_test.php @@ -0,0 +1,147 @@ +. + +/** + * Unit tests for lib/classes/output/external.php + * @author Guy Thomas + * @copyright Copyright (c) 2017 Blackboard Inc. + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +use core\output\external; + +require_once(__DIR__.'/../../lib/externallib.php'); +require_once(__DIR__.'/../../lib/mustache/src/Mustache/Tokenizer.php'); +require_once(__DIR__.'/../../lib/mustache/src/Mustache/Parser.php'); + +/** + * Class core_output_external_testcase - test \core\output\external class. + * @package core + * @author Guy Thomas + * @copyright Copyright (c) 2017 Blackboard Inc. + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class core_output_external_testcase extends base_testcase { + + /** + * Ensure that stripping comments from templates does not mutilate the template body. + */ + public function test_strip_template_comments() { + + $templatebody = <<<'TBD' +

{{# str }} pluginname, mod_lemmings {{/ str }}

+
{{test}}
+
{{{unescapedtest}}}
+ {{#lemmings}} +
+

{{name}}

+ {{> mod_lemmings/lemmingprofile }} + {{# pix }} t/edit, core, Edit Lemming {{/ pix }} +
+ {{/lemmings}} + {{^lemmings}}Sorry, no lemmings today{{/lemmings}} +
+ {{# tabheader }} + + {{/ tabheader }} + {{# tabbody }} +
+ {{# tabcontent }} + {{# tabs }} + {{> core/notification_info}} + {{/ tabs }} + {{/ tabcontent }} +
+ {{/ tabbody }} +
+ {{#js}} + require(['jquery','core/tabs'], function($, tabs) { + + var container = $("#{{ uniqid }}-tab-container"); + tabs.create(container); + }); + {{/js}} +TBD; + $templatewithcomment = <<. + }} + {{! + @template mod_lemmings/lemmings + + Lemmings template. + + The purpose of this template is to render a lot of lemmings. + + Classes required for JS: + * none + + Data attributes required for JS: + * none + + Context variables required for this template: + * attributes Array of name / value pairs. + + Example context (json): + { + "lemmings": [ + { "name": "Lemmy Winks", "age" : 1, "size" : "big" }, + { "name": "Rocky", "age" : 2, "size" : "small" } + ] + } + + }} + $templatebody + {{! + Here's some more comment text + Note, there is no need to test bracketed variables inside comments as gherkin does not support that! + See this issue: https://github.com/mustache/spec/issues/8 + }} +TBC; + + // Ensure that the template when stripped of comments just includes the body. + $stripped = phpunit_util::call_internal_method(null, 'strip_template_comments', + [$templatewithcomment], 'core\output\external'); + $this->assertEquals(trim($templatebody), trim($stripped)); + + $tokenizer = new Mustache_Tokenizer(); + $tokens = $tokenizer->scan($templatebody); + $parser = new Mustache_Parser(); + $tree = $parser->parse($tokens); + $this->assertNotEmpty($tree); + } +}