e302adef7b94b8ca2342720b0585a54d667149a7
[moodle.git] / theme / noname / classes / output / core_renderer.php
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/>.
17 namespace theme_noname\output;
19 use coding_exception;
20 use html_writer;
21 use tabobject;
22 use tabtree;
23 use custom_menu_item;
24 use custom_menu;
25 use block_contents;
26 use stdClass;
27 use moodle_url;
29 defined('MOODLE_INTERNAL') || die;
31 /**
32  * Renderers to align Moodle's HTML with that expected by Bootstrap
33  *
34  * @package    theme_noname
35  * @copyright  2012 Bas Brands, www.basbrands.nl
36  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37  */
39 class core_renderer extends \core_renderer {
41     /** @var custom_menu_item language The language menu if created */
42     protected $language = null;
44     /**
45      * The standard tags that should be included in the <head> tag
46      * including a meta description for the front page
47      *
48      * @return string HTML fragment.
49      */
50     public function standard_head_html() {
51         global $SITE, $PAGE;
53         $output = parent::standard_head_html();
54         if ($PAGE->pagelayout == 'frontpage') {
55             $summary = s(strip_tags(format_text($SITE->summary, FORMAT_HTML)));
56             if (!empty($summary)) {
57                 $output .= "<meta name=\"description\" content=\"$summary\" />\n";
58             }
59         }
61         return $output;
62     }
64     /*
65      * This renders the navbar.
66      * Uses bootstrap compatible html.
67      */
68     public function navbar() {
69         $items = $this->page->navbar->get_items();
70         if (empty($items)) {
71             return '';
72         }
74         $breadcrumbs = array();
75         foreach ($items as $item) {
76             $item->hideicon = true;
77             $breadcrumbs[] = $this->render($item);
78         }
79         $list_items = '<li>'.join(" </li><li>", $breadcrumbs).'</li>';
80         $title = '<span class="accesshide" id="navbar-label">'.get_string('pagepath').'</span>';
81         return $title . '<nav aria-labelledby="navbar-label"><ul class="breadcrumb">' .
82                 $list_items . '</ul></nav>';
83     }
85     /*
86      * Overriding the custom_menu function ensures the custom menu is
87      * always shown, even if no menu items are configured in the global
88      * theme settings page.
89      */
90     public function custom_menu($custommenuitems = '') {
91         global $CFG;
93         if (empty($custommenuitems) && !empty($CFG->custommenuitems)) {
94             $custommenuitems = $CFG->custommenuitems;
95         }
96         $custommenu = new custom_menu($custommenuitems, current_language());
97         return $this->render_custom_menu($custommenu);
98     }
100     /*
101      * This renders the bootstrap top menu.
102      *
103      * This renderer is needed to enable the Bootstrap style navigation.
104      */
105     protected function render_custom_menu(custom_menu $menu) {
106         global $CFG;
108         $langs = get_string_manager()->get_list_of_translations();
109         $haslangmenu = $this->lang_menu() != '';
111         if (!$menu->has_children() && !$haslangmenu) {
112             return '';
113         }
115         if ($haslangmenu) {
116             $strlang = get_string('language');
117             $currentlang = current_language();
118             if (isset($langs[$currentlang])) {
119                 $currentlang = $langs[$currentlang];
120             } else {
121                 $currentlang = $strlang;
122             }
123             $this->language = $menu->add($currentlang, new moodle_url('#'), $strlang, 10000);
124             foreach ($langs as $langtype => $langname) {
125                 $this->language->add($langname, new moodle_url($this->page->url, array('lang' => $langtype)), $langname);
126             }
127         }
129         $content = '';
130         foreach ($menu->get_children() as $item) {
131             $context = $item->export_for_template($this);
132             $content .= $this->render_from_template('core/custom_menu_item', $context);
133         }
135         return $content;
136     }
138     /**
139      * This code renders the navbar button to control the display of the custom menu
140      * on smaller screens.
141      *
142      * Do not display the button if the menu is empty.
143      *
144      * @return string HTML fragment
145      */
146     public function navbar_button() {
147         global $CFG;
149         if (empty($CFG->custommenuitems) && $this->lang_menu() == '') {
150             return '';
151         }
153         $iconbar = html_writer::tag('span', '', array('class' => 'icon-bar'));
154         $button = html_writer::tag('a', $iconbar . "\n" . $iconbar. "\n" . $iconbar, array(
155             'class'       => 'btn btn-navbar',
156             'data-toggle' => 'collapse',
157             'data-target' => '.nav-collapse'
158         ));
159         return $button;
160     }
162     /**
163      * Renders tabtree
164      *
165      * @param tabtree $tabtree
166      * @return string
167      */
168     protected function render_tabtree(tabtree $tabtree) {
169         if (empty($tabtree->subtree)) {
170             return '';
171         }
172         $data = $tabtree->export_for_template($this);
173         return $this->render_from_template('core/tabtree', $data);
174     }
176     /**
177      * Renders tabobject (part of tabtree)
178      *
179      * This function is called from {@link core_renderer::render_tabtree()}
180      * and also it calls itself when printing the $tabobject subtree recursively.
181      *
182      * @param tabobject $tabobject
183      * @return string HTML fragment
184      */
185     protected function render_tabobject(tabobject $tab) {
186         throw new coding_exception('Tab objects should not be directly rendered.');
187     }
189     /**
190      * Prints a nice side block with an optional header.
191      *
192      * @param block_contents $bc HTML for the content
193      * @param string $region the region the block is appearing in.
194      * @return string the HTML to be output.
195      */
196     public function block(block_contents $bc, $region) {
197         $bc = clone($bc); // Avoid messing up the object passed in.
198         if (empty($bc->blockinstanceid) || !strip_tags($bc->title)) {
199             $bc->collapsible = block_contents::NOT_HIDEABLE;
200         }
201         if (!empty($bc->blockinstanceid)) {
202             $bc->attributes['data-instanceid'] = $bc->blockinstanceid;
203         }
204         $skiptitle = strip_tags($bc->title);
205         if ($bc->blockinstanceid && !empty($skiptitle)) {
206             $bc->attributes['aria-labelledby'] = 'instance-'.$bc->blockinstanceid.'-header';
207         } else if (!empty($bc->arialabel)) {
208             $bc->attributes['aria-label'] = $bc->arialabel;
209         }
210         if ($bc->dockable) {
211             $bc->attributes['data-dockable'] = 1;
212         }
213         if ($bc->collapsible == block_contents::HIDDEN) {
214             $bc->add_class('hidden');
215         }
216         if (!empty($bc->controls)) {
217             $bc->add_class('block_with_controls');
218         }
220         $id = !empty($bc->attributes['id']) ? $bc->attributes['id'] : uniqid('block-');
221         $context = new stdClass();
222         $context->skipid = $bc->skipid;
223         $context->blockinstanceid = $bc->blockinstanceid;
224         $context->dockable = $bc->dockable;
225         $context->id = $id;
226         $context->hidden = $bc->collapsible == block_contents::HIDDEN;
227         $context->skiptitle = strip_tags($bc->title);
228         $context->showskiplink = !empty($context->skiptitle);
229         $context->arialabel = $bc->arialabel;
230         $context->ariarole = !empty($bc->attributes['role']) ? $bc->attributes['role'] : 'complementary';
231         $context->type = $bc->attributes['data-block'];
232         $context->title = $bc->title;
233         $context->content = $bc->content;
234         $context->annotation = $bc->annotation;
235         $context->footer = $bc->footer;
236         $context->hascontrols = !empty($bc->controls);
237         if ($context->hascontrols) {
238             $context->controls = $this->block_controls($bc->controls, $id);
239         }
241         return $this->render_from_template('core/block', $context);
242     }
244     /**
245      * Returns the CSS classes to apply to the body tag.
246      *
247      * @since Moodle 2.5.1 2.6
248      * @param array $additionalclasses Any additional classes to apply.
249      * @return string
250      */
251     public function body_css_classes(array $additionalclasses = array()) {
252         return $this->page->bodyclasses;
253     }