Commit 274d79c9 authored by Damyon Wiese's avatar Damyon Wiese
Browse files

MDL-49650 tool_templatelibrary: New tool for browsing mustache templates

parent bed022de
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This module adds ajax display functions to the template library page.
*
* @module tool_templatelibrary/display
* @package tool_templatelibrary
* @copyright 2015 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates', 'core/config', 'core/str'],
function($, ajax, log, notification, templates, config, str) {
/**
* Handle a template loaded response.
*
* @param {String} templateName The template name
* @param {String} source The template source
*/
var templateLoaded = function(templateName, source) {
str.get_string('templateselected', 'tool_templatelibrary', templateName).done(function(s) {
$('[data-region="displaytemplateheader"]').text(s);
}).fail(notification.exception);
// Remove the GPL from the start of the template.
var sections = source.match(/{{!([\s\S]*?)}}/g);
var i = 0;
// Find the first non-empty comment that is not the GPL.
// If no sections match - show the entire file.
if (sections !== null) {
for (i = 0; i < sections.length; i++) {
var section = sections[i];
if ((section.trim() !== '') && (section.indexOf('GNU General Public License') === -1)) {
// Remove {{! and }} from start and end.
section = section.substr(3, section.length - 5);
source = section;
break;
}
}
}
$('[data-region="displaytemplatesource"]').text(source);
// Now search the text for a json example.
var example = source.match(/Example context \(json\):([\s\S]*)/);
var context = false;
if (example) {
var rawJSON = example[1].trim();
try {
context = $.parseJSON(rawJSON);
} catch (e) {
log.debug('Could not parse json example context for template.');
log.debug(e);
}
}
if (context) {
templates.render(templateName, context).done(function(html, js) {
$('[data-region="displaytemplateexample"]').empty();
$('[data-region="displaytemplateexample"]').append(html);
templates.runTemplateJS(js);
}).fail(notification.exception);
} else {
str.get_string('templatehasnoexample', 'tool_templatelibrary').done(function(s) {
$('[data-region="displaytemplateexample"]').text(s);
}).fail(notification.exception);
}
};
/**
* Load the a template source from Moodle.
* @param {String} templateName
*/
var loadTemplate = function(templateName) {
var parts = templateName.split('/');
var component = parts.shift();
var name = parts.shift();
ajax.call([{
methodname: 'core_output_load_template',
args:{
component: component,
template: name,
themename: config.theme
},
done: function(source) { templateLoaded(templateName, source); },
fail: notification.exception
}]);
};
// Add the event listeners.
$('[data-region="list-templates"]').on('click', '[data-templatename]', function() {
var templatename = $(this).data('templatename');
loadTemplate(templatename);
});
// This module does not expose anything.
return {};
});
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This module adds ajax search functions to the template library page.
*
* @module tool_templatelibrary/search
* @package tool_templatelibrary
* @copyright 2015 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates'],
function($, ajax, log, notification, templates) {
/**
* The ajax call has returned with a new list of templates.
*
* @method reloadListTemplate
* @param String[] templates List of template ids.
*/
var reloadListTemplate = function(templateList) {
templates.render('tool_templatelibrary/search_results', { templates: templateList })
.done(function (result) {
$('[data-region="searchresults"]').replaceWith(result);
}).fail(notification.exception);
};
/**
* Get the current values for the form inputs and refresh the list of matching templates.
*
* @method refreshSearch
*/
var refreshSearch = function() {
var componentStr = $('[data-field="component"]').val();
var searchStr = $('[data-field="search"]').val();
// Trigger the search.
ajax.call([
{ methodname: 'tool_templatelibrary_list_templates',
args: { component: componentStr, search: searchStr },
done: reloadListTemplate,
fail: notification.exception }
]);
};
var throttle = null;
/**
* Call the specified function after a delay. If this function is called again before the function is executed,
* the function will only be executed once.
*
* @method queueRefresh
* @param function callback
* @param int delay The time in milliseconds to delay.
*/
var queueRefresh = function(callback, delay) {
if (throttle !== null) {
window.clearTimeout(throttle);
}
throttle = window.setTimeout(function() {
callback();
throttle = null;
}, delay);
};
var changeHandler = function() {
queueRefresh(refreshSearch, 400);
};
// Add change handlers to refresh the list.
$('[data-region="list-templates"]').on('change', '[data-field="component"]', changeHandler);
$('[data-region="list-templates"]').on('input', '[data-field="search"]', changeHandler);
refreshSearch();
return {};
});
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Class for listing mustache templates.
*
* @package tool_templatelibrary
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_templatelibrary;
use stdClass;
use core_component;
use coding_exception;
use required_capability_exception;
/**
* API exposed by tool_templatelibrary
*
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class api {
/**
* Return a list of details about installed templates.
*
* @param string $component Filter the list to a single component.
* @param string $search Search string to optionally filter the list of templates.
* @return array[string] Where each template is in the form "component/templatename".
*/
public static function list_templates($component = '', $search = '') {
global $CFG;
$templatedirs = array();
$results = array();
if ($component != '') {
// Just look at one component for templates.
$dir = core_component::get_component_directory($component);
if (!$dir) {
return $templatedirs;
}
$templatedirs[$component] = $dir . '/templates';
} else {
// Look at all the templates dirs for all installed plugins.
$dir = $CFG->libdir . '/templates';
if (!empty($dir) && is_dir($dir)) {
$templatedirs['core'] = $dir;
}
$plugintypes = core_component::get_plugin_types();
foreach ($plugintypes as $type => $dir) {
$plugins = core_component::get_plugin_list_with_file($type, 'templates', false);
foreach ($plugins as $plugin => $dir) {
if (!empty($dir) && is_dir($dir)) {
$templatedirs[$type . '_' . $plugin] = $dir;
}
}
}
}
foreach ($templatedirs as $templatecomponent => $dir) {
// List it.
$files = glob($dir . '/*.mustache');
foreach ($files as $file) {
$templatename = basename($file, '.mustache');
if ($search == '' || strpos($templatename, $search) !== false) {
$results[] = $templatecomponent . '/' . $templatename;
}
}
}
return $results;
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This is the external API for this tool.
*
* @package tool_templatelibrary
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_templatelibrary;
require_once("$CFG->libdir/externallib.php");
use external_api;
use external_function_parameters;
use external_value;
use external_format_value;
use external_single_structure;
use external_multiple_structure;
use invalid_parameter_exception;
/**
* This is the external API for this tool.
*
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class external extends external_api {
/**
* Returns description of list_templates() parameters.
*
* @return external_function_parameters
*/
public static function list_templates_parameters() {
$component = new external_value(
PARAM_COMPONENT,
'The component to search',
VALUE_DEFAULT,
''
);
$search = new external_value(
PARAM_RAW,
'The search string',
VALUE_DEFAULT,
''
);
$params = array('component' => $component, 'search' => $search);
return new external_function_parameters($params);
}
/**
* Expose to AJAX
* @return boolean
*/
public static function list_templates_is_allowed_from_ajax() {
return true;
}
/**
* Loads the list of templates.
* @param string $component Limit the search to a component.
* @param string $search The search string.
* @return array[string]
*/
public static function list_templates($component, $search) {
$params = self::validate_parameters(self::list_templates_parameters(),
array(
'component' => $component,
'search' => $search,
));
return api::list_templates($component, $search);
}
/**
* Returns description of list_templates() result value.
*
* @return external_description
*/
public static function list_templates_returns() {
return new external_multiple_structure(new external_value(PARAM_RAW, 'The template name (format is component/templatename)'));
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Class containing data for list_templates page
*
* @package tool_templatelibrary
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_templatelibrary\output;
use renderable;
use templatable;
use renderer_base;
use stdClass;
use core_plugin_manager;
use tool_templatelibrary\api;
/**
* Class containing data for list_templates page
*
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class list_templates_page implements renderable, templatable {
/**
* Export this data so it can be used as the context for a mustache template.
*
* @return stdClass
*/
public function export_for_template(renderer_base $output) {
$data = new stdClass();
$data->allcomponents = array();
$fulltemplatenames = api::list_templates();
$pluginmanager = core_plugin_manager::instance();
$components = array();
foreach ($fulltemplatenames as $templatename) {
list($component, $templatename) = explode('/', $templatename, 2);
$components[$component] = 1;
}
$components = array_keys($components);
foreach ($components as $component) {
$info = new stdClass();
$info->component = $component;
if ($component == 'core') {
$info->name = get_string('core_component', 'tool_templatelibrary');
} else {
$info->name = $pluginmanager->plugin_name($component);
}
$data->allcomponents[] = $info;
}
return $data;
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Renderer class for template library.
*
* @package tool_templatelibrary
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_templatelibrary\output;
defined('MOODLE_INTERNAL') || die;
use plugin_renderer_base;
/**
* Renderer class for template library.
*
* @package tool_templatelibrary
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class renderer extends plugin_renderer_base {
/**
* Defer to template.
*
* @param list_templates_page $page
*
* @return string html for the page
*/
public function render_list_templates_page($page) {
$data = $page->export_for_template($this);
return parent::render_from_template('tool_templatelibrary/list_templates_page', $data);
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Template library webservice definitions.
*
*
* @package tool_templatelibrary
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$functions = array(
'tool_templatelibrary_list_templates' => array(
'classname' => 'tool_templatelibrary\external',
'methodname' => 'list_templates',
'classpath' => '',
'description' => 'List/search templates by component.',
'type' => 'read',
'capabilities'=> '',
),
);
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This page lets users to manage site wide competencies.
*
* @package tool_templatelibrary
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('tooltemplatelibrary');
$component = optional_param('component', '', PARAM_COMPONENT);
$search = optional_param('search', '', PARAM_RAW);
$title = get_string('templates', 'tool_templatelibrary');
$pagetitle = get_string('searchtemplates', 'tool_templatelibrary');
// Set up the page.
$url = new moodle_url("/admin/tool/templatelibrary/index.php", array('component' => $component, 'search' => $search));
$PAGE->set_url($url);
$PAGE->set_title($title);
$PAGE->set_heading($title);
$output = $PAGE->get_renderer('tool_templatelibrary');
echo $output->header();
echo $output->heading($pagetitle);