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}}