diff --git a/lib/outputactions.php b/lib/outputactions.php index 38c6fdb5c50..cf0d70d0a6b 100644 --- a/lib/outputactions.php +++ b/lib/outputactions.php @@ -37,7 +37,7 @@ defined('MOODLE_INTERNAL') || die(); * @package core * @category output */ -class component_action { +class component_action implements templatable { /** * @var string $event The DOM event that will trigger this action when caught @@ -75,6 +75,21 @@ class component_action { } } } + + /** + * Export for template. + * + * @param renderer_base $output The renderer. + * @return stdClass + */ + public function export_for_template(renderer_base $output) { + $args = !empty($this->jsfunctionargs) ? json_encode($this->jsfunctionargs) : false; + return (object) [ + 'event' => $this->event, + 'jsfunction' => $this->jsfunction, + 'jsfunctionargs' => $args, + ]; + } } diff --git a/lib/outputcomponents.php b/lib/outputcomponents.php index 92f0bf66cfe..88e34860cf4 100644 --- a/lib/outputcomponents.php +++ b/lib/outputcomponents.php @@ -755,14 +755,9 @@ class single_button implements renderable { // Button actions. $actions = $this->actions; - $data->actions = array_map(function($key) use ($actions) { - $args = !empty($actions[$key]->jsfunctionargs) ? json_encode($actions[$key]->jsfunctionargs) : false; - return [ - 'event' => $actions[$key]->event, - 'jsfunction' => $actions[$key]->jsfunction, - 'jsfunctionargs' => $args, - ]; - }, array_keys($actions)); + $data->actions = array_map(function($action) use ($output) { + return $action->export_for_template($output); + }, $actions); $data->hasactions = !empty($data->actions); return $data; @@ -1363,6 +1358,46 @@ class action_link implements renderable { } return $OUTPUT->render($this->icon); } + + /** + * Export for template. + * + * @param renderer_base $output The renderer. + * @return stdClass + */ + public function export_for_template(renderer_base $output) { + $data = new stdClass(); + $attributes = $this->attributes; + + if (empty($attributes['id'])) { + $attributes['id'] = html_writer::random_id('action_link'); + } + $data->id = $attributes['id']; + unset($attributes['id']); + + $data->disabled = !empty($attributes['disabled']); + unset($attributes['disabled']); + + $data->text = $this->text instanceof renderable ? $output->render($this->text) : (string) $this->text; + $data->url = $this->url ? $this->url->out(false) : ''; + $data->icon = $this->icon ? $this->icon->export_for_template($output) : null; + $data->classes = isset($attributes['class']) ? $attributes['class'] : ''; + unset($attributes['class']); + + $data->attributes = array_map(function($key, $value) { + return [ + 'name' => $key, + 'value' => $value + ]; + }, array_keys($attributes), $attributes); + + $data->actions = array_map(function($action) use ($output) { + return $action->export_for_template($output); + }, !empty($this->actions) ? $this->actions : []); + $data->hasactions = !empty($this->actions); + + return $data; + } } /** diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php index 280e8004dc3..e4c8392f3ac 100644 --- a/lib/outputrenderers.php +++ b/lib/outputrenderers.php @@ -1697,45 +1697,9 @@ class core_renderer extends renderer_base { * @return string HTML fragment */ protected function render_action_link(action_link $link) { - global $CFG; - - $text = ''; - if ($link->icon) { - $text .= $this->render($link->icon); - } - - if ($link->text instanceof renderable) { - $text .= $this->render($link->text); - } else { - $text .= $link->text; - } - - // A disabled link is rendered as formatted text - if (!empty($link->attributes['disabled'])) { - // do not use div here due to nesting restriction in xhtml strict - return html_writer::tag('span', $text, array('class'=>'currentlink')); - } - - $attributes = $link->attributes; - unset($link->attributes['disabled']); - $attributes['href'] = $link->url; - - if ($link->actions) { - if (empty($attributes['id'])) { - $id = html_writer::random_id('action_link'); - $attributes['id'] = $id; - } else { - $id = $attributes['id']; - } - foreach ($link->actions as $action) { - $this->add_action_handler($action, $id); - } - } - - return html_writer::tag('a', $text, $attributes); + return $this->render_from_template('core/action_link', $link->export_for_template($this)); } - /** * Renders an action_icon. * diff --git a/lib/templates/action_link.mustache b/lib/templates/action_link.mustache new file mode 100644 index 00000000000..c3a3bb5f6d9 --- /dev/null +++ b/lib/templates/action_link.mustache @@ -0,0 +1,28 @@ +{{! + 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 . +}} +{{! + Action link. +}} +{{^disabled}} + {{#icon}}{{>core/pix_icon}}{{/icon}}{{{text}}} + {{#hasactions}} + {{> core/actions }} + {{/hasactions}} +{{/disabled}} +{{#disabled}} + {{#icon}}{{>core/pix_icon}}{{/icon}}{{{text}}} +{{/disabled}} diff --git a/lib/templates/actions.mustache b/lib/templates/actions.mustache new file mode 100644 index 00000000000..3d76246d83c --- /dev/null +++ b/lib/templates/actions.mustache @@ -0,0 +1,26 @@ +{{! + 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 . +}} +{{! + Actions. +}} +{{#js}} + require(['core/yui'], function(Y) { + {{#actions}} + Y.on('{{event}}', {{{jsfunction}}}, '#{{id}}', null{{#jsfunctionargs}}, {{{jsfunctionargs}}}{{/jsfunctionargs}}); + {{/actions}} + }); +{{/js}}