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