MDL-55805 theme_noname: Adding padding to all boxes
[moodle.git] / theme / noname / classes / output / core_renderer.php
CommitLineData
536f0460
DW
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
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.
8//
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.
13//
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/>.
16
17namespace theme_noname\output;
18
da4d9eb7 19use coding_exception;
536f0460
DW
20use html_writer;
21use tabobject;
22use tabtree;
23use custom_menu_item;
24use custom_menu;
d7fbf722
DW
25use block_contents;
26use stdClass;
f130c411 27use moodle_url;
3f0544b8
DW
28use preferences_groups;
29use action_menu;
b7e95263 30use help_icon;
d7c65752 31use single_button;
bf7f35e9 32use single_select;
b0da86e0 33use paging_bar;
f1b34660 34use url_select;
b71c82ad 35use context_course;
536f0460
DW
36
37defined('MOODLE_INTERNAL') || die;
38
39/**
40 * Renderers to align Moodle's HTML with that expected by Bootstrap
41 *
42 * @package theme_noname
43 * @copyright 2012 Bas Brands, www.basbrands.nl
44 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
45 */
46
47class core_renderer extends \core_renderer {
48
49 /** @var custom_menu_item language The language menu if created */
50 protected $language = null;
51
7fcfc073
FM
52 /**
53 * Outputs the opening section of a box.
54 *
55 * @param string $classes A space-separated list of CSS classes
56 * @param string $id An optional ID
57 * @param array $attributes An array of other attributes to give the box.
58 * @return string the HTML to output.
59 */
60 public function box_start($classes = 'generalbox', $id = null, $attributes = array()) {
61 return parent::box_start($classes . ' p-a-1', $id, $attributes);
62 }
63
536f0460
DW
64 /**
65 * The standard tags that should be included in the <head> tag
66 * including a meta description for the front page
67 *
68 * @return string HTML fragment.
69 */
70 public function standard_head_html() {
71 global $SITE, $PAGE;
72
73 $output = parent::standard_head_html();
74 if ($PAGE->pagelayout == 'frontpage') {
75 $summary = s(strip_tags(format_text($SITE->summary, FORMAT_HTML)));
76 if (!empty($summary)) {
77 $output .= "<meta name=\"description\" content=\"$summary\" />\n";
78 }
79 }
80
81 return $output;
82 }
83
84 /*
85 * This renders the navbar.
86 * Uses bootstrap compatible html.
87 */
88 public function navbar() {
13d07a01 89 return $this->render_from_template('core/navbar', $this->page->navbar);
536f0460
DW
90 }
91
b71c82ad
FM
92 /**
93 * Override to inject the logo.
94 *
95 * @param array $headerinfo The header info.
96 * @param int $headinglevel What level the 'h' tag will be.
97 * @return string HTML for the header bar.
98 */
99 public function context_header($headerinfo = null, $headinglevel = 1) {
100 global $SITE;
101
102 if ($this->should_display_main_logo($headinglevel)) {
103 $sitename = format_string($SITE->fullname, true, array('context' => context_course::instance(SITEID)));
104 return html_writer::div(html_writer::empty_tag('img', [
105 'src' => $this->get_logo_url(null, 75), 'alt' => $sitename]), 'logo');
106 }
107
108 return parent::context_header($headerinfo, $headinglevel);
109 }
110
111 /**
112 * Get the compact logo URL.
113 *
114 * @return string
115 */
116 public function get_compact_logo_url($maxwidth = 100, $maxheight = 100) {
117 return parent::get_compact_logo_url(null, 43);
118 }
119
120 /**
121 * Whether we should display the main logo.
122 *
123 * @return bool
124 */
125 public function should_display_main_logo($headinglevel = 1) {
126 global $PAGE;
127
128 // Only render the logo if we're on the front page or login page and the we have a logo.
129 $logo = $this->get_logo_url();
130 if ($headinglevel == 1 && !empty($logo)) {
131 if ($PAGE->pagelayout == 'frontpage' || $PAGE->pagelayout == 'login') {
132 return true;
133 }
134 }
135
136 return false;
137 }
138 /**
139 * Whether we should display the logo in the navbar.
140 *
141 * We will when there are no main logos, and we have compact logo.
142 *
143 * @return bool
144 */
145 public function should_display_navbar_logo() {
146 $logo = $this->get_compact_logo_url();
147 return !empty($logo) && !$this->should_display_main_logo();
148 }
149
536f0460
DW
150 /*
151 * Overriding the custom_menu function ensures the custom menu is
152 * always shown, even if no menu items are configured in the global
153 * theme settings page.
154 */
155 public function custom_menu($custommenuitems = '') {
156 global $CFG;
157
158 if (empty($custommenuitems) && !empty($CFG->custommenuitems)) {
159 $custommenuitems = $CFG->custommenuitems;
160 }
161 $custommenu = new custom_menu($custommenuitems, current_language());
162 return $this->render_custom_menu($custommenu);
163 }
164
165 /*
166 * This renders the bootstrap top menu.
167 *
168 * This renderer is needed to enable the Bootstrap style navigation.
169 */
170 protected function render_custom_menu(custom_menu $menu) {
171 global $CFG;
172
173 $langs = get_string_manager()->get_list_of_translations();
174 $haslangmenu = $this->lang_menu() != '';
175
176 if (!$menu->has_children() && !$haslangmenu) {
177 return '';
178 }
179
180 if ($haslangmenu) {
f130c411 181 $strlang = get_string('language');
536f0460
DW
182 $currentlang = current_language();
183 if (isset($langs[$currentlang])) {
184 $currentlang = $langs[$currentlang];
185 } else {
186 $currentlang = $strlang;
187 }
188 $this->language = $menu->add($currentlang, new moodle_url('#'), $strlang, 10000);
189 foreach ($langs as $langtype => $langname) {
190 $this->language->add($langname, new moodle_url($this->page->url, array('lang' => $langtype)), $langname);
191 }
192 }
193
f130c411 194 $content = '';
536f0460 195 foreach ($menu->get_children() as $item) {
f130c411
DW
196 $context = $item->export_for_template($this);
197 $content .= $this->render_from_template('core/custom_menu_item', $context);
536f0460
DW
198 }
199
536f0460
DW
200 return $content;
201 }
202
203 /**
204 * This code renders the navbar button to control the display of the custom menu
205 * on smaller screens.
206 *
207 * Do not display the button if the menu is empty.
208 *
209 * @return string HTML fragment
210 */
211 public function navbar_button() {
212 global $CFG;
213
214 if (empty($CFG->custommenuitems) && $this->lang_menu() == '') {
215 return '';
216 }
217
218 $iconbar = html_writer::tag('span', '', array('class' => 'icon-bar'));
219 $button = html_writer::tag('a', $iconbar . "\n" . $iconbar. "\n" . $iconbar, array(
220 'class' => 'btn btn-navbar',
221 'data-toggle' => 'collapse',
222 'data-target' => '.nav-collapse'
223 ));
224 return $button;
225 }
226
227 /**
228 * Renders tabtree
229 *
230 * @param tabtree $tabtree
231 * @return string
232 */
233 protected function render_tabtree(tabtree $tabtree) {
234 if (empty($tabtree->subtree)) {
235 return '';
236 }
da4d9eb7
FM
237 $data = $tabtree->export_for_template($this);
238 return $this->render_from_template('core/tabtree', $data);
536f0460
DW
239 }
240
241 /**
242 * Renders tabobject (part of tabtree)
243 *
244 * This function is called from {@link core_renderer::render_tabtree()}
245 * and also it calls itself when printing the $tabobject subtree recursively.
246 *
247 * @param tabobject $tabobject
248 * @return string HTML fragment
249 */
250 protected function render_tabobject(tabobject $tab) {
da4d9eb7 251 throw new coding_exception('Tab objects should not be directly rendered.');
536f0460 252 }
d7fbf722
DW
253
254 /**
255 * Prints a nice side block with an optional header.
256 *
257 * @param block_contents $bc HTML for the content
258 * @param string $region the region the block is appearing in.
259 * @return string the HTML to be output.
260 */
261 public function block(block_contents $bc, $region) {
262 $bc = clone($bc); // Avoid messing up the object passed in.
263 if (empty($bc->blockinstanceid) || !strip_tags($bc->title)) {
264 $bc->collapsible = block_contents::NOT_HIDEABLE;
265 }
266 if (!empty($bc->blockinstanceid)) {
267 $bc->attributes['data-instanceid'] = $bc->blockinstanceid;
268 }
269 $skiptitle = strip_tags($bc->title);
270 if ($bc->blockinstanceid && !empty($skiptitle)) {
271 $bc->attributes['aria-labelledby'] = 'instance-'.$bc->blockinstanceid.'-header';
272 } else if (!empty($bc->arialabel)) {
273 $bc->attributes['aria-label'] = $bc->arialabel;
274 }
275 if ($bc->dockable) {
276 $bc->attributes['data-dockable'] = 1;
277 }
278 if ($bc->collapsible == block_contents::HIDDEN) {
279 $bc->add_class('hidden');
280 }
281 if (!empty($bc->controls)) {
282 $bc->add_class('block_with_controls');
283 }
284
285 $id = !empty($bc->attributes['id']) ? $bc->attributes['id'] : uniqid('block-');
286 $context = new stdClass();
287 $context->skipid = $bc->skipid;
288 $context->blockinstanceid = $bc->blockinstanceid;
289 $context->dockable = $bc->dockable;
290 $context->id = $id;
291 $context->hidden = $bc->collapsible == block_contents::HIDDEN;
292 $context->skiptitle = strip_tags($bc->title);
293 $context->showskiplink = !empty($context->skiptitle);
294 $context->arialabel = $bc->arialabel;
295 $context->ariarole = !empty($bc->attributes['role']) ? $bc->attributes['role'] : 'complementary';
296 $context->type = $bc->attributes['data-block'];
297 $context->title = $bc->title;
298 $context->content = $bc->content;
299 $context->annotation = $bc->annotation;
300 $context->footer = $bc->footer;
301 $context->hascontrols = !empty($bc->controls);
302 if ($context->hascontrols) {
303 $context->controls = $this->block_controls($bc->controls, $id);
304 }
305
306 return $this->render_from_template('core/block', $context);
307 }
308
309 /**
310 * Returns the CSS classes to apply to the body tag.
311 *
312 * @since Moodle 2.5.1 2.6
313 * @param array $additionalclasses Any additional classes to apply.
314 * @return string
315 */
316 public function body_css_classes(array $additionalclasses = array()) {
317 return $this->page->bodyclasses;
318 }
3f0544b8
DW
319
320 /**
321 * Renders preferences groups.
322 *
323 * @param preferences_groups $renderable The renderable
324 * @return string The output.
325 */
326 public function render_preferences_groups(preferences_groups $renderable) {
327 return $this->render_from_template('core/preferences_groups', $renderable);
328 }
329
3f0544b8
DW
330 /**
331 * Renders an action menu component.
332 *
333 * @param action_menu $menu
334 * @return string HTML
335 */
336 public function render_action_menu(action_menu $menu) {
337 return $this->render_from_template('core/action_menu', $menu);
338 }
ac4a389e 339
b7e95263
DW
340 /**
341 * Implementation of user image rendering.
342 *
343 * @param help_icon $helpicon A help icon instance
344 * @return string HTML fragment
345 */
346 protected function render_help_icon(help_icon $helpicon) {
347 $context = $helpicon->export_for_template($this);
348 return $this->render_from_template('core/help_icon', $context);
349 }
bf7f35e9 350
d7c65752
FM
351 /**
352 * Renders a single button widget.
353 *
354 * This will return HTML to display a form containing a single button.
355 *
356 * @param single_button $button
357 * @return string HTML fragment
358 */
359 protected function render_single_button(single_button $button) {
360 return $this->render_from_template('core/single_button', $button->export_for_template($this));
361 }
362
bf7f35e9
FM
363 /**
364 * Renders a single select.
365 *
366 * @param single_select $select The object.
367 * @return string HTML
368 */
369 protected function render_single_select(single_select $select) {
370 return $this->render_from_template('core/single_select', $select->export_for_template($this));
371 }
372
b0da86e0
FM
373 /**
374 * Renders a paging bar.
375 *
376 * @param paging_bar $pagingbar The object.
377 * @return string HTML
378 */
379 protected function render_paging_bar(paging_bar $pagingbar) {
8a47abcd
DW
380 // Any more than 10 is not usable and causes wierd wrapping of the pagination in this theme.
381 $pagingbar->maxdisplay = 10;
b0da86e0
FM
382 return $this->render_from_template('core/paging_bar', $pagingbar->export_for_template($this));
383 }
384
f1b34660
FM
385 /**
386 * Renders a url select.
387 *
388 * @param url_select $select The object.
389 * @return string HTML
390 */
391 protected function render_url_select(url_select $select) {
392 return $this->render_from_template('core/url_select', $select->export_for_template($this));
393 }
536f0460 394}