Skip to content

Commit

Permalink
MDL-55831 output: Convert action menu to templates
Browse files Browse the repository at this point in the history
Part of MDL-55071
  • Loading branch information
Frederic Massart authored and danpoltawski committed Sep 23, 2016
1 parent 45fe470 commit f15024c
Show file tree
Hide file tree
Showing 7 changed files with 273 additions and 75 deletions.
152 changes: 151 additions & 1 deletion lib/outputcomponents.php
Original file line number Diff line number Diff line change
Expand Up @@ -3759,7 +3759,7 @@ public function export_for_template(renderer_base $output) {
* @copyright 2013 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class action_menu implements renderable {
class action_menu implements renderable, templatable {

/**
* Top right alignment.
Expand Down Expand Up @@ -4108,6 +4108,98 @@ public function set_nowrap_on_items($value = true) {
$this->attributes['class'] = $class;
}
}

/**
* 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;
$attributesprimary = $this->attributesprimary;
$attributessecondary = $this->attributessecondary;

$data->instance = $this->instance;

$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);

$primary = new stdClass();
$primary->title = '';
$primary->prioritise = $this->prioritise;

$primary->classes = isset($attributesprimary['class']) ? $attributesprimary['class'] : '';
unset($attributesprimary['class']);
$primary->attributes = array_map(function($key, $value) {
return [ 'name' => $key, 'value' => $value ];
}, array_keys($attributesprimary), $attributesprimary);

$actionicon = $this->actionicon;
if (!empty($this->menutrigger)) {
$primary->menutrigger = $this->menutrigger;
} else {
$primary->title = get_string('actions');
$actionicon = new pix_icon('t/edit_menu', '', 'moodle', ['class' => 'iconsmall actionmenu', 'title' => '']);
}

if ($actionicon instanceof pix_icon) {
$primary->icon = $actionicon->export_for_template($output);
$primary->title = !empty($actionicon->attributes['alt']) ? $this->actionicon->attributes['alt'] : '';
} else {
$primary->iconraw = $actionicon ? $output->render($actionicon) : '';
}

$primary->actiontext = $this->actiontext ? (string) $this->actiontext : '';
$primary->items = array_map(function($item) use ($output) {
$data = (object) [];
if ($item instanceof action_menu_link) {
$data->actionmenulink = $item->export_for_template($output);
} else if ($item instanceof action_menu_filler) {
$data->actionmenufiller = $item->export_for_template($output);
} else if ($item instanceof action_link) {
$data->actionlink = $item->export_for_template($output);
} else if ($item instanceof pix_icon) {
$data->pixicon = $item->export_for_template($output);
} else {
$data->rawhtml = ($item instanceof renderable) ? $output->render($item) : $item;
}
return $data;
}, $this->primaryactions);

$secondary = new stdClass();
$secondary->classes = isset($attributessecondary['class']) ? $attributessecondary['class'] : '';
unset($attributessecondary['class']);
$secondary->attributes = array_map(function($key, $value) {
return [ 'name' => $key, 'value' => $value ];
}, array_keys($attributessecondary), $attributessecondary);
$secondary->items = array_map(function($item) use ($output) {
$data = (object) [];
if ($item instanceof action_menu_link) {
$data->actionmenulink = $item->export_for_template($output);
} else if ($item instanceof action_menu_filler) {
$data->actionmenufiller = $item->export_for_template($output);
} else if ($item instanceof action_link) {
$data->actionlink = $item->export_for_template($output);
} else if ($item instanceof pix_icon) {
$data->pixicon = $item->export_for_template($output);
} else {
$data->rawhtml = ($item instanceof renderable) ? $output->render($item) : $item;
}
return $data;
}, $this->secondaryactions);

$data->primary = $primary;
$data->secondary = $secondary;

return $data;
}

}

/**
Expand Down Expand Up @@ -4170,6 +4262,64 @@ public function __construct(moodle_url $url, pix_icon $icon = null, $text, $prim
$this->add_class('menu-action');
$this->attributes['role'] = 'menuitem';
}

/**
* Export for template.
*
* @param renderer_base $output The renderer.
* @return stdClass
*/
public function export_for_template(renderer_base $output) {
static $instance = 1;

$data = parent::export_for_template($output);
$data->instance = $instance++;

// Ignore what the parent did with the attributes, except for ID and class.
$data->attributes = [];
$attributes = $this->attributes;
unset($attributes['id']);
unset($attributes['class']);

// Handle text being a renderable.
$comparetoalt = $this->text;
if ($this->text instanceof renderable) {
$data->text = $this->render($this->text);
$comparetoalt = '';
}
$comparetoalt = (string) $comparetoalt;

$data->showtext = (!$this->icon || $this->primary === false);

$data->icon = null;
if ($this->icon) {
$icon = $this->icon;
if ($this->primary || !$this->actionmenu->will_be_enhanced()) {
$attributes['title'] = $data->text;
}
if (!$this->primary && $this->actionmenu->will_be_enhanced()) {
if ((string) $icon->attributes['alt'] === $comparetoalt) {
$icon->attributes['alt'] = '';
}
if (isset($icon->attributes['title']) && (string) $icon->attributes['title'] === $comparetoalt) {
unset($icon->attributes['title']);
}
}
$data->icon = $icon ? $icon->export_for_template($output) : null;
}

$data->disabled = !empty($attributes['disabled']);
unset($attributes['disabled']);

$data->attributes = array_map(function($key, $value) {
return [
'name' => $key,
'value' => $value
];
}, array_keys($attributes), $attributes);

return $data;
}
}

/**
Expand Down
76 changes: 3 additions & 73 deletions lib/outputrenderers.php
Original file line number Diff line number Diff line change
Expand Up @@ -1310,31 +1310,8 @@ public function block_controls($actions, $blockid = null) {
* @return string HTML
*/
public function render_action_menu(action_menu $menu) {
$menu->initialise_js($this->page);

$output = html_writer::start_tag('div', $menu->attributes);
$output .= html_writer::start_tag('ul', $menu->attributesprimary);
foreach ($menu->get_primary_actions($this) as $action) {
if ($action instanceof renderable) {
$content = $this->render($action);
} else {
$content = $action;
}
$output .= html_writer::tag('li', $content, array('role' => 'presentation'));
}
$output .= html_writer::end_tag('ul');
$output .= html_writer::start_tag('ul', $menu->attributessecondary);
foreach ($menu->get_secondary_actions() as $action) {
if ($action instanceof renderable) {
$content = $this->render($action);
} else {
$content = $action;
}
$output .= html_writer::tag('li', $content, array('role' => 'presentation'));
}
$output .= html_writer::end_tag('ul');
$output .= html_writer::end_tag('div');
return $output;
$context = $menu->export_for_template($this);
return $this->render_from_template('core/action_menu', $context);
}

/**
Expand All @@ -1344,53 +1321,7 @@ public function render_action_menu(action_menu $menu) {
* @return string HTML fragment
*/
protected function render_action_menu_link(action_menu_link $action) {
static $actioncount = 0;
$actioncount++;

$comparetoalt = '';
$text = '';
if (!$action->icon || $action->primary === false) {
$text .= html_writer::start_tag('span', array('class'=>'menu-action-text', 'id' => 'actionmenuaction-'.$actioncount));
if ($action->text instanceof renderable) {
$text .= $this->render($action->text);
} else {
$text .= $action->text;
$comparetoalt = (string)$action->text;
}
$text .= html_writer::end_tag('span');
}

$icon = '';
if ($action->icon) {
$icon = $action->icon;
if ($action->primary || !$action->actionmenu->will_be_enhanced()) {
$action->attributes['title'] = $action->text;
}
if (!$action->primary && $action->actionmenu->will_be_enhanced()) {
if ((string)$icon->attributes['alt'] === $comparetoalt) {
$icon->attributes['alt'] = '';
}
if (isset($icon->attributes['title']) && (string)$icon->attributes['title'] === $comparetoalt) {
unset($icon->attributes['title']);
}
}
$icon = $this->render($icon);
}

// A disabled link is rendered as formatted text.
if (!empty($action->attributes['disabled'])) {
// Do not use div here due to nesting restriction in xhtml strict.
return html_writer::tag('span', $icon.$text, array('class'=>'currentlink', 'role' => 'menuitem'));
}

$attributes = $action->attributes;
unset($action->attributes['disabled']);
$attributes['href'] = $action->url;
if ($text !== '') {
$attributes['aria-labelledby'] = 'actionmenuaction-'.$actioncount;
}

return html_writer::tag('a', $icon.$text, $attributes);
return $this->render_from_template('core/action_menu_link', $action->export_for_template($this));
}

/**
Expand Down Expand Up @@ -3376,7 +3307,6 @@ public function user_menu($user = null, $withlinks = null) {
$divider->primary = false;

$am = new action_menu();
$am->initialise_js($this->page);
$am->set_menu_trigger(
$returnstr
);
Expand Down
49 changes: 49 additions & 0 deletions lib/templates/action_menu.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{{!
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/>.
}}
{{!
Action menu.
}}
<div class="{{classes}}" {{#attributes}}{{name}}="{{value}}"{{/attributes}}>
{{#primary}}

<ul class="{{classes}}" {{#attributes}}{{name}}="{{value}}"{{/attributes}}>

{{#prioritise}}<li role="presentation">{{> core/action_menu_trigger }}</li>{{/prioritise}}<!--
-->{{#items}}<li role="presentation">{{> core/action_menu_item }}</li>{{/items}}<!--
-->{{^prioritise}}<li role="presentation">{{> core/action_menu_trigger }}</li>{{/prioritise}}

</ul>

{{/primary}}

{{#secondary}}
<ul class="{{classes}}" {{#attributes}}{{name}}="{{value}}"{{/attributes}}>
{{#items}}<li role="presentation">{{> core/action_menu_item }}</li>{{/items}}
</ul>
{{/secondary}}

</span>
</div>
{{#js}}
require(['core/yui'], function(Y) {
Y.use('moodle-core-actionmenu', function() {
M.core.actionmenu.init();
});
});
{{/js}}
24 changes: 24 additions & 0 deletions lib/templates/action_menu_item.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{{!
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/>.
}}
{{!
Action menu item.
}}
{{#actionmenulink}}{{> core/action_menu_link }}{{/actionmenulink}}
{{#actionmenufiller}}<span class="filler">&nbsp;</span>{{/actionmenufiller}}
{{#actionlink}}{{> core/action_link }}{{/actionlink}}
{{#pixicon}}{{> core/pix_icon }}{{/pixicon}}
{{#rawhtml}}{{{.}}}{{/rawhtml}}
25 changes: 25 additions & 0 deletions lib/templates/action_menu_link.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{{!
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/>.
}}
{{!
Action menu link.
}}
{{^disabled}}
<a href="{{url}}" class="{{classes}}" {{#attributes}}{{name}}={{#quote}}{{value}}{{/quote}}{{/attributes}} {{#showtext}}aria-labelledby="actionmenuaction-{{instance}}"{{/showtext}}>{{#icon}}{{>core/pix_icon}}{{/icon}}{{#showtext}}<span class="menu-action-text" id="actionmenuaction-{{instance}}">{{{text}}}</span>{{/showtext}}</a>
{{/disabled}}
{{#disabled}}
<span class="currentlink" role="menuitem">{{#icon}}{{>core/pix_icon}}{{/icon}}{{{text}}}</span>
{{/disabled}}
20 changes: 20 additions & 0 deletions lib/templates/action_menu_trigger.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{{!
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/>.
}}
{{!
Action menu trigger.
}}
<a href="#" class="toggle-display {{#menutrigger}}textmenu{{/menutrigger}}" id="action-menu-toggle-{{instance}}" title="{{title}}" role="menuitem">{{{actiontext}}}{{{menutrigger}}}{{#icon}}{{> core/pix_icon}}{{/icon}}{{#rawicon}}{{{.}}}{{/rawicon}}{{#menutrigger}}<b class="caret"></b>{{/menutrigger}}</a>
Loading

0 comments on commit f15024c

Please sign in to comment.