function($, ajax, log, notification, templates, config, str) {
/**
- * Handle a template loaded response.
+ * Search through a template for a template docs comment.
*
- * @param {String} templateName The template name
- * @param {String} source The template source
+ * @param {String} templateSource The raw template
+ * @param {String} templateName The name of the template used to search for docs tag
+ * @return {String|boolean} the correct comment or false
*/
- var templateLoaded = function(templateName, source) {
- str.get_string('templateselected', 'tool_templatelibrary', templateName).done(function(s) {
- $('[data-region="displaytemplateheader"]').text(s);
- }).fail(notification.exception);
+ var findDocsSection = function(templateSource, templateName) {
// Find the comment section marked with @template component/template.
- var marker = "@template " + templateName;
+ var marker = "@template " + templateName,
+ i = 0,
+ sections = [];
- var sections = source.match(/{{!([\s\S]*?)}}/g);
- var i = 0;
+ sections = templateSource.match(/{{!([\s\S]*?)}}/g);
// If no sections match - show the entire file.
if (sections !== null) {
// Remove {{! and }} from start and end.
var offset = start + marker.length + 1;
section = section.substr(offset, section.length - 2 - offset);
- source = section;
- break;
+ return section;
}
}
}
+ // No matching comment.
+ return false;
+ };
+
+ /**
+ * Handle a template loaded response.
+ *
+ * @param {String} templateName The template name
+ * @param {String} source The template source
+ * @param {String} originalSource The original template source (not theme overridden)
+ */
+ var templateLoaded = function(templateName, source, originalSource) {
+ str.get_string('templateselected', 'tool_templatelibrary', templateName).done(function(s) {
+ $('[data-region="displaytemplateheader"]').text(s);
+ }).fail(notification.exception);
+
+ // Find the comment section marked with @template component/template.
+ var docs = findDocsSection(source, templateName);
+
+ if (docs === false) {
+ // Docs was not in theme template, try original.
+ docs = findDocsSection(originalSource, templateName);
+ }
+
+ // If we found a docs section, limit the template library to showing this section.
+ if (docs) {
+ source = docs;
+ }
$('[data-region="displaytemplatesource"]').text(source);
/**
* Load the a template source from Moodle.
+ *
* @param {String} templateName
*/
var loadTemplate = function(templateName) {
var component = parts.shift();
var name = parts.shift();
- ajax.call([{
+ var promises = ajax.call([{
methodname: 'core_output_load_template',
args:{
component: component,
template: name,
themename: config.theme
- },
- done: function(source) { templateLoaded(templateName, source); },
- fail: notification.exception
+ }
+ }, {
+ methodname: 'tool_templatelibrary_load_canonical_template',
+ args:{
+ component: component,
+ template: name
+ }
}]);
+
+ // When returns a new promise that is resolved when all the passed in promises are resolved.
+ // The arguments to the done become the values of each resolved promise.
+ $.when.apply($, promises)
+ .done( function(source, originalSource) { templateLoaded(templateName, source, originalSource); })
+ .fail(notification.exception);
};
// Add the event listeners.
*/
namespace tool_templatelibrary;
-use core\output\mustache_template_finder;
-use stdClass;
use core_component;
+use core\output\mustache_template_finder;
use coding_exception;
+use moodle_exception;
use required_capability_exception;
+use stdClass;
/**
* API exposed by tool_templatelibrary
return $results;
}
+ /**
+ * Return a mustache template.
+ * Note - this function differs from the function core_output_load_template
+ * because it will never return a theme overridden version of a template.
+ *
+ * @param string $component The component that holds the template.
+ * @param string $template The name of the template.
+ * @return string the template
+ */
+ public static function load_canonical_template($component, $template) {
+ // Get the list of possible template directories.
+ $dirs = mustache_template_finder::get_template_directories_for_component($component);
+ $filename = false;
+
+ foreach ($dirs as $dir) {
+ // Skip theme dirs - we only want the original plugin/core template.
+ if (strpos($dir, "/theme/") === false) {
+ $candidate = $dir . $template . '.mustache';
+ if (file_exists($candidate)) {
+ $filename = $candidate;
+ break;
+ }
+ }
+ }
+ if ($filename === false) {
+ throw new moodle_exception('filenotfound', 'error');
+ }
+
+ $templatestr = file_get_contents($filename);
+ return $templatestr;
+ }
+
+
}
public static function list_templates_returns() {
return new external_multiple_structure(new external_value(PARAM_RAW, 'The template name (format is component/templatename)'));
}
+
+ /**
+ * Returns description of load_canonical_template() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function load_canonical_template_parameters() {
+ return new external_function_parameters(
+ array('component' => new external_value(PARAM_COMPONENT, 'component containing the template'),
+ 'template' => new external_value(PARAM_ALPHANUMEXT, 'name of the template'))
+ );
+ }
+
+ /**
+ * Can this function be called directly from ajax?
+ *
+ * @return boolean
+ * @since Moodle 2.9
+ */
+ public static function load_canonical_template_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Return a mustache template.
+ * Note - this function differs from the function core_output_load_template
+ * because it will never return a theme overridden version of a template.
+ *
+ * @param string $component The component that holds the template.
+ * @param string $template The name of the template.
+ * @return string the template
+ */
+ public static function load_canonical_template($component, $template) {
+ $params = self::validate_parameters(self::load_canonical_template_parameters(),
+ array('component' => $component,
+ 'template' => $template));
+
+ $component = $params['component'];
+ $template = $params['template'];
+
+ return api::load_canonical_template($component, $template);
+ }
+
+ /**
+ * Returns description of load_canonical_template() result value.
+ *
+ * @return external_description
+ */
+ public static function load_canonical_template_returns() {
+ return new external_value(PARAM_RAW, 'template');
+ }
}
'type' => 'read',
'capabilities'=> '',
),
+ 'tool_templatelibrary_load_canonical_template' => array(
+ 'classname' => 'tool_templatelibrary\external',
+ 'methodname' => 'load_canonical_template',
+ 'description' => 'Load a canonical template by name (not the theme overidden one).',
+ 'type' => 'read'
+ ),
+
);
$this->assertEquals($result[0], "tool_templatelibrary/list_templates_page");
}
+ public function test_load_canonical_template() {
+ global $CFG;
+ $originaltheme = $CFG->theme;
+ // Change the theme to 'base' because it overrides these templates.
+ $CFG->theme = 'base';
+
+ $template = external::load_canonical_template('core', 'notification_problem');
+
+ // Only the base template should contain the docs.
+ $this->assertContains('@template core/notification_problem', $template);
+
+ // Restore the original theme.
+ $CFG->theme = $originaltheme;
+ }
}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2015021623; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version = 2015050401; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2014110400; // Requires this Moodle version.
$plugin->component = 'tool_templatelibrary'; // Full name of the plugin (used for diagnostics).
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
-{{!
- Moodle notification template.
-
- The purpose of this template is to render a message notification.
-
- Classes required for JS:
- * none
-
- Data attributes required for JS:
- * none
-
- Context variables required for this template:
- * message A cleaned string (use clean_text()) to display.
-}}
-<div class="notifymessage">{{{message}}}</div>
\ No newline at end of file
+<div class="notifymessage">{{{message}}}</div>
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
-{{!
- Moodle notification template.
-
- The purpose of this template is to render a problem notification.
-
- Classes required for JS:
- * none
-
- Data attributes required for JS:
- * none
-
- Context variables required for this template:
- * message A cleaned string (use clean_text()) to display.
-}}
-<div class="notifyproblem">{{{message}}}</div>
\ No newline at end of file
+<div class="notifyproblem">{{{message}}}</div>
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
-{{!
- Moodle notification template.
-
- The purpose of this template is to render a message notification.
-
- Classes required for JS:
- * none
-
- Data attributes required for JS:
- * none
-
- Context variables required for this template:
- * message A cleaned string (use clean_text()) to display.
-}}
-<div class="redirectmessage">{{{message}}}</div>
\ No newline at end of file
+<div class="redirectmessage">{{{message}}}</div>
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
-{{!
- Moodle notification template.
-
- The purpose of this template is to render a success notification.
-
- Classes required for JS:
- * none
-
- Data attributes required for JS:
- * none
-
- Context variables required for this template:
- * message A cleaned string (use clean_text()) to display.
-}}
-<div class="notifysuccess">{{{message}}}</div>
\ No newline at end of file
+<div class="notifysuccess">{{{message}}}</div>