2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 namespace theme_noname\output;
28 use preferences_groups;
33 defined('MOODLE_INTERNAL') || die;
36 * Renderers to align Moodle's HTML with that expected by Bootstrap
38 * @package theme_noname
39 * @copyright 2012 Bas Brands, www.basbrands.nl
40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
43 class core_renderer extends \core_renderer {
45 /** @var custom_menu_item language The language menu if created */
46 protected $language = null;
49 * The standard tags that should be included in the <head> tag
50 * including a meta description for the front page
52 * @return string HTML fragment.
54 public function standard_head_html() {
57 $output = parent::standard_head_html();
58 if ($PAGE->pagelayout == 'frontpage') {
59 $summary = s(strip_tags(format_text($SITE->summary, FORMAT_HTML)));
60 if (!empty($summary)) {
61 $output .= "<meta name=\"description\" content=\"$summary\" />\n";
69 * This renders the navbar.
70 * Uses bootstrap compatible html.
72 public function navbar() {
73 return $this->render_from_template('core/navbar', $this->page->navbar);
77 * Overriding the custom_menu function ensures the custom menu is
78 * always shown, even if no menu items are configured in the global
79 * theme settings page.
81 public function custom_menu($custommenuitems = '') {
84 if (empty($custommenuitems) && !empty($CFG->custommenuitems)) {
85 $custommenuitems = $CFG->custommenuitems;
87 $custommenu = new custom_menu($custommenuitems, current_language());
88 return $this->render_custom_menu($custommenu);
92 * This renders the bootstrap top menu.
94 * This renderer is needed to enable the Bootstrap style navigation.
96 protected function render_custom_menu(custom_menu $menu) {
99 $langs = get_string_manager()->get_list_of_translations();
100 $haslangmenu = $this->lang_menu() != '';
102 if (!$menu->has_children() && !$haslangmenu) {
107 $strlang = get_string('language');
108 $currentlang = current_language();
109 if (isset($langs[$currentlang])) {
110 $currentlang = $langs[$currentlang];
112 $currentlang = $strlang;
114 $this->language = $menu->add($currentlang, new moodle_url('#'), $strlang, 10000);
115 foreach ($langs as $langtype => $langname) {
116 $this->language->add($langname, new moodle_url($this->page->url, array('lang' => $langtype)), $langname);
121 foreach ($menu->get_children() as $item) {
122 $context = $item->export_for_template($this);
123 $content .= $this->render_from_template('core/custom_menu_item', $context);
130 * This code renders the navbar button to control the display of the custom menu
131 * on smaller screens.
133 * Do not display the button if the menu is empty.
135 * @return string HTML fragment
137 public function navbar_button() {
140 if (empty($CFG->custommenuitems) && $this->lang_menu() == '') {
144 $iconbar = html_writer::tag('span', '', array('class' => 'icon-bar'));
145 $button = html_writer::tag('a', $iconbar . "\n" . $iconbar. "\n" . $iconbar, array(
146 'class' => 'btn btn-navbar',
147 'data-toggle' => 'collapse',
148 'data-target' => '.nav-collapse'
156 * @param tabtree $tabtree
159 protected function render_tabtree(tabtree $tabtree) {
160 if (empty($tabtree->subtree)) {
163 $data = $tabtree->export_for_template($this);
164 return $this->render_from_template('core/tabtree', $data);
168 * Renders tabobject (part of tabtree)
170 * This function is called from {@link core_renderer::render_tabtree()}
171 * and also it calls itself when printing the $tabobject subtree recursively.
173 * @param tabobject $tabobject
174 * @return string HTML fragment
176 protected function render_tabobject(tabobject $tab) {
177 throw new coding_exception('Tab objects should not be directly rendered.');
181 * Prints a nice side block with an optional header.
183 * @param block_contents $bc HTML for the content
184 * @param string $region the region the block is appearing in.
185 * @return string the HTML to be output.
187 public function block(block_contents $bc, $region) {
188 $bc = clone($bc); // Avoid messing up the object passed in.
189 if (empty($bc->blockinstanceid) || !strip_tags($bc->title)) {
190 $bc->collapsible = block_contents::NOT_HIDEABLE;
192 if (!empty($bc->blockinstanceid)) {
193 $bc->attributes['data-instanceid'] = $bc->blockinstanceid;
195 $skiptitle = strip_tags($bc->title);
196 if ($bc->blockinstanceid && !empty($skiptitle)) {
197 $bc->attributes['aria-labelledby'] = 'instance-'.$bc->blockinstanceid.'-header';
198 } else if (!empty($bc->arialabel)) {
199 $bc->attributes['aria-label'] = $bc->arialabel;
202 $bc->attributes['data-dockable'] = 1;
204 if ($bc->collapsible == block_contents::HIDDEN) {
205 $bc->add_class('hidden');
207 if (!empty($bc->controls)) {
208 $bc->add_class('block_with_controls');
211 $id = !empty($bc->attributes['id']) ? $bc->attributes['id'] : uniqid('block-');
212 $context = new stdClass();
213 $context->skipid = $bc->skipid;
214 $context->blockinstanceid = $bc->blockinstanceid;
215 $context->dockable = $bc->dockable;
217 $context->hidden = $bc->collapsible == block_contents::HIDDEN;
218 $context->skiptitle = strip_tags($bc->title);
219 $context->showskiplink = !empty($context->skiptitle);
220 $context->arialabel = $bc->arialabel;
221 $context->ariarole = !empty($bc->attributes['role']) ? $bc->attributes['role'] : 'complementary';
222 $context->type = $bc->attributes['data-block'];
223 $context->title = $bc->title;
224 $context->content = $bc->content;
225 $context->annotation = $bc->annotation;
226 $context->footer = $bc->footer;
227 $context->hascontrols = !empty($bc->controls);
228 if ($context->hascontrols) {
229 $context->controls = $this->block_controls($bc->controls, $id);
232 return $this->render_from_template('core/block', $context);
236 * Returns the CSS classes to apply to the body tag.
238 * @since Moodle 2.5.1 2.6
239 * @param array $additionalclasses Any additional classes to apply.
242 public function body_css_classes(array $additionalclasses = array()) {
243 return $this->page->bodyclasses;
247 * Renders preferences groups.
249 * @param preferences_groups $renderable The renderable
250 * @return string The output.
252 public function render_preferences_groups(preferences_groups $renderable) {
253 return $this->render_from_template('core/preferences_groups', $renderable);
257 * Renders an action menu component.
259 * @param action_menu $menu
260 * @return string HTML
262 public function render_action_menu(action_menu $menu) {
263 return $this->render_from_template('core/action_menu', $menu);
267 * Implementation of user image rendering.
269 * @param help_icon $helpicon A help icon instance
270 * @return string HTML fragment
272 protected function render_help_icon(help_icon $helpicon) {
273 $context = $helpicon->export_for_template($this);
274 return $this->render_from_template('core/help_icon', $context);
278 * Renders a single select.
280 * @param single_select $select The object.
281 * @return string HTML
283 protected function render_single_select(single_select $select) {
284 return $this->render_from_template('core/single_select', $select->export_for_template($this));