7cd8268e3a914648096532665ed8945ef82ef4a4
[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 html_writer;
20 use tabobject;
21 use tabtree;
22 use custom_menu_item;
23 use custom_menu;
25 defined('MOODLE_INTERNAL') || die;
27 /**
28  * Renderers to align Moodle's HTML with that expected by Bootstrap
29  *
30  * @package    theme_noname
31  * @copyright  2012 Bas Brands, www.basbrands.nl
32  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33  */
35 class core_renderer extends \core_renderer {
37     /** @var custom_menu_item language The language menu if created */
38     protected $language = null;
40     /**
41      * The standard tags that should be included in the <head> tag
42      * including a meta description for the front page
43      *
44      * @return string HTML fragment.
45      */
46     public function standard_head_html() {
47         global $SITE, $PAGE;
49         $output = parent::standard_head_html();
50         if ($PAGE->pagelayout == 'frontpage') {
51             $summary = s(strip_tags(format_text($SITE->summary, FORMAT_HTML)));
52             if (!empty($summary)) {
53                 $output .= "<meta name=\"description\" content=\"$summary\" />\n";
54             }
55         }
57         return $output;
58     }
60     /*
61      * This renders the navbar.
62      * Uses bootstrap compatible html.
63      */
64     public function navbar() {
65         $items = $this->page->navbar->get_items();
66         if (empty($items)) {
67             return '';
68         }
70         $breadcrumbs = array();
71         foreach ($items as $item) {
72             $item->hideicon = true;
73             $breadcrumbs[] = $this->render($item);
74         }
75         $list_items = '<li>'.join(" </li><li>", $breadcrumbs).'</li>';
76         $title = '<span class="accesshide" id="navbar-label">'.get_string('pagepath').'</span>';
77         return $title . '<nav aria-labelledby="navbar-label"><ul class="breadcrumb">' .
78                 $list_items . '</ul></nav>';
79     }
81     /*
82      * Overriding the custom_menu function ensures the custom menu is
83      * always shown, even if no menu items are configured in the global
84      * theme settings page.
85      */
86     public function custom_menu($custommenuitems = '') {
87         global $CFG;
89         if (empty($custommenuitems) && !empty($CFG->custommenuitems)) {
90             $custommenuitems = $CFG->custommenuitems;
91         }
92         $custommenu = new custom_menu($custommenuitems, current_language());
93         return $this->render_custom_menu($custommenu);
94     }
96     /*
97      * This renders the bootstrap top menu.
98      *
99      * This renderer is needed to enable the Bootstrap style navigation.
100      */
101     protected function render_custom_menu(custom_menu $menu) {
102         global $CFG;
104         $langs = get_string_manager()->get_list_of_translations();
105         $haslangmenu = $this->lang_menu() != '';
107         if (!$menu->has_children() && !$haslangmenu) {
108             return '';
109         }
111         if ($haslangmenu) {
112             $strlang =  get_string('language');
113             $currentlang = current_language();
114             if (isset($langs[$currentlang])) {
115                 $currentlang = $langs[$currentlang];
116             } else {
117                 $currentlang = $strlang;
118             }
119             $this->language = $menu->add($currentlang, new moodle_url('#'), $strlang, 10000);
120             foreach ($langs as $langtype => $langname) {
121                 $this->language->add($langname, new moodle_url($this->page->url, array('lang' => $langtype)), $langname);
122             }
123         }
125         $content = '<ul class="nav">';
126         foreach ($menu->get_children() as $item) {
127             $content .= $this->render_custom_menu_item($item, 1);
128         }
130         return $content.'</ul>';
131     }
133     /*
134      * This code renders the custom menu items for the
135      * bootstrap dropdown menu.
136      */
137     protected function render_custom_menu_item(custom_menu_item $menunode, $level = 0 ) {
138         static $submenucount = 0;
140         $content = '';
141         if ($menunode->has_children()) {
143             if ($level == 1) {
144                 $class = 'dropdown';
145             } else {
146                 $class = 'dropdown-submenu';
147             }
149             if ($menunode === $this->language) {
150                 $class .= ' langmenu';
151             }
152             $content = html_writer::start_tag('li', array('class' => $class));
153             // If the child has menus render it as a sub menu.
154             $submenucount++;
155             if ($menunode->get_url() !== null) {
156                 $url = $menunode->get_url();
157             } else {
158                 $url = '#cm_submenu_'.$submenucount;
159             }
160             $content .= html_writer::start_tag('a', array('href'=>$url, 'class'=>'dropdown-toggle', 'data-toggle'=>'dropdown', 'title'=>$menunode->get_title()));
161             $content .= $menunode->get_text();
162             if ($level == 1) {
163                 $content .= '<b class="caret"></b>';
164             }
165             $content .= '</a>';
166             $content .= '<ul class="dropdown-menu">';
167             foreach ($menunode->get_children() as $menunode) {
168                 $content .= $this->render_custom_menu_item($menunode, 0);
169             }
170             $content .= '</ul>';
171         } else {
172             // The node doesn't have children so produce a final menuitem.
173             // Also, if the node's text matches '####', add a class so we can treat it as a divider.
174             if (preg_match("/^#+$/", $menunode->get_text())) {
175                 // This is a divider.
176                 $content = '<li class="divider">&nbsp;</li>';
177             } else {
178                 $content = '<li>';
179                 if ($menunode->get_url() !== null) {
180                     $url = $menunode->get_url();
181                 } else {
182                     $url = '#';
183                 }
184                 $content .= html_writer::link($url, $menunode->get_text(), array('title' => $menunode->get_title()));
185                 $content .= '</li>';
186             }
187         }
188         return $content;
189     }
191     /**
192      * This code renders the navbar button to control the display of the custom menu
193      * on smaller screens.
194      *
195      * Do not display the button if the menu is empty.
196      *
197      * @return string HTML fragment
198      */
199     public function navbar_button() {
200         global $CFG;
202         if (empty($CFG->custommenuitems) && $this->lang_menu() == '') {
203             return '';
204         }
206         $iconbar = html_writer::tag('span', '', array('class' => 'icon-bar'));
207         $button = html_writer::tag('a', $iconbar . "\n" . $iconbar. "\n" . $iconbar, array(
208             'class'       => 'btn btn-navbar',
209             'data-toggle' => 'collapse',
210             'data-target' => '.nav-collapse'
211         ));
212         return $button;
213     }
215     /**
216      * Renders tabtree
217      *
218      * @param tabtree $tabtree
219      * @return string
220      */
221     protected function render_tabtree(tabtree $tabtree) {
222         if (empty($tabtree->subtree)) {
223             return '';
224         }
225         $firstrow = $secondrow = '';
226         foreach ($tabtree->subtree as $tab) {
227             $firstrow .= $this->render($tab);
228             if (($tab->selected || $tab->activated) && !empty($tab->subtree) && $tab->subtree !== array()) {
229                 $secondrow = $this->tabtree($tab->subtree);
230             }
231         }
232         return html_writer::tag('ul', $firstrow, array('class' => 'nav nav-tabs')) . $secondrow;
233     }
235     /**
236      * Renders tabobject (part of tabtree)
237      *
238      * This function is called from {@link core_renderer::render_tabtree()}
239      * and also it calls itself when printing the $tabobject subtree recursively.
240      *
241      * @param tabobject $tabobject
242      * @return string HTML fragment
243      */
244     protected function render_tabobject(tabobject $tab) {
245         if (($tab->selected and (!$tab->linkedwhenselected)) or $tab->activated) {
246             return html_writer::tag('li', html_writer::tag('a', $tab->text), array('class' => 'active'));
247         } else if ($tab->inactive) {
248             return html_writer::tag('li', html_writer::tag('a', $tab->text), array('class' => 'disabled'));
249         } else {
250             if (!($tab->link instanceof moodle_url)) {
251                 // backward compartibility when link was passed as quoted string
252                 $link = "<a href=\"$tab->link\" title=\"$tab->title\">$tab->text</a>";
253             } else {
254                 $link = html_writer::link($tab->link, $tab->text, array('title' => $tab->title));
255             }
256             $params = $tab->selected ? array('class' => 'active') : null;
257             return html_writer::tag('li', $link, $params);
258         }
259     }