MDL-55463 output: Make single select a templatable
[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;
31 use single_select;
33 defined('MOODLE_INTERNAL') || die;
35 /**
36  * Renderers to align Moodle's HTML with that expected by Bootstrap
37  *
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
41  */
43 class core_renderer extends \core_renderer {
45     /** @var custom_menu_item language The language menu if created */
46     protected $language = null;
48     /**
49      * The standard tags that should be included in the <head> tag
50      * including a meta description for the front page
51      *
52      * @return string HTML fragment.
53      */
54     public function standard_head_html() {
55         global $SITE, $PAGE;
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";
62             }
63         }
65         return $output;
66     }
68     /*
69      * This renders the navbar.
70      * Uses bootstrap compatible html.
71      */
72     public function navbar() {
73         return $this->render_from_template('core/navbar', $this->page->navbar);
74     }
76     /*
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.
80      */
81     public function custom_menu($custommenuitems = '') {
82         global $CFG;
84         if (empty($custommenuitems) && !empty($CFG->custommenuitems)) {
85             $custommenuitems = $CFG->custommenuitems;
86         }
87         $custommenu = new custom_menu($custommenuitems, current_language());
88         return $this->render_custom_menu($custommenu);
89     }
91     /*
92      * This renders the bootstrap top menu.
93      *
94      * This renderer is needed to enable the Bootstrap style navigation.
95      */
96     protected function render_custom_menu(custom_menu $menu) {
97         global $CFG;
99         $langs = get_string_manager()->get_list_of_translations();
100         $haslangmenu = $this->lang_menu() != '';
102         if (!$menu->has_children() && !$haslangmenu) {
103             return '';
104         }
106         if ($haslangmenu) {
107             $strlang = get_string('language');
108             $currentlang = current_language();
109             if (isset($langs[$currentlang])) {
110                 $currentlang = $langs[$currentlang];
111             } else {
112                 $currentlang = $strlang;
113             }
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);
117             }
118         }
120         $content = '';
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);
124         }
126         return $content;
127     }
129     /**
130      * This code renders the navbar button to control the display of the custom menu
131      * on smaller screens.
132      *
133      * Do not display the button if the menu is empty.
134      *
135      * @return string HTML fragment
136      */
137     public function navbar_button() {
138         global $CFG;
140         if (empty($CFG->custommenuitems) && $this->lang_menu() == '') {
141             return '';
142         }
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'
149         ));
150         return $button;
151     }
153     /**
154      * Renders tabtree
155      *
156      * @param tabtree $tabtree
157      * @return string
158      */
159     protected function render_tabtree(tabtree $tabtree) {
160         if (empty($tabtree->subtree)) {
161             return '';
162         }
163         $data = $tabtree->export_for_template($this);
164         return $this->render_from_template('core/tabtree', $data);
165     }
167     /**
168      * Renders tabobject (part of tabtree)
169      *
170      * This function is called from {@link core_renderer::render_tabtree()}
171      * and also it calls itself when printing the $tabobject subtree recursively.
172      *
173      * @param tabobject $tabobject
174      * @return string HTML fragment
175      */
176     protected function render_tabobject(tabobject $tab) {
177         throw new coding_exception('Tab objects should not be directly rendered.');
178     }
180     /**
181      * Prints a nice side block with an optional header.
182      *
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.
186      */
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;
191         }
192         if (!empty($bc->blockinstanceid)) {
193             $bc->attributes['data-instanceid'] = $bc->blockinstanceid;
194         }
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;
200         }
201         if ($bc->dockable) {
202             $bc->attributes['data-dockable'] = 1;
203         }
204         if ($bc->collapsible == block_contents::HIDDEN) {
205             $bc->add_class('hidden');
206         }
207         if (!empty($bc->controls)) {
208             $bc->add_class('block_with_controls');
209         }
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;
216         $context->id = $id;
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);
230         }
232         return $this->render_from_template('core/block', $context);
233     }
235     /**
236      * Returns the CSS classes to apply to the body tag.
237      *
238      * @since Moodle 2.5.1 2.6
239      * @param array $additionalclasses Any additional classes to apply.
240      * @return string
241      */
242     public function body_css_classes(array $additionalclasses = array()) {
243         return $this->page->bodyclasses;
244     }
246     /**
247      * Renders preferences groups.
248      *
249      * @param  preferences_groups $renderable The renderable
250      * @return string The output.
251      */
252     public function render_preferences_groups(preferences_groups $renderable) {
253         return $this->render_from_template('core/preferences_groups', $renderable);
254     }
256     /**
257      * Renders an action menu component.
258      *
259      * @param action_menu $menu
260      * @return string HTML
261      */
262     public function render_action_menu(action_menu $menu) {
263         return $this->render_from_template('core/action_menu', $menu);
264     }
266     /**
267      * Implementation of user image rendering.
268      *
269      * @param help_icon $helpicon A help icon instance
270      * @return string HTML fragment
271      */
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);
275     }
277     /**
278      * Renders a single select.
279      *
280      * @param single_select $select The object.
281      * @return string HTML
282      */
283     protected function render_single_select(single_select $select) {
284         return $this->render_from_template('core/single_select', $select->export_for_template($this));
285     }