mirror of
https://github.com/moodle/moodle.git
synced 2025-04-20 07:56:06 +02:00
MDL-58428 renderer: Move renderer override from core
Also update all html_writer user to escape the namespace. Also update the xpaths in behat
This commit is contained in:
parent
6a80186ebb
commit
847b0fa941
@ -13,6 +13,34 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting
|
||||
|
||||
Admin setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* labelfor - id of the form element
|
||||
* title - Setting title
|
||||
* override - Overridden message
|
||||
* warning - Warning message
|
||||
* name - Setting name
|
||||
* error - Error message
|
||||
* element - The Element HTML
|
||||
* forceltr - Force this element to be displayed LTR
|
||||
* default - Default value
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"title": "Setting title",
|
||||
"labelfor": "id0",
|
||||
"override": "Overidden",
|
||||
"warning": "Warning",
|
||||
"name": "Name",
|
||||
"error": "Error",
|
||||
"element": "Raw HTML",
|
||||
"forceltr": false,
|
||||
"default": "Default value"
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting
|
||||
|
@ -13,6 +13,26 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting_configcolourpicker
|
||||
|
||||
Admin setting colour picker template.
|
||||
|
||||
Context variables required for this template:
|
||||
* icon - optional icon context (see pix_icon)
|
||||
* name - element name
|
||||
* id - element id
|
||||
* value - element value
|
||||
* haspreviewconfig - show preview of selected color
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"icon": false,
|
||||
"name": "name0",
|
||||
"id": "id0",
|
||||
"value": "#555655",
|
||||
"haspreviewconfig": false
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_configcolourpicker
|
||||
|
@ -13,6 +13,24 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting_configduration
|
||||
|
||||
Admin duration setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* name - form element name
|
||||
* options - list of options for units containing name, value, selected
|
||||
* value - yes
|
||||
* id - element id
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"value": "5",
|
||||
"id": "test0",
|
||||
"options": [ { "name": "Minutes", "value": "mins", "selected": true } ]
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_configduration
|
||||
|
@ -13,6 +13,29 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting_configfile
|
||||
|
||||
Admin file setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* name - form element name
|
||||
* id - element id
|
||||
* size - size of the field
|
||||
* readonly - Make the field readonly
|
||||
* value - value
|
||||
* showvalidity - Show a green check if the path is readable
|
||||
* valid - True if the path is readable
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"value": "/my-super-secret-path/file",
|
||||
"id": "test0",
|
||||
"readonly": true,
|
||||
"showvalidity": true,
|
||||
"valid": false
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_configfile
|
||||
|
@ -13,6 +13,25 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting_configmultiselect
|
||||
|
||||
Admin multiselect setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* name - form element name
|
||||
* id - element id
|
||||
* size - element size
|
||||
* options - list of options containing name, value, selected
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"size": "3",
|
||||
"options": [ { "name": "Option 1", "value": "V", "selected": true },
|
||||
{ "name": "Option 2", "value": "V", "selected": true } ]
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_configmultiselect
|
||||
|
@ -13,6 +13,44 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting_configmultiselect_optgroup
|
||||
|
||||
Admin multiselect setting template with optgroup support.
|
||||
|
||||
Context variables required for this template:
|
||||
* name - form element name
|
||||
* id - element id
|
||||
* size - element size
|
||||
* options - list of options not grouped
|
||||
* optgroups - list of options grouped containing the group label and for each option: name, value, selected
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"size": "3",
|
||||
"options": [
|
||||
{ "name": "Option 1", "value": "V", "selected": false },
|
||||
{ "name": "Option 2", "value": "V", "selected": true }
|
||||
],
|
||||
"optgroups": [
|
||||
{
|
||||
"label": "Group 1",
|
||||
"options": [
|
||||
{ "name": "Option 3", "value": "V", "selected": false },
|
||||
{ "name": "Option 4", "value": "V", "selected": true }
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Group 2",
|
||||
"options": [
|
||||
{ "name": "Option 5", "value": "V", "selected": false },
|
||||
{ "name": "Option 6", "value": "V", "selected": true }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_configmultiselect_optgroup
|
||||
|
@ -13,6 +13,25 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting_configselect
|
||||
|
||||
Admin select setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* name - form element name
|
||||
* id - element id
|
||||
* options - list of options containing name, value, selected
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"options": [
|
||||
{ "name": "Option 1", "value": "V", "selected": true },
|
||||
{ "name": "Option 2", "value": "V", "selected": true }
|
||||
]
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_configselect
|
||||
|
@ -13,6 +13,42 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting_configselect_optgroup
|
||||
|
||||
Admin select with optgroup setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* name - form element name
|
||||
* id - element id
|
||||
* options - list of options (not grouped)
|
||||
* optgroups - list of options grouped containing the group label and for each option: name, value, selected
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"options": [
|
||||
{ "name": "Option 1", "value": "V", "selected": false },
|
||||
{ "name": "Option 2", "value": "V", "selected": false }
|
||||
],
|
||||
"optgroups": [
|
||||
{
|
||||
"label": "Group 1",
|
||||
"options": [
|
||||
{ "name": "Option 3", "value": "V", "selected": true },
|
||||
{ "name": "Option 4", "value": "V", "selected": false }
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Group 2",
|
||||
"options": [
|
||||
{ "name": "Option 5", "value": "V", "selected": false },
|
||||
{ "name": "Option 6", "value": "V", "selected": false }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_configselect_optgroup
|
||||
|
@ -13,6 +13,28 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting_configtext
|
||||
|
||||
Admin text setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* name - form element name
|
||||
* id - element id
|
||||
* value - element value
|
||||
* size - element size
|
||||
* forceltr - always display as ltr
|
||||
* attributes - list of additional attributes containing name, value
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"value": "A tall, dark stranger will have more fun than you.",
|
||||
"size": "21",
|
||||
"forceltr": false,
|
||||
"attributes": [ { "name": "readonly", "value": "readonly" } ]
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_configtext
|
||||
|
@ -13,6 +13,27 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting_configtextarea
|
||||
|
||||
Admin textarea setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* name - form element name
|
||||
* id - element id
|
||||
* rows - number of rows
|
||||
* cols - number of cols
|
||||
* value - default value
|
||||
* forceltr - always display as ltr
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"cols": "30",
|
||||
"rows": "3",
|
||||
"value": "Excellent day for putting Slinkies on an escalator.",
|
||||
"id": "test0"
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_configtextarea
|
||||
|
@ -13,6 +13,30 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting_configtime
|
||||
|
||||
Admin time setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* name - form element name
|
||||
* id - element id
|
||||
* hours - list of valid hour options containing name, value, selected
|
||||
* minutes - list of valid minute options containing name, value, selected
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"minutes": [
|
||||
{ "name": "00", "value": "0", "selected": true },
|
||||
{ "name": "01", "value": "1", "selected": false }
|
||||
],
|
||||
"hours": [
|
||||
{ "name": "1", "value": "1", "selected": true },
|
||||
{ "name": "2", "value": "2", "selected": false }
|
||||
]
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_configtime
|
||||
|
@ -13,6 +13,28 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting_courselist_frontpage
|
||||
|
||||
Admin courselist_frontpage setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* selects list of select objects containing id, name, key and options.
|
||||
options is another nested list of items containing name, value and selected
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"selects": [
|
||||
{
|
||||
"id": "i1",
|
||||
"name": "s1",
|
||||
"key": "k1",
|
||||
"options": [
|
||||
{ "name": "Fish", "value": "snapper", "selected": true }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_courselist_frontpage
|
||||
|
@ -13,6 +13,20 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting_devicedetectregex
|
||||
|
||||
Admin devicedetectregex setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* expressions - List of expressions containing index, name, expression and value
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"expressions": [
|
||||
{ "index": "i1", "name": "Name", "expression": "/bird|yellow/", "value": "Canary" }
|
||||
]
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_devicedetectregex
|
||||
|
@ -13,6 +13,23 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting_emoticons
|
||||
|
||||
Admin emoticons setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* name - form element name
|
||||
* id - element id
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"emoticons": [
|
||||
{ "fields": [
|
||||
{ "name": "Smile", "field": "f1", "value": ":)" }
|
||||
]}
|
||||
]
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_emoticons
|
||||
|
@ -13,6 +13,28 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/setting_gradecat_combo
|
||||
|
||||
Admin gradecat_combo setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* name - form element name
|
||||
* id - element id
|
||||
* options - list of options containing name, value and selected
|
||||
* forced - is it forced
|
||||
* advanced - is it advanced
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"options": [
|
||||
{ "name": "Option name", "value": "Value", "selected": true }
|
||||
],
|
||||
"forced": true,
|
||||
"advanced": true
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_gradecat_combo
|
||||
|
@ -13,6 +13,27 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}{{!
|
||||
@template core_admin/settings
|
||||
|
||||
Admin settings form template.
|
||||
|
||||
Context variables required for this template:
|
||||
* actionurl - url to submit to
|
||||
* params - list of parameters containing name and value
|
||||
* return - page to return to
|
||||
* title - form title
|
||||
* settings - raw html for settings
|
||||
* showsave - true if we need save buttons
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"actionurl": "/",
|
||||
"return": "/",
|
||||
"title": "Settings Form",
|
||||
"settings": "RAW HTML",
|
||||
"showsave": true
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/settings
|
||||
|
@ -368,6 +368,38 @@ class renderer_base {
|
||||
theme_get_revision(), $logo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether we should display the logo in the navbar.
|
||||
*
|
||||
* We will when there are no main logos, and we have compact logo.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_display_navbar_logo() {
|
||||
$logo = $this->get_compact_logo_url();
|
||||
return !empty($logo) && !$this->should_display_main_logo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether we should display the main logo.
|
||||
*
|
||||
* @param int $headinglevel
|
||||
* @return bool
|
||||
*/
|
||||
public function should_display_main_logo($headinglevel = 1) {
|
||||
global $PAGE;
|
||||
|
||||
// Only render the logo if we're on the front page or login page and the we have a logo.
|
||||
$logo = $this->get_logo_url();
|
||||
if ($headinglevel == 1 && !empty($logo)) {
|
||||
if ($PAGE->pagelayout == 'frontpage' || $PAGE->pagelayout == 'login') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -512,6 +544,9 @@ class core_renderer extends renderer_base {
|
||||
*/
|
||||
protected $unique_main_content_token;
|
||||
|
||||
/** @var custom_menu_item language The language menu if created */
|
||||
protected $language = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@ -593,7 +628,7 @@ class core_renderer extends renderer_base {
|
||||
* @return string HTML fragment.
|
||||
*/
|
||||
public function standard_head_html() {
|
||||
global $CFG, $SESSION;
|
||||
global $CFG, $SESSION, $SITE, $PAGE;
|
||||
|
||||
// Before we output any content, we need to ensure that certain
|
||||
// page components are set up.
|
||||
@ -689,6 +724,13 @@ class core_renderer extends renderer_base {
|
||||
$output .= "\n".$CFG->additionalhtmlhead;
|
||||
}
|
||||
|
||||
if ($PAGE->pagelayout == 'frontpage') {
|
||||
$summary = s(strip_tags(format_text($SITE->summary, FORMAT_HTML)));
|
||||
if (!empty($summary)) {
|
||||
$output .= "<meta name=\"description\" content=\"$summary\" />\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
@ -1591,15 +1633,23 @@ class core_renderer extends renderer_base {
|
||||
/**
|
||||
* Renders an action menu component.
|
||||
*
|
||||
* ARIA references:
|
||||
* - http://www.w3.org/WAI/GL/wiki/Using_ARIA_menus
|
||||
* - http://stackoverflow.com/questions/12279113/recommended-wai-aria-implementation-for-navigation-bar-menu
|
||||
*
|
||||
* @param action_menu $menu
|
||||
* @return string HTML
|
||||
*/
|
||||
public function render_action_menu(action_menu $menu) {
|
||||
|
||||
// We don't want the class icon there!
|
||||
foreach ($menu->get_secondary_actions() as $action) {
|
||||
if ($action instanceof \action_menu_link && $action->has_class('icon')) {
|
||||
$action->attributes['class'] = preg_replace('/(^|\s+)icon(\s+|$)/i', '', $action->attributes['class']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($menu->is_empty()) {
|
||||
return '';
|
||||
}
|
||||
$context = $menu->export_for_template($this);
|
||||
|
||||
return $this->render_from_template('core/action_menu', $context);
|
||||
}
|
||||
|
||||
@ -1646,20 +1696,6 @@ class core_renderer extends renderer_base {
|
||||
/**
|
||||
* Prints a nice side block with an optional header.
|
||||
*
|
||||
* The content is described
|
||||
* by a {@link core_renderer::block_contents} object.
|
||||
*
|
||||
* <div id="inst{$instanceid}" class="block_{$blockname} block">
|
||||
* <div class="header"></div>
|
||||
* <div class="content">
|
||||
* ...CONTENT...
|
||||
* <div class="footer">
|
||||
* </div>
|
||||
* </div>
|
||||
* <div class="annotation">
|
||||
* </div>
|
||||
* </div>
|
||||
*
|
||||
* @param block_contents $bc HTML for the content
|
||||
* @param string $region the region the block is appearing in.
|
||||
* @return string the HTML to be output.
|
||||
@ -1669,144 +1705,29 @@ class core_renderer extends renderer_base {
|
||||
if (empty($bc->blockinstanceid) || !strip_tags($bc->title)) {
|
||||
$bc->collapsible = block_contents::NOT_HIDEABLE;
|
||||
}
|
||||
if (!empty($bc->blockinstanceid)) {
|
||||
$bc->attributes['data-instanceid'] = $bc->blockinstanceid;
|
||||
}
|
||||
$skiptitle = strip_tags($bc->title);
|
||||
if ($bc->blockinstanceid && !empty($skiptitle)) {
|
||||
$bc->attributes['aria-labelledby'] = 'instance-'.$bc->blockinstanceid.'-header';
|
||||
} else if (!empty($bc->arialabel)) {
|
||||
$bc->attributes['aria-label'] = $bc->arialabel;
|
||||
}
|
||||
if ($bc->dockable) {
|
||||
$bc->attributes['data-dockable'] = 1;
|
||||
}
|
||||
if ($bc->collapsible == block_contents::HIDDEN) {
|
||||
$bc->add_class('hidden');
|
||||
}
|
||||
if (!empty($bc->controls)) {
|
||||
$bc->add_class('block_with_controls');
|
||||
|
||||
$id = !empty($bc->attributes['id']) ? $bc->attributes['id'] : uniqid('block-');
|
||||
$context = new stdClass();
|
||||
$context->skipid = $bc->skipid;
|
||||
$context->blockinstanceid = $bc->blockinstanceid;
|
||||
$context->dockable = $bc->dockable;
|
||||
$context->id = $id;
|
||||
$context->hidden = $bc->collapsible == block_contents::HIDDEN;
|
||||
$context->skiptitle = strip_tags($bc->title);
|
||||
$context->showskiplink = !empty($context->skiptitle);
|
||||
$context->arialabel = $bc->arialabel;
|
||||
$context->ariarole = !empty($bc->attributes['role']) ? $bc->attributes['role'] : 'complementary';
|
||||
$context->type = $bc->attributes['data-block'];
|
||||
$context->title = $bc->title;
|
||||
$context->content = $bc->content;
|
||||
$context->annotation = $bc->annotation;
|
||||
$context->footer = $bc->footer;
|
||||
$context->hascontrols = !empty($bc->controls);
|
||||
if ($context->hascontrols) {
|
||||
$context->controls = $this->block_controls($bc->controls, $id);
|
||||
}
|
||||
|
||||
|
||||
if (empty($skiptitle)) {
|
||||
$output = '';
|
||||
$skipdest = '';
|
||||
} else {
|
||||
$output = html_writer::link('#sb-'.$bc->skipid, get_string('skipa', 'access', $skiptitle),
|
||||
array('class' => 'skip skip-block', 'id' => 'fsb-' . $bc->skipid));
|
||||
$skipdest = html_writer::span('', 'skip-block-to',
|
||||
array('id' => 'sb-' . $bc->skipid));
|
||||
}
|
||||
|
||||
$output .= html_writer::start_tag('div', $bc->attributes);
|
||||
|
||||
$output .= $this->block_header($bc);
|
||||
$output .= $this->block_content($bc);
|
||||
|
||||
$output .= html_writer::end_tag('div');
|
||||
|
||||
$output .= $this->block_annotation($bc);
|
||||
|
||||
$output .= $skipdest;
|
||||
|
||||
$this->init_block_hider_js($bc);
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a header for a block
|
||||
*
|
||||
* @param block_contents $bc
|
||||
* @return string
|
||||
*/
|
||||
protected function block_header(block_contents $bc) {
|
||||
|
||||
$title = '';
|
||||
if ($bc->title) {
|
||||
$attributes = array();
|
||||
if ($bc->blockinstanceid) {
|
||||
$attributes['id'] = 'instance-'.$bc->blockinstanceid.'-header';
|
||||
}
|
||||
$title = html_writer::tag('h2', $bc->title, $attributes);
|
||||
}
|
||||
|
||||
$blockid = null;
|
||||
if (isset($bc->attributes['id'])) {
|
||||
$blockid = $bc->attributes['id'];
|
||||
}
|
||||
$controlshtml = $this->block_controls($bc->controls, $blockid);
|
||||
|
||||
$output = '';
|
||||
if ($title || $controlshtml) {
|
||||
$output .= html_writer::tag('div', html_writer::tag('div', html_writer::tag('div', '', array('class'=>'block_action')). $title . $controlshtml, array('class' => 'title')), array('class' => 'header'));
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the content area for a block
|
||||
*
|
||||
* @param block_contents $bc
|
||||
* @return string
|
||||
*/
|
||||
protected function block_content(block_contents $bc) {
|
||||
$output = html_writer::start_tag('div', array('class' => 'content'));
|
||||
if (!$bc->title && !$this->block_controls($bc->controls)) {
|
||||
$output .= html_writer::tag('div', '', array('class'=>'block_action notitle'));
|
||||
}
|
||||
$output .= $bc->content;
|
||||
$output .= $this->block_footer($bc);
|
||||
$output .= html_writer::end_tag('div');
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the footer for a block
|
||||
*
|
||||
* @param block_contents $bc
|
||||
* @return string
|
||||
*/
|
||||
protected function block_footer(block_contents $bc) {
|
||||
$output = '';
|
||||
if ($bc->footer) {
|
||||
$output .= html_writer::tag('div', $bc->footer, array('class' => 'footer'));
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the annotation for a block
|
||||
*
|
||||
* @param block_contents $bc
|
||||
* @return string
|
||||
*/
|
||||
protected function block_annotation(block_contents $bc) {
|
||||
$output = '';
|
||||
if ($bc->annotation) {
|
||||
$output .= html_writer::tag('div', $bc->annotation, array('class' => 'blockannotation'));
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the JS require function to hide a block.
|
||||
*
|
||||
* @param block_contents $bc A block_contents object
|
||||
*/
|
||||
protected function init_block_hider_js(block_contents $bc) {
|
||||
if (!empty($bc->attributes['id']) and $bc->collapsible != block_contents::NOT_HIDEABLE) {
|
||||
$config = new stdClass;
|
||||
$config->id = $bc->attributes['id'];
|
||||
$config->title = strip_tags($bc->title);
|
||||
$config->preference = 'block' . $bc->blockinstanceid . 'hidden';
|
||||
$config->tooltipVisible = get_string('hideblocka', 'access', $config->title);
|
||||
$config->tooltipHidden = get_string('showblocka', 'access', $config->title);
|
||||
|
||||
$this->page->requires->js_init_call('M.util.init_block_hider', array($config));
|
||||
user_preference_allow_ajax_update($config->preference, PARAM_BOOL);
|
||||
}
|
||||
return $this->render_from_template('core/block', $context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2055,50 +1976,7 @@ class core_renderer extends renderer_base {
|
||||
* @return string HTML fragment
|
||||
*/
|
||||
protected function render_single_button(single_button $button) {
|
||||
$attributes = array('type' => 'submit',
|
||||
'value' => $button->label,
|
||||
'disabled' => $button->disabled ? 'disabled' : null,
|
||||
'title' => $button->tooltip);
|
||||
|
||||
if ($button->actions) {
|
||||
$id = html_writer::random_id('single_button');
|
||||
$attributes['id'] = $id;
|
||||
foreach ($button->actions as $action) {
|
||||
$this->add_action_handler($action, $id);
|
||||
}
|
||||
}
|
||||
|
||||
// first the input element
|
||||
$output = html_writer::empty_tag('input', $attributes);
|
||||
|
||||
// then hidden fields
|
||||
$params = $button->url->params();
|
||||
if ($button->method === 'post') {
|
||||
$params['sesskey'] = sesskey();
|
||||
}
|
||||
foreach ($params as $var => $val) {
|
||||
$output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => $var, 'value' => $val));
|
||||
}
|
||||
|
||||
// then div wrapper for xhtml strictness
|
||||
$output = html_writer::tag('div', $output);
|
||||
|
||||
// now the form itself around it
|
||||
if ($button->method === 'get') {
|
||||
$url = $button->url->out_omit_querystring(true); // url without params, the anchor part allowed
|
||||
} else {
|
||||
$url = $button->url->out_omit_querystring(); // url without params, the anchor part not allowed
|
||||
}
|
||||
if ($url === '') {
|
||||
$url = '#'; // there has to be always some action
|
||||
}
|
||||
$attributes = array('method' => $button->method,
|
||||
'action' => $url,
|
||||
'id' => $button->formid);
|
||||
$output = html_writer::tag('form', $output, $attributes);
|
||||
|
||||
// and finally one more wrapper with class
|
||||
return html_writer::tag('div', $output, array('class' => $button->class));
|
||||
return $this->render_from_template('core/single_button', $button->export_for_template($this));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2471,7 +2349,8 @@ class core_renderer extends renderer_base {
|
||||
* @return string HTML fragment
|
||||
*/
|
||||
protected function render_help_icon(help_icon $helpicon) {
|
||||
return $this->render_from_template('core/help_icon', $helpicon->export_for_template($this));
|
||||
$context = $helpicon->export_for_template($this);
|
||||
return $this->render_from_template('core/help_icon', $context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3154,7 +3033,7 @@ EOD;
|
||||
public function box_start($classes = 'generalbox', $id = null, $attributes = array()) {
|
||||
$this->opencontainers->push('box', html_writer::end_tag('div'));
|
||||
$attributes['id'] = $id;
|
||||
$attributes['class'] = 'box ' . renderer_base::prepare_classes($classes);
|
||||
$attributes['class'] = 'box py-3 ' . renderer_base::prepare_classes($classes);
|
||||
return html_writer::start_tag('div', $attributes);
|
||||
}
|
||||
|
||||
@ -3532,39 +3411,11 @@ EOD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the navbar content so that it can be echoed out by the layout
|
||||
*
|
||||
* @return string XHTML navbar
|
||||
* This renders the navbar.
|
||||
* Uses bootstrap compatible html.
|
||||
*/
|
||||
public function navbar() {
|
||||
$items = $this->page->navbar->get_items();
|
||||
$itemcount = count($items);
|
||||
if ($itemcount === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$htmlblocks = array();
|
||||
// Iterate the navarray and display each node
|
||||
$separator = get_separator();
|
||||
for ($i=0;$i < $itemcount;$i++) {
|
||||
$item = $items[$i];
|
||||
$item->hideicon = true;
|
||||
if ($i===0) {
|
||||
$content = html_writer::tag('li', $this->render($item));
|
||||
} else {
|
||||
$content = html_writer::tag('li', $separator.$this->render($item));
|
||||
}
|
||||
$htmlblocks[] = $content;
|
||||
}
|
||||
|
||||
//accessibility: heading for navbar list (MDL-20446)
|
||||
$navbarcontent = html_writer::tag('span', get_string('pagepath'),
|
||||
array('class' => 'accesshide', 'id' => 'navbar-label'));
|
||||
$navbarcontent .= html_writer::tag('nav',
|
||||
html_writer::tag('ul', join('', $htmlblocks)),
|
||||
array('aria-labelledby' => 'navbar-label'));
|
||||
// XHTML
|
||||
return $navbarcontent;
|
||||
return $this->render_from_template('core/navbar', $this->page->navbar);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3719,14 +3570,44 @@ EOD;
|
||||
*/
|
||||
public function custom_menu($custommenuitems = '') {
|
||||
global $CFG;
|
||||
|
||||
if (empty($custommenuitems) && !empty($CFG->custommenuitems)) {
|
||||
$custommenuitems = $CFG->custommenuitems;
|
||||
}
|
||||
if (empty($custommenuitems)) {
|
||||
return '';
|
||||
$custommenu = new custom_menu($custommenuitems, current_language());
|
||||
return $this->render_custom_menu($custommenu);
|
||||
}
|
||||
|
||||
/**
|
||||
* We want to show the custom menus as a list of links in the footer on small screens.
|
||||
* Just return the menu object exported so we can render it differently.
|
||||
*/
|
||||
public function custom_menu_flat() {
|
||||
global $CFG;
|
||||
$custommenuitems = '';
|
||||
|
||||
if (empty($custommenuitems) && !empty($CFG->custommenuitems)) {
|
||||
$custommenuitems = $CFG->custommenuitems;
|
||||
}
|
||||
$custommenu = new custom_menu($custommenuitems, current_language());
|
||||
return $this->render($custommenu);
|
||||
$langs = get_string_manager()->get_list_of_translations();
|
||||
$haslangmenu = $this->lang_menu() != '';
|
||||
|
||||
if ($haslangmenu) {
|
||||
$strlang = get_string('language');
|
||||
$currentlang = current_language();
|
||||
if (isset($langs[$currentlang])) {
|
||||
$currentlang = $langs[$currentlang];
|
||||
} else {
|
||||
$currentlang = $strlang;
|
||||
}
|
||||
$this->language = $custommenu->add($currentlang, new moodle_url('#'), $strlang, 10000);
|
||||
foreach ($langs as $langtype => $langname) {
|
||||
$this->language->add($langname, new moodle_url($this->page->url, array('lang' => $langtype)), $langname);
|
||||
}
|
||||
}
|
||||
|
||||
return $custommenu->export_for_template($this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3740,31 +3621,35 @@ EOD;
|
||||
* @return string
|
||||
*/
|
||||
protected function render_custom_menu(custom_menu $menu) {
|
||||
static $menucount = 0;
|
||||
// If the menu has no children return an empty string
|
||||
if (!$menu->has_children()) {
|
||||
global $CFG;
|
||||
|
||||
$langs = get_string_manager()->get_list_of_translations();
|
||||
$haslangmenu = $this->lang_menu() != '';
|
||||
|
||||
if (!$menu->has_children() && !$haslangmenu) {
|
||||
return '';
|
||||
}
|
||||
// Increment the menu count. This is used for ID's that get worked with
|
||||
// in JavaScript as is essential
|
||||
$menucount++;
|
||||
// Initialise this custom menu (the custom menu object is contained in javascript-static
|
||||
$jscode = js_writer::function_call_with_Y('M.core_custom_menu.init', array('custom_menu_'.$menucount));
|
||||
$jscode = "(function(){{$jscode}})";
|
||||
$this->page->requires->yui_module('node-menunav', $jscode);
|
||||
// Build the root nodes as required by YUI
|
||||
$content = html_writer::start_tag('div', array('id'=>'custom_menu_'.$menucount, 'class'=>'yui3-menu yui3-menu-horizontal javascript-disabled custom-menu'));
|
||||
$content .= html_writer::start_tag('div', array('class'=>'yui3-menu-content'));
|
||||
$content .= html_writer::start_tag('ul');
|
||||
// Render each child
|
||||
foreach ($menu->get_children() as $item) {
|
||||
$content .= $this->render_custom_menu_item($item);
|
||||
|
||||
if ($haslangmenu) {
|
||||
$strlang = get_string('language');
|
||||
$currentlang = current_language();
|
||||
if (isset($langs[$currentlang])) {
|
||||
$currentlang = $langs[$currentlang];
|
||||
} else {
|
||||
$currentlang = $strlang;
|
||||
}
|
||||
$this->language = $menu->add($currentlang, new moodle_url('#'), $strlang, 10000);
|
||||
foreach ($langs as $langtype => $langname) {
|
||||
$this->language->add($langname, new moodle_url($this->page->url, array('lang' => $langtype)), $langname);
|
||||
}
|
||||
}
|
||||
// Close the open tags
|
||||
$content .= html_writer::end_tag('ul');
|
||||
$content .= html_writer::end_tag('div');
|
||||
$content .= html_writer::end_tag('div');
|
||||
// Return the custom menu
|
||||
|
||||
$content = '';
|
||||
foreach ($menu->get_children() as $item) {
|
||||
$context = $item->export_for_template($this);
|
||||
$content .= $this->render_from_template('core/custom_menu_item', $context);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
@ -3897,12 +3782,8 @@ EOD;
|
||||
if (empty($tabtree->subtree)) {
|
||||
return '';
|
||||
}
|
||||
$str = '';
|
||||
$str .= html_writer::start_tag('div', array('class' => 'tabtree'));
|
||||
$str .= $this->render_tabobject($tabtree);
|
||||
$str .= html_writer::end_tag('div').
|
||||
html_writer::tag('div', ' ', array('class' => 'clearer'));
|
||||
return $str;
|
||||
$data = $tabtree->export_for_template($this);
|
||||
return $this->render_from_template('core/tabtree', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4029,36 +3910,7 @@ EOD;
|
||||
* @return string
|
||||
*/
|
||||
public function body_css_classes(array $additionalclasses = array()) {
|
||||
// Add a class for each block region on the page.
|
||||
// We use the block manager here because the theme object makes get_string calls.
|
||||
$usedregions = array();
|
||||
foreach ($this->page->blocks->get_regions() as $region) {
|
||||
$additionalclasses[] = 'has-region-'.$region;
|
||||
if ($this->page->blocks->region_has_content($region, $this)) {
|
||||
$additionalclasses[] = 'used-region-'.$region;
|
||||
$usedregions[] = $region;
|
||||
} else {
|
||||
$additionalclasses[] = 'empty-region-'.$region;
|
||||
}
|
||||
if ($this->page->blocks->region_completely_docked($region, $this)) {
|
||||
$additionalclasses[] = 'docked-region-'.$region;
|
||||
}
|
||||
}
|
||||
if (!$usedregions) {
|
||||
// No regions means there is only content, add 'content-only' class.
|
||||
$additionalclasses[] = 'content-only';
|
||||
} else if (count($usedregions) === 1) {
|
||||
// Add the -only class for the only used region.
|
||||
$region = array_shift($usedregions);
|
||||
$additionalclasses[] = $region . '-only';
|
||||
}
|
||||
foreach ($this->page->layout_options as $option => $value) {
|
||||
if ($value) {
|
||||
$additionalclasses[] = 'layout-option-'.$option;
|
||||
}
|
||||
}
|
||||
$css = $this->page->bodyclasses .' '. join(' ', $additionalclasses);
|
||||
return $css;
|
||||
return $this->page->bodyclasses . ' ' . implode(' ', $additionalclasses);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4161,29 +4013,7 @@ EOD;
|
||||
* @return string The output.
|
||||
*/
|
||||
public function render_preferences_groups(preferences_groups $renderable) {
|
||||
$html = '';
|
||||
$html .= html_writer::start_div('row-fluid');
|
||||
$html .= html_writer::start_tag('div', array('class' => 'span12 preferences-groups'));
|
||||
$i = 0;
|
||||
$open = false;
|
||||
foreach ($renderable->groups as $group) {
|
||||
if ($i == 0 || $i % 3 == 0) {
|
||||
if ($open) {
|
||||
$html .= html_writer::end_tag('div');
|
||||
}
|
||||
$html .= html_writer::start_tag('div', array('class' => 'row-fluid'));
|
||||
$open = true;
|
||||
}
|
||||
$html .= $this->render($group);
|
||||
$i++;
|
||||
}
|
||||
|
||||
$html .= html_writer::end_tag('div');
|
||||
|
||||
$html .= html_writer::end_tag('ul');
|
||||
$html .= html_writer::end_tag('div');
|
||||
$html .= html_writer::end_div();
|
||||
return $html;
|
||||
return $this->render_from_template('core/preferences_groups', $renderable);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4209,13 +4039,20 @@ EOD;
|
||||
}
|
||||
|
||||
public function context_header($headerinfo = null, $headinglevel = 1) {
|
||||
global $DB, $USER, $CFG;
|
||||
global $DB, $USER, $CFG, $SITE;
|
||||
require_once($CFG->dirroot . '/user/lib.php');
|
||||
$context = $this->page->context;
|
||||
$heading = null;
|
||||
$imagedata = null;
|
||||
$subheader = null;
|
||||
$userbuttons = null;
|
||||
|
||||
if ($this->should_display_main_logo($headinglevel)) {
|
||||
$sitename = format_string($SITE->fullname, true, array('context' => context_course::instance(SITEID)));
|
||||
return html_writer::div(html_writer::empty_tag('img', [
|
||||
'src' => $this->get_logo_url(null, 150), 'alt' => $sitename]), 'logo');
|
||||
}
|
||||
|
||||
// Make sure to use the heading if it has been set.
|
||||
if (isset($headerinfo['heading'])) {
|
||||
$heading = $headerinfo['heading'];
|
||||
@ -4372,15 +4209,232 @@ EOD;
|
||||
* @return string HTML to display the main header.
|
||||
*/
|
||||
public function full_header() {
|
||||
$html = html_writer::start_tag('header', array('id' => 'page-header', 'class' => 'clearfix'));
|
||||
$html .= $this->context_header();
|
||||
$html .= html_writer::start_div('clearfix', array('id' => 'page-navbar'));
|
||||
$html .= html_writer::tag('div', $this->navbar(), array('class' => 'breadcrumb-nav'));
|
||||
$html .= html_writer::div($this->page_heading_button(), 'breadcrumb-button');
|
||||
$html .= html_writer::end_div();
|
||||
$html .= html_writer::tag('div', $this->course_header(), array('id' => 'course-header'));
|
||||
$html .= html_writer::end_tag('header');
|
||||
return $html;
|
||||
global $PAGE;
|
||||
|
||||
$header = new stdClass();
|
||||
$header->settingsmenu = $this->context_header_settings_menu();
|
||||
$header->contextheader = $this->context_header();
|
||||
$header->hasnavbar = empty($PAGE->layout_options['nonavbar']);
|
||||
$header->navbar = $this->navbar();
|
||||
$header->pageheadingbutton = $this->page_heading_button();
|
||||
$header->courseheader = $this->course_header();
|
||||
return $this->render_from_template('core/full_header', $header);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an optional menu that can be added to a layout by a theme. It contains the
|
||||
* menu for the course administration, only on the course main page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function context_header_settings_menu() {
|
||||
$context = $this->page->context;
|
||||
$menu = new action_menu();
|
||||
|
||||
$items = $this->page->navbar->get_items();
|
||||
$currentnode = end($items);
|
||||
|
||||
$showcoursemenu = false;
|
||||
$showfrontpagemenu = false;
|
||||
$showusermenu = false;
|
||||
|
||||
// We are on the course home page.
|
||||
if (($context->contextlevel == CONTEXT_COURSE) &&
|
||||
!empty($currentnode) &&
|
||||
($currentnode->type == navigation_node::TYPE_COURSE || $currentnode->type == navigation_node::TYPE_SECTION)) {
|
||||
$showcoursemenu = true;
|
||||
}
|
||||
|
||||
$courseformat = course_get_format($this->page->course);
|
||||
// This is a single activity course format, always show the course menu on the activity main page.
|
||||
if ($context->contextlevel == CONTEXT_MODULE &&
|
||||
!$courseformat->has_view_page()) {
|
||||
|
||||
$this->page->navigation->initialise();
|
||||
$activenode = $this->page->navigation->find_active_node();
|
||||
// If the settings menu has been forced then show the menu.
|
||||
if ($this->page->is_settings_menu_forced()) {
|
||||
$showcoursemenu = true;
|
||||
} else if (!empty($activenode) && ($activenode->type == navigation_node::TYPE_ACTIVITY ||
|
||||
$activenode->type == navigation_node::TYPE_RESOURCE)) {
|
||||
|
||||
// We only want to show the menu on the first page of the activity. This means
|
||||
// the breadcrumb has no additional nodes.
|
||||
if ($currentnode && ($currentnode->key == $activenode->key && $currentnode->type == $activenode->type)) {
|
||||
$showcoursemenu = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is the site front page.
|
||||
if ($context->contextlevel == CONTEXT_COURSE &&
|
||||
!empty($currentnode) &&
|
||||
$currentnode->key === 'home') {
|
||||
$showfrontpagemenu = true;
|
||||
}
|
||||
|
||||
// This is the user profile page.
|
||||
if ($context->contextlevel == CONTEXT_USER &&
|
||||
!empty($currentnode) &&
|
||||
($currentnode->key === 'myprofile')) {
|
||||
$showusermenu = true;
|
||||
}
|
||||
|
||||
if ($showfrontpagemenu) {
|
||||
$settingsnode = $this->page->settingsnav->find('frontpage', navigation_node::TYPE_SETTING);
|
||||
if ($settingsnode) {
|
||||
// Build an action menu based on the visible nodes from this navigation tree.
|
||||
$skipped = $this->build_action_menu_from_navigation($menu, $settingsnode, false, true);
|
||||
|
||||
// We only add a list to the full settings menu if we didn't include every node in the short menu.
|
||||
if ($skipped) {
|
||||
$text = get_string('morenavigationlinks');
|
||||
$url = new moodle_url('/course/admin.php', array('courseid' => $this->page->course->id));
|
||||
$link = new action_link($url, $text, null, null, new pix_icon('t/edit', $text));
|
||||
$menu->add_secondary_action($link);
|
||||
}
|
||||
}
|
||||
} else if ($showcoursemenu) {
|
||||
$settingsnode = $this->page->settingsnav->find('courseadmin', navigation_node::TYPE_COURSE);
|
||||
if ($settingsnode) {
|
||||
// Build an action menu based on the visible nodes from this navigation tree.
|
||||
$skipped = $this->build_action_menu_from_navigation($menu, $settingsnode, false, true);
|
||||
|
||||
// We only add a list to the full settings menu if we didn't include every node in the short menu.
|
||||
if ($skipped) {
|
||||
$text = get_string('morenavigationlinks');
|
||||
$url = new moodle_url('/course/admin.php', array('courseid' => $this->page->course->id));
|
||||
$link = new action_link($url, $text, null, null, new pix_icon('t/edit', $text));
|
||||
$menu->add_secondary_action($link);
|
||||
}
|
||||
}
|
||||
} else if ($showusermenu) {
|
||||
// Get the course admin node from the settings navigation.
|
||||
$settingsnode = $this->page->settingsnav->find('useraccount', navigation_node::TYPE_CONTAINER);
|
||||
if ($settingsnode) {
|
||||
// Build an action menu based on the visible nodes from this navigation tree.
|
||||
$this->build_action_menu_from_navigation($menu, $settingsnode);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->render($menu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a node in the nav tree and make an action menu out of it.
|
||||
* The links are injected in the action menu.
|
||||
*
|
||||
* @param action_menu $menu
|
||||
* @param navigation_node $node
|
||||
* @param boolean $indent
|
||||
* @param boolean $onlytopleafnodes
|
||||
* @return boolean nodesskipped - True if nodes were skipped in building the menu
|
||||
*/
|
||||
protected function build_action_menu_from_navigation(action_menu $menu,
|
||||
navigation_node $node,
|
||||
$indent = false,
|
||||
$onlytopleafnodes = false) {
|
||||
$skipped = false;
|
||||
// Build an action menu based on the visible nodes from this navigation tree.
|
||||
foreach ($node->children as $menuitem) {
|
||||
if ($menuitem->display) {
|
||||
if ($onlytopleafnodes && $menuitem->children->count()) {
|
||||
$skipped = true;
|
||||
continue;
|
||||
}
|
||||
if ($menuitem->action) {
|
||||
if ($menuitem->action instanceof action_link) {
|
||||
$link = $menuitem->action;
|
||||
// Give preference to setting icon over action icon.
|
||||
if (!empty($menuitem->icon)) {
|
||||
$link->icon = $menuitem->icon;
|
||||
}
|
||||
} else {
|
||||
$link = new action_link($menuitem->action, $menuitem->text, null, null, $menuitem->icon);
|
||||
}
|
||||
} else {
|
||||
if ($onlytopleafnodes) {
|
||||
$skipped = true;
|
||||
continue;
|
||||
}
|
||||
$link = new action_link(new moodle_url('#'), $menuitem->text, null, ['disabled' => true], $menuitem->icon);
|
||||
}
|
||||
if ($indent) {
|
||||
$link->add_class('ml-4');
|
||||
}
|
||||
if (!empty($menuitem->classes)) {
|
||||
$link->add_class(implode(" ", $menuitem->classes));
|
||||
}
|
||||
|
||||
$menu->add_secondary_action($link);
|
||||
$skipped = $skipped || $this->build_action_menu_from_navigation($menu, $menuitem, true);
|
||||
}
|
||||
}
|
||||
return $skipped;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an optional menu that can be added to a layout by a theme. It contains the
|
||||
* menu for the most specific thing from the settings block. E.g. Module administration.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function region_main_settings_menu() {
|
||||
$context = $this->page->context;
|
||||
$menu = new action_menu();
|
||||
|
||||
if ($context->contextlevel == CONTEXT_MODULE) {
|
||||
|
||||
$this->page->navigation->initialise();
|
||||
$node = $this->page->navigation->find_active_node();
|
||||
$buildmenu = false;
|
||||
// If the settings menu has been forced then show the menu.
|
||||
if ($this->page->is_settings_menu_forced()) {
|
||||
$buildmenu = true;
|
||||
} else if (!empty($node) && ($node->type == navigation_node::TYPE_ACTIVITY ||
|
||||
$node->type == navigation_node::TYPE_RESOURCE)) {
|
||||
|
||||
$items = $this->page->navbar->get_items();
|
||||
$navbarnode = end($items);
|
||||
// We only want to show the menu on the first page of the activity. This means
|
||||
// the breadcrumb has no additional nodes.
|
||||
if ($navbarnode && ($navbarnode->key === $node->key && $navbarnode->type == $node->type)) {
|
||||
$buildmenu = true;
|
||||
}
|
||||
}
|
||||
if ($buildmenu) {
|
||||
// Get the course admin node from the settings navigation.
|
||||
$node = $this->page->settingsnav->find('modulesettings', navigation_node::TYPE_SETTING);
|
||||
if ($node) {
|
||||
// Build an action menu based on the visible nodes from this navigation tree.
|
||||
$this->build_action_menu_from_navigation($menu, $node);
|
||||
}
|
||||
}
|
||||
|
||||
} else if ($context->contextlevel == CONTEXT_COURSECAT) {
|
||||
// For course category context, show category settings menu, if we're on the course category page.
|
||||
if ($this->page->pagetype === 'course-index-category') {
|
||||
$node = $this->page->settingsnav->find('categorysettings', navigation_node::TYPE_CONTAINER);
|
||||
if ($node) {
|
||||
// Build an action menu based on the visible nodes from this navigation tree.
|
||||
$this->build_action_menu_from_navigation($menu, $node);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
$items = $this->page->navbar->get_items();
|
||||
$navbarnode = end($items);
|
||||
|
||||
if ($navbarnode && ($navbarnode->key === 'participants')) {
|
||||
$node = $this->page->settingsnav->find('users', navigation_node::TYPE_CONTAINER);
|
||||
if ($node) {
|
||||
// Build an action menu based on the visible nodes from this navigation tree.
|
||||
$this->build_action_menu_from_navigation($menu, $node);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return $this->render($menu);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4462,7 +4516,7 @@ EOD;
|
||||
* @return string
|
||||
*/
|
||||
public function render_login(\core_auth\output\login $form) {
|
||||
global $CFG;
|
||||
global $CFG, $SITE;
|
||||
|
||||
$context = $form->export_for_template($this);
|
||||
|
||||
@ -4473,6 +4527,13 @@ EOD;
|
||||
$context->cookieshelpiconformatted = $this->help_icon('cookiesenabled');
|
||||
}
|
||||
$context->errorformatted = $this->error_text($context->error);
|
||||
$url = $this->get_logo_url();
|
||||
if ($url) {
|
||||
$url = $url->out(false);
|
||||
}
|
||||
$context->logourl = $url;
|
||||
$context->sitename = format_string($SITE->fullname, true,
|
||||
['context' => context_course::instance(SITEID), "escape" => false]);
|
||||
|
||||
return $this->render_from_template('core/loginform', $context);
|
||||
}
|
||||
@ -4556,7 +4617,16 @@ EOD;
|
||||
* @return string
|
||||
*/
|
||||
public function render_login_signup_form($form) {
|
||||
global $SITE;
|
||||
|
||||
$context = $form->export_for_template($this);
|
||||
$url = $this->get_logo_url();
|
||||
if ($url) {
|
||||
$url = $url->out(false);
|
||||
}
|
||||
$context['logourl'] = $url;
|
||||
$context['sitename'] = format_string($SITE->fullname, true,
|
||||
['context' => context_course::instance(SITEID), "escape" => false]);
|
||||
|
||||
return $this->render_from_template('core/signup_form_layout', $context);
|
||||
}
|
||||
@ -5023,6 +5093,15 @@ class core_renderer_maintenance extends core_renderer {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure login info.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function secure_login_info() {
|
||||
return $this->login_info(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does nothing. The maintenance renderer cannot produce user pictures.
|
||||
*
|
||||
|
@ -16,23 +16,7 @@
|
||||
|
||||
namespace theme_boost\output;
|
||||
|
||||
use coding_exception;
|
||||
use html_writer;
|
||||
use tabobject;
|
||||
use tabtree;
|
||||
use custom_menu_item;
|
||||
use custom_menu;
|
||||
use block_contents;
|
||||
use navigation_node;
|
||||
use action_link;
|
||||
use stdClass;
|
||||
use moodle_url;
|
||||
use preferences_groups;
|
||||
use action_menu;
|
||||
use help_icon;
|
||||
use single_button;
|
||||
use context_course;
|
||||
use pix_icon;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
@ -46,70 +30,6 @@ defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
class core_renderer extends \core_renderer {
|
||||
|
||||
/** @var custom_menu_item language The language menu if created */
|
||||
protected $language = null;
|
||||
|
||||
/**
|
||||
* Outputs the opening section of a box.
|
||||
*
|
||||
* @param string $classes A space-separated list of CSS classes
|
||||
* @param string $id An optional ID
|
||||
* @param array $attributes An array of other attributes to give the box.
|
||||
* @return string the HTML to output.
|
||||
*/
|
||||
public function box_start($classes = 'generalbox', $id = null, $attributes = array()) {
|
||||
if (is_array($classes)) {
|
||||
$classes = implode(' ', $classes);
|
||||
}
|
||||
return parent::box_start($classes . ' py-3', $id, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for header elements.
|
||||
*
|
||||
* @return string HTML to display the main header.
|
||||
*/
|
||||
public function full_header() {
|
||||
global $PAGE;
|
||||
|
||||
$header = new stdClass();
|
||||
$header->settingsmenu = $this->context_header_settings_menu();
|
||||
$header->contextheader = $this->context_header();
|
||||
$header->hasnavbar = empty($PAGE->layout_options['nonavbar']);
|
||||
$header->navbar = $this->navbar();
|
||||
$header->pageheadingbutton = $this->page_heading_button();
|
||||
$header->courseheader = $this->course_header();
|
||||
return $this->render_from_template('theme_boost/header', $header);
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard tags that should be included in the <head> tag
|
||||
* including a meta description for the front page
|
||||
*
|
||||
* @return string HTML fragment.
|
||||
*/
|
||||
public function standard_head_html() {
|
||||
global $SITE, $PAGE;
|
||||
|
||||
$output = parent::standard_head_html();
|
||||
if ($PAGE->pagelayout == 'frontpage') {
|
||||
$summary = s(strip_tags(format_text($SITE->summary, FORMAT_HTML)));
|
||||
if (!empty($summary)) {
|
||||
$output .= "<meta name=\"description\" content=\"$summary\" />\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/*
|
||||
* This renders the navbar.
|
||||
* Uses bootstrap compatible html.
|
||||
*/
|
||||
public function navbar() {
|
||||
return $this->render_from_template('core/navbar', $this->page->navbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* We don't like these...
|
||||
*
|
||||
@ -117,577 +37,4 @@ class core_renderer extends \core_renderer {
|
||||
public function edit_button(moodle_url $url) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to inject the logo.
|
||||
*
|
||||
* @param array $headerinfo The header info.
|
||||
* @param int $headinglevel What level the 'h' tag will be.
|
||||
* @return string HTML for the header bar.
|
||||
*/
|
||||
public function context_header($headerinfo = null, $headinglevel = 1) {
|
||||
global $SITE;
|
||||
|
||||
if ($this->should_display_main_logo($headinglevel)) {
|
||||
$sitename = format_string($SITE->fullname, true, array('context' => context_course::instance(SITEID)));
|
||||
return html_writer::div(html_writer::empty_tag('img', [
|
||||
'src' => $this->get_logo_url(null, 150), 'alt' => $sitename]), 'logo');
|
||||
}
|
||||
|
||||
return parent::context_header($headerinfo, $headinglevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the compact logo URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_compact_logo_url($maxwidth = 100, $maxheight = 100) {
|
||||
return parent::get_compact_logo_url(null, 70);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether we should display the main logo.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_display_main_logo($headinglevel = 1) {
|
||||
global $PAGE;
|
||||
|
||||
// Only render the logo if we're on the front page or login page and the we have a logo.
|
||||
$logo = $this->get_logo_url();
|
||||
if ($headinglevel == 1 && !empty($logo)) {
|
||||
if ($PAGE->pagelayout == 'frontpage' || $PAGE->pagelayout == 'login') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Whether we should display the logo in the navbar.
|
||||
*
|
||||
* We will when there are no main logos, and we have compact logo.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_display_navbar_logo() {
|
||||
$logo = $this->get_compact_logo_url();
|
||||
return !empty($logo) && !$this->should_display_main_logo();
|
||||
}
|
||||
|
||||
/*
|
||||
* Overriding the custom_menu function ensures the custom menu is
|
||||
* always shown, even if no menu items are configured in the global
|
||||
* theme settings page.
|
||||
*/
|
||||
public function custom_menu($custommenuitems = '') {
|
||||
global $CFG;
|
||||
|
||||
if (empty($custommenuitems) && !empty($CFG->custommenuitems)) {
|
||||
$custommenuitems = $CFG->custommenuitems;
|
||||
}
|
||||
$custommenu = new custom_menu($custommenuitems, current_language());
|
||||
return $this->render_custom_menu($custommenu);
|
||||
}
|
||||
|
||||
/**
|
||||
* We want to show the custom menus as a list of links in the footer on small screens.
|
||||
* Just return the menu object exported so we can render it differently.
|
||||
*/
|
||||
public function custom_menu_flat() {
|
||||
global $CFG;
|
||||
$custommenuitems = '';
|
||||
|
||||
if (empty($custommenuitems) && !empty($CFG->custommenuitems)) {
|
||||
$custommenuitems = $CFG->custommenuitems;
|
||||
}
|
||||
$custommenu = new custom_menu($custommenuitems, current_language());
|
||||
$langs = get_string_manager()->get_list_of_translations();
|
||||
$haslangmenu = $this->lang_menu() != '';
|
||||
|
||||
if ($haslangmenu) {
|
||||
$strlang = get_string('language');
|
||||
$currentlang = current_language();
|
||||
if (isset($langs[$currentlang])) {
|
||||
$currentlang = $langs[$currentlang];
|
||||
} else {
|
||||
$currentlang = $strlang;
|
||||
}
|
||||
$this->language = $custommenu->add($currentlang, new moodle_url('#'), $strlang, 10000);
|
||||
foreach ($langs as $langtype => $langname) {
|
||||
$this->language->add($langname, new moodle_url($this->page->url, array('lang' => $langtype)), $langname);
|
||||
}
|
||||
}
|
||||
|
||||
return $custommenu->export_for_template($this);
|
||||
}
|
||||
|
||||
/*
|
||||
* This renders the bootstrap top menu.
|
||||
*
|
||||
* This renderer is needed to enable the Bootstrap style navigation.
|
||||
*/
|
||||
protected function render_custom_menu(custom_menu $menu) {
|
||||
global $CFG;
|
||||
|
||||
$langs = get_string_manager()->get_list_of_translations();
|
||||
$haslangmenu = $this->lang_menu() != '';
|
||||
|
||||
if (!$menu->has_children() && !$haslangmenu) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($haslangmenu) {
|
||||
$strlang = get_string('language');
|
||||
$currentlang = current_language();
|
||||
if (isset($langs[$currentlang])) {
|
||||
$currentlang = $langs[$currentlang];
|
||||
} else {
|
||||
$currentlang = $strlang;
|
||||
}
|
||||
$this->language = $menu->add($currentlang, new moodle_url('#'), $strlang, 10000);
|
||||
foreach ($langs as $langtype => $langname) {
|
||||
$this->language->add($langname, new moodle_url($this->page->url, array('lang' => $langtype)), $langname);
|
||||
}
|
||||
}
|
||||
|
||||
$content = '';
|
||||
foreach ($menu->get_children() as $item) {
|
||||
$context = $item->export_for_template($this);
|
||||
$content .= $this->render_from_template('core/custom_menu_item', $context);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* This code renders the navbar button to control the display of the custom menu
|
||||
* on smaller screens.
|
||||
*
|
||||
* Do not display the button if the menu is empty.
|
||||
*
|
||||
* @return string HTML fragment
|
||||
*/
|
||||
public function navbar_button() {
|
||||
global $CFG;
|
||||
|
||||
if (empty($CFG->custommenuitems) && $this->lang_menu() == '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$iconbar = html_writer::tag('span', '', array('class' => 'icon-bar'));
|
||||
$button = html_writer::tag('a', $iconbar . "\n" . $iconbar. "\n" . $iconbar, array(
|
||||
'class' => 'btn btn-navbar',
|
||||
'data-toggle' => 'collapse',
|
||||
'data-target' => '.nav-collapse'
|
||||
));
|
||||
return $button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders tabtree
|
||||
*
|
||||
* @param tabtree $tabtree
|
||||
* @return string
|
||||
*/
|
||||
protected function render_tabtree(tabtree $tabtree) {
|
||||
if (empty($tabtree->subtree)) {
|
||||
return '';
|
||||
}
|
||||
$data = $tabtree->export_for_template($this);
|
||||
return $this->render_from_template('core/tabtree', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders tabobject (part of tabtree)
|
||||
*
|
||||
* This function is called from {@link core_renderer::render_tabtree()}
|
||||
* and also it calls itself when printing the $tabobject subtree recursively.
|
||||
*
|
||||
* @param tabobject $tabobject
|
||||
* @return string HTML fragment
|
||||
*/
|
||||
protected function render_tabobject(tabobject $tab) {
|
||||
throw new coding_exception('Tab objects should not be directly rendered.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a nice side block with an optional header.
|
||||
*
|
||||
* @param block_contents $bc HTML for the content
|
||||
* @param string $region the region the block is appearing in.
|
||||
* @return string the HTML to be output.
|
||||
*/
|
||||
public function block(block_contents $bc, $region) {
|
||||
$bc = clone($bc); // Avoid messing up the object passed in.
|
||||
if (empty($bc->blockinstanceid) || !strip_tags($bc->title)) {
|
||||
$bc->collapsible = block_contents::NOT_HIDEABLE;
|
||||
}
|
||||
|
||||
$id = !empty($bc->attributes['id']) ? $bc->attributes['id'] : uniqid('block-');
|
||||
$context = new stdClass();
|
||||
$context->skipid = $bc->skipid;
|
||||
$context->blockinstanceid = $bc->blockinstanceid;
|
||||
$context->dockable = $bc->dockable;
|
||||
$context->id = $id;
|
||||
$context->hidden = $bc->collapsible == block_contents::HIDDEN;
|
||||
$context->skiptitle = strip_tags($bc->title);
|
||||
$context->showskiplink = !empty($context->skiptitle);
|
||||
$context->arialabel = $bc->arialabel;
|
||||
$context->ariarole = !empty($bc->attributes['role']) ? $bc->attributes['role'] : 'complementary';
|
||||
$context->type = $bc->attributes['data-block'];
|
||||
$context->title = $bc->title;
|
||||
$context->content = $bc->content;
|
||||
$context->annotation = $bc->annotation;
|
||||
$context->footer = $bc->footer;
|
||||
$context->hascontrols = !empty($bc->controls);
|
||||
if ($context->hascontrols) {
|
||||
$context->controls = $this->block_controls($bc->controls, $id);
|
||||
}
|
||||
|
||||
return $this->render_from_template('core/block', $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CSS classes to apply to the body tag.
|
||||
*
|
||||
* @since Moodle 2.5.1 2.6
|
||||
* @param array $additionalclasses Any additional classes to apply.
|
||||
* @return string
|
||||
*/
|
||||
public function body_css_classes(array $additionalclasses = array()) {
|
||||
return $this->page->bodyclasses . ' ' . implode(' ', $additionalclasses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders preferences groups.
|
||||
*
|
||||
* @param preferences_groups $renderable The renderable
|
||||
* @return string The output.
|
||||
*/
|
||||
public function render_preferences_groups(preferences_groups $renderable) {
|
||||
return $this->render_from_template('core/preferences_groups', $renderable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an action menu component.
|
||||
*
|
||||
* @param action_menu $menu
|
||||
* @return string HTML
|
||||
*/
|
||||
public function render_action_menu(action_menu $menu) {
|
||||
|
||||
// We don't want the class icon there!
|
||||
foreach ($menu->get_secondary_actions() as $action) {
|
||||
if ($action instanceof \action_menu_link && $action->has_class('icon')) {
|
||||
$action->attributes['class'] = preg_replace('/(^|\s+)icon(\s+|$)/i', '', $action->attributes['class']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($menu->is_empty()) {
|
||||
return '';
|
||||
}
|
||||
$context = $menu->export_for_template($this);
|
||||
|
||||
return $this->render_from_template('core/action_menu', $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of user image rendering.
|
||||
*
|
||||
* @param help_icon $helpicon A help icon instance
|
||||
* @return string HTML fragment
|
||||
*/
|
||||
protected function render_help_icon(help_icon $helpicon) {
|
||||
$context = $helpicon->export_for_template($this);
|
||||
return $this->render_from_template('core/help_icon', $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a single button widget.
|
||||
*
|
||||
* This will return HTML to display a form containing a single button.
|
||||
*
|
||||
* @param single_button $button
|
||||
* @return string HTML fragment
|
||||
*/
|
||||
protected function render_single_button(single_button $button) {
|
||||
return $this->render_from_template('core/single_button', $button->export_for_template($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the login form.
|
||||
*
|
||||
* @param \core_auth\output\login $form The renderable.
|
||||
* @return string
|
||||
*/
|
||||
public function render_login(\core_auth\output\login $form) {
|
||||
global $CFG, $SITE;
|
||||
|
||||
$context = $form->export_for_template($this);
|
||||
|
||||
// Override because rendering is not supported in template yet.
|
||||
if ($CFG->rememberusername == 0) {
|
||||
$context->cookieshelpiconformatted = $this->help_icon('cookiesenabledonlysession');
|
||||
} else {
|
||||
$context->cookieshelpiconformatted = $this->help_icon('cookiesenabled');
|
||||
}
|
||||
$context->errorformatted = $this->error_text($context->error);
|
||||
$url = $this->get_logo_url();
|
||||
if ($url) {
|
||||
$url = $url->out(false);
|
||||
}
|
||||
$context->logourl = $url;
|
||||
$context->sitename = format_string($SITE->fullname, true,
|
||||
['context' => context_course::instance(SITEID), "escape" => false]);
|
||||
|
||||
return $this->render_from_template('core/loginform', $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the login signup form into a nice template for the theme.
|
||||
*
|
||||
* @param mform $form
|
||||
* @return string
|
||||
*/
|
||||
public function render_login_signup_form($form) {
|
||||
global $SITE;
|
||||
|
||||
$context = $form->export_for_template($this);
|
||||
$url = $this->get_logo_url();
|
||||
if ($url) {
|
||||
$url = $url->out(false);
|
||||
}
|
||||
$context['logourl'] = $url;
|
||||
$context['sitename'] = format_string($SITE->fullname, true,
|
||||
['context' => context_course::instance(SITEID), "escape" => false]);
|
||||
|
||||
return $this->render_from_template('core/signup_form_layout', $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an optional menu that can be added to a layout by a theme. It contains the
|
||||
* menu for the course administration, only on the course main page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function context_header_settings_menu() {
|
||||
$context = $this->page->context;
|
||||
$menu = new action_menu();
|
||||
|
||||
$items = $this->page->navbar->get_items();
|
||||
$currentnode = end($items);
|
||||
|
||||
$showcoursemenu = false;
|
||||
$showfrontpagemenu = false;
|
||||
$showusermenu = false;
|
||||
|
||||
// We are on the course home page.
|
||||
if (($context->contextlevel == CONTEXT_COURSE) &&
|
||||
!empty($currentnode) &&
|
||||
($currentnode->type == navigation_node::TYPE_COURSE || $currentnode->type == navigation_node::TYPE_SECTION)) {
|
||||
$showcoursemenu = true;
|
||||
}
|
||||
|
||||
$courseformat = course_get_format($this->page->course);
|
||||
// This is a single activity course format, always show the course menu on the activity main page.
|
||||
if ($context->contextlevel == CONTEXT_MODULE &&
|
||||
!$courseformat->has_view_page()) {
|
||||
|
||||
$this->page->navigation->initialise();
|
||||
$activenode = $this->page->navigation->find_active_node();
|
||||
// If the settings menu has been forced then show the menu.
|
||||
if ($this->page->is_settings_menu_forced()) {
|
||||
$showcoursemenu = true;
|
||||
} else if (!empty($activenode) && ($activenode->type == navigation_node::TYPE_ACTIVITY ||
|
||||
$activenode->type == navigation_node::TYPE_RESOURCE)) {
|
||||
|
||||
// We only want to show the menu on the first page of the activity. This means
|
||||
// the breadcrumb has no additional nodes.
|
||||
if ($currentnode && ($currentnode->key == $activenode->key && $currentnode->type == $activenode->type)) {
|
||||
$showcoursemenu = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is the site front page.
|
||||
if ($context->contextlevel == CONTEXT_COURSE &&
|
||||
!empty($currentnode) &&
|
||||
$currentnode->key === 'home') {
|
||||
$showfrontpagemenu = true;
|
||||
}
|
||||
|
||||
// This is the user profile page.
|
||||
if ($context->contextlevel == CONTEXT_USER &&
|
||||
!empty($currentnode) &&
|
||||
($currentnode->key === 'myprofile')) {
|
||||
$showusermenu = true;
|
||||
}
|
||||
|
||||
if ($showfrontpagemenu) {
|
||||
$settingsnode = $this->page->settingsnav->find('frontpage', navigation_node::TYPE_SETTING);
|
||||
if ($settingsnode) {
|
||||
// Build an action menu based on the visible nodes from this navigation tree.
|
||||
$skipped = $this->build_action_menu_from_navigation($menu, $settingsnode, false, true);
|
||||
|
||||
// We only add a list to the full settings menu if we didn't include every node in the short menu.
|
||||
if ($skipped) {
|
||||
$text = get_string('morenavigationlinks');
|
||||
$url = new moodle_url('/course/admin.php', array('courseid' => $this->page->course->id));
|
||||
$link = new action_link($url, $text, null, null, new pix_icon('t/edit', ''));
|
||||
$menu->add_secondary_action($link);
|
||||
}
|
||||
}
|
||||
} else if ($showcoursemenu) {
|
||||
$settingsnode = $this->page->settingsnav->find('courseadmin', navigation_node::TYPE_COURSE);
|
||||
if ($settingsnode) {
|
||||
// Build an action menu based on the visible nodes from this navigation tree.
|
||||
$skipped = $this->build_action_menu_from_navigation($menu, $settingsnode, false, true);
|
||||
|
||||
// We only add a list to the full settings menu if we didn't include every node in the short menu.
|
||||
if ($skipped) {
|
||||
$text = get_string('morenavigationlinks');
|
||||
$url = new moodle_url('/course/admin.php', array('courseid' => $this->page->course->id));
|
||||
$link = new action_link($url, $text, null, null, new pix_icon('t/edit', ''));
|
||||
$menu->add_secondary_action($link);
|
||||
}
|
||||
}
|
||||
} else if ($showusermenu) {
|
||||
// Get the course admin node from the settings navigation.
|
||||
$settingsnode = $this->page->settingsnav->find('useraccount', navigation_node::TYPE_CONTAINER);
|
||||
if ($settingsnode) {
|
||||
// Build an action menu based on the visible nodes from this navigation tree.
|
||||
$this->build_action_menu_from_navigation($menu, $settingsnode);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->render($menu);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an optional menu that can be added to a layout by a theme. It contains the
|
||||
* menu for the most specific thing from the settings block. E.g. Module administration.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function region_main_settings_menu() {
|
||||
$context = $this->page->context;
|
||||
$menu = new action_menu();
|
||||
|
||||
if ($context->contextlevel == CONTEXT_MODULE) {
|
||||
|
||||
$this->page->navigation->initialise();
|
||||
$node = $this->page->navigation->find_active_node();
|
||||
$buildmenu = false;
|
||||
// If the settings menu has been forced then show the menu.
|
||||
if ($this->page->is_settings_menu_forced()) {
|
||||
$buildmenu = true;
|
||||
} else if (!empty($node) && ($node->type == navigation_node::TYPE_ACTIVITY ||
|
||||
$node->type == navigation_node::TYPE_RESOURCE)) {
|
||||
|
||||
$items = $this->page->navbar->get_items();
|
||||
$navbarnode = end($items);
|
||||
// We only want to show the menu on the first page of the activity. This means
|
||||
// the breadcrumb has no additional nodes.
|
||||
if ($navbarnode && ($navbarnode->key === $node->key && $navbarnode->type == $node->type)) {
|
||||
$buildmenu = true;
|
||||
}
|
||||
}
|
||||
if ($buildmenu) {
|
||||
// Get the course admin node from the settings navigation.
|
||||
$node = $this->page->settingsnav->find('modulesettings', navigation_node::TYPE_SETTING);
|
||||
if ($node) {
|
||||
// Build an action menu based on the visible nodes from this navigation tree.
|
||||
$this->build_action_menu_from_navigation($menu, $node);
|
||||
}
|
||||
}
|
||||
|
||||
} else if ($context->contextlevel == CONTEXT_COURSECAT) {
|
||||
// For course category context, show category settings menu, if we're on the course category page.
|
||||
if ($this->page->pagetype === 'course-index-category') {
|
||||
$node = $this->page->settingsnav->find('categorysettings', navigation_node::TYPE_CONTAINER);
|
||||
if ($node) {
|
||||
// Build an action menu based on the visible nodes from this navigation tree.
|
||||
$this->build_action_menu_from_navigation($menu, $node);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
$items = $this->page->navbar->get_items();
|
||||
$navbarnode = end($items);
|
||||
|
||||
if ($navbarnode && ($navbarnode->key === 'participants')) {
|
||||
$node = $this->page->settingsnav->find('users', navigation_node::TYPE_CONTAINER);
|
||||
if ($node) {
|
||||
// Build an action menu based on the visible nodes from this navigation tree.
|
||||
$this->build_action_menu_from_navigation($menu, $node);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return $this->render($menu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a node in the nav tree and make an action menu out of it.
|
||||
* The links are injected in the action menu.
|
||||
*
|
||||
* @param action_menu $menu
|
||||
* @param navigation_node $node
|
||||
* @param boolean $indent
|
||||
* @param boolean $onlytopleafnodes
|
||||
* @return boolean nodesskipped - True if nodes were skipped in building the menu
|
||||
*/
|
||||
protected function build_action_menu_from_navigation(action_menu $menu,
|
||||
navigation_node $node,
|
||||
$indent = false,
|
||||
$onlytopleafnodes = false) {
|
||||
$skipped = false;
|
||||
// Build an action menu based on the visible nodes from this navigation tree.
|
||||
foreach ($node->children as $menuitem) {
|
||||
if ($menuitem->display) {
|
||||
if ($onlytopleafnodes && $menuitem->children->count()) {
|
||||
$skipped = true;
|
||||
continue;
|
||||
}
|
||||
if ($menuitem->action) {
|
||||
if ($menuitem->action instanceof action_link) {
|
||||
$link = $menuitem->action;
|
||||
// Give preference to setting icon over action icon.
|
||||
if (!empty($menuitem->icon)) {
|
||||
$link->icon = $menuitem->icon;
|
||||
}
|
||||
} else {
|
||||
$link = new action_link($menuitem->action, $menuitem->text, null, null, $menuitem->icon);
|
||||
}
|
||||
} else {
|
||||
if ($onlytopleafnodes) {
|
||||
$skipped = true;
|
||||
continue;
|
||||
}
|
||||
$link = new action_link(new moodle_url('#'), $menuitem->text, null, ['disabled' => true], $menuitem->icon);
|
||||
}
|
||||
if ($indent) {
|
||||
$link->add_class('ml-4');
|
||||
}
|
||||
if (!empty($menuitem->classes)) {
|
||||
$link->add_class(implode(" ", $menuitem->classes));
|
||||
}
|
||||
|
||||
$menu->add_secondary_action($link);
|
||||
$skipped = $skipped || $this->build_action_menu_from_navigation($menu, $menuitem, true);
|
||||
}
|
||||
}
|
||||
return $skipped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure login info.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function secure_login_info() {
|
||||
return $this->login_info(false);
|
||||
}
|
||||
}
|
||||
}
|
@ -39,13 +39,13 @@ use moodle_url;
|
||||
class block_settings_renderer extends \block_settings_renderer {
|
||||
|
||||
public function search_form(moodle_url $formtarget, $searchvalue) {
|
||||
$content = html_writer::start_tag('form', array('class'=>'adminsearchform', 'method'=>'get', 'action'=>$formtarget, 'role' => 'search'));
|
||||
$content .= html_writer::start_tag('div');
|
||||
$content .= html_writer::tag('label', s(get_string('searchinsettings', 'admin')), array('for'=>'adminsearchquery', 'class'=>'accesshide'));
|
||||
$content .= html_writer::empty_tag('input', array('id'=>'adminsearchquery', 'type'=>'text', 'name'=>'query', 'value'=>s($searchvalue)));
|
||||
$content .= html_writer::empty_tag('input', array('type'=>'submit', 'value'=>s(get_string('search'))));
|
||||
$content .= html_writer::end_tag('div');
|
||||
$content .= html_writer::end_tag('form');
|
||||
$content = \html_writer::start_tag('form', array('class'=>'adminsearchform', 'method'=>'get', 'action'=>$formtarget, 'role' => 'search'));
|
||||
$content .= \html_writer::start_tag('div');
|
||||
$content .= \html_writer::tag('label', s(get_string('searchinsettings', 'admin')), array('for'=>'adminsearchquery', 'class'=>'accesshide'));
|
||||
$content .= \html_writer::empty_tag('input', array('id'=>'adminsearchquery', 'type'=>'text', 'name'=>'query', 'value'=>s($searchvalue)));
|
||||
$content .= \html_writer::empty_tag('input', array('type'=>'submit', 'value'=>s(get_string('search'))));
|
||||
$content .= \html_writer::end_tag('div');
|
||||
$content .= \html_writer::end_tag('form');
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
@ -71,18 +71,18 @@ class course_renderer extends \core_course_renderer {
|
||||
$strsearchcourses= get_string("searchcourses");
|
||||
$searchurl = new moodle_url('/course/search.php');
|
||||
|
||||
$output = html_writer::start_tag('form', array('id' => $formid, 'action' => $searchurl, 'method' => 'get'));
|
||||
$output .= html_writer::start_tag('fieldset', array('class' => 'coursesearchbox invisiblefieldset'));
|
||||
$output .= html_writer::tag('label', $strsearchcourses.': ', array('for' => $inputid));
|
||||
$output .= html_writer::empty_tag('input', array('type' => 'text', 'id' => $inputid,
|
||||
$output = \html_writer::start_tag('form', array('id' => $formid, 'action' => $searchurl, 'method' => 'get'));
|
||||
$output .= \html_writer::start_tag('fieldset', array('class' => 'coursesearchbox invisiblefieldset'));
|
||||
$output .= \html_writer::tag('label', $strsearchcourses.': ', array('for' => $inputid));
|
||||
$output .= \html_writer::empty_tag('input', array('type' => 'text', 'id' => $inputid,
|
||||
'size' => $inputsize, 'name' => 'search', 'value' => s($value)));
|
||||
$output .= html_writer::empty_tag('input', array('type' => 'submit',
|
||||
$output .= \html_writer::empty_tag('input', array('type' => 'submit',
|
||||
'value' => get_string('go')));
|
||||
$output .= html_writer::end_tag('fieldset');
|
||||
$output .= \html_writer::end_tag('fieldset');
|
||||
if ($format != 'navbar') {
|
||||
$output .= $this->output->help_icon("coursesearch", "core");
|
||||
}
|
||||
$output .= html_writer::end_tag('form');
|
||||
$output .= \html_writer::end_tag('form');
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
@ -417,11 +417,11 @@ class files_renderer extends \core_files_renderer {
|
||||
* Default contents is one text input field with name="s"
|
||||
*/
|
||||
public function repository_default_searchform() {
|
||||
$searchinput = html_writer::label(get_string('searchrepo', 'repository'),
|
||||
$searchinput = \html_writer::label(get_string('searchrepo', 'repository'),
|
||||
'reposearch', false, array('class' => 'accesshide'));
|
||||
$searchinput .= html_writer::empty_tag('input', array('type' => 'text',
|
||||
$searchinput .= \html_writer::empty_tag('input', array('type' => 'text',
|
||||
'id' => 'reposearch', 'name' => 's', 'value' => get_string('search', 'repository')));
|
||||
$str = html_writer::tag('div', $searchinput, array('class' => "fp-def-search"));
|
||||
$str = \html_writer::tag('div', $searchinput, array('class' => "fp-def-search"));
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ class renderer extends \core_course_management_renderer {
|
||||
if (!is_null($id)) {
|
||||
$attributes['id'] = $id;
|
||||
}
|
||||
return html_writer::start_div($class, $attributes);
|
||||
return \html_writer::start_div($class, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,7 +112,7 @@ class renderer extends \core_course_management_renderer {
|
||||
if (!is_null($id)) {
|
||||
$attributes['id'] = $id;
|
||||
}
|
||||
return html_writer::start_div($class, $attributes);
|
||||
return \html_writer::start_div($class, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -125,13 +125,13 @@ class renderer extends \core_course_management_renderer {
|
||||
$details = \core_course\management\helper::get_course_detail_array($course);
|
||||
$fullname = $details['fullname']['value'];
|
||||
|
||||
$html = html_writer::start_div('course-detail');
|
||||
$html .= html_writer::tag('h3', $fullname, array('id' => 'course-detail-title', 'tabindex' => '0'));
|
||||
$html = \html_writer::start_div('course-detail');
|
||||
$html .= \html_writer::tag('h3', $fullname, array('id' => 'course-detail-title', 'tabindex' => '0'));
|
||||
$html .= $this->course_detail_actions($course);
|
||||
foreach ($details as $class => $data) {
|
||||
$html .= $this->detail_pair($data['key'], $data['value'], $class);
|
||||
}
|
||||
$html .= html_writer::end_div();
|
||||
$html .= \html_writer::end_div();
|
||||
return $html;
|
||||
}
|
||||
|
||||
@ -167,16 +167,16 @@ class renderer extends \core_course_management_renderer {
|
||||
$strsearchcourses = get_string("searchcourses");
|
||||
$searchurl = new moodle_url('/course/management.php');
|
||||
|
||||
$output = html_writer::start_tag('form', array('id' => $formid, 'action' => $searchurl, 'method' => 'get',
|
||||
$output = \html_writer::start_tag('form', array('id' => $formid, 'action' => $searchurl, 'method' => 'get',
|
||||
'class' => 'form-inline'));
|
||||
$output .= html_writer::start_tag('fieldset', array('class' => 'coursesearchbox invisiblefieldset m-y-1'));
|
||||
$output .= html_writer::tag('label', $strsearchcourses, array('for' => $inputid));
|
||||
$output .= html_writer::empty_tag('input', array('type' => 'text', 'id' => $inputid, 'size' => $inputsize,
|
||||
$output .= \html_writer::start_tag('fieldset', array('class' => 'coursesearchbox invisiblefieldset m-y-1'));
|
||||
$output .= \html_writer::tag('label', $strsearchcourses, array('for' => $inputid));
|
||||
$output .= \html_writer::empty_tag('input', array('type' => 'text', 'id' => $inputid, 'size' => $inputsize,
|
||||
'name' => 'search', 'value' => s($value), 'class' => 'form-control m-x-1'));
|
||||
$output .= html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('go'),
|
||||
$output .= \html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('go'),
|
||||
'class' => 'btn btn-secondary'));
|
||||
$output .= html_writer::end_tag('fieldset');
|
||||
$output .= html_writer::end_tag('form');
|
||||
$output .= \html_writer::end_tag('fieldset');
|
||||
$output .= \html_writer::end_tag('form');
|
||||
|
||||
return $output;
|
||||
}
|
||||
@ -209,10 +209,10 @@ class renderer extends \core_course_management_renderer {
|
||||
'aria-labelledby' => 'category-listing-title'
|
||||
);
|
||||
|
||||
$html = html_writer::start_div('category-listing');
|
||||
$html .= html_writer::tag('h3', get_string('categories'), array('id' => 'category-listing-title'));
|
||||
$html = \html_writer::start_div('category-listing');
|
||||
$html .= \html_writer::tag('h3', get_string('categories'), array('id' => 'category-listing-title'));
|
||||
$html .= $this->category_listing_actions($category);
|
||||
$html .= html_writer::start_tag('ul', $attributes);
|
||||
$html .= \html_writer::start_tag('ul', $attributes);
|
||||
foreach ($listing as $listitem) {
|
||||
// Render each category in the listing.
|
||||
$subcategories = array();
|
||||
@ -227,9 +227,9 @@ class renderer extends \core_course_management_renderer {
|
||||
$selectedparents
|
||||
);
|
||||
}
|
||||
$html .= html_writer::end_tag('ul');
|
||||
$html .= \html_writer::end_tag('ul');
|
||||
$html .= $this->category_bulk_actions($category);
|
||||
$html .= html_writer::end_div();
|
||||
$html .= \html_writer::end_div();
|
||||
return $html;
|
||||
}
|
||||
|
||||
@ -286,7 +286,7 @@ class renderer extends \core_course_management_renderer {
|
||||
$viewcaturl = new moodle_url('/course/management.php', array('categoryid' => $category->id));
|
||||
if ($isexpanded) {
|
||||
$icon = $this->output->pix_icon('t/switch_minus', get_string('collapse'), 'moodle', array('class' => 'tree-icon', 'title' => ''));
|
||||
$icon = html_writer::link(
|
||||
$icon = \html_writer::link(
|
||||
$viewcaturl,
|
||||
$icon,
|
||||
array(
|
||||
@ -298,7 +298,7 @@ class renderer extends \core_course_management_renderer {
|
||||
);
|
||||
} else if ($isexpandable) {
|
||||
$icon = $this->output->pix_icon('t/switch_plus', get_string('expand'), 'moodle', array('class' => 'tree-icon', 'title' => ''));
|
||||
$icon = html_writer::link(
|
||||
$icon = \html_writer::link(
|
||||
$viewcaturl,
|
||||
$icon,
|
||||
array(
|
||||
@ -313,16 +313,16 @@ class renderer extends \core_course_management_renderer {
|
||||
'',
|
||||
'moodle',
|
||||
array('class' => 'tree-icon'));
|
||||
$icon = html_writer::span($icon, 'float-left');
|
||||
$icon = \html_writer::span($icon, 'float-left');
|
||||
}
|
||||
$actions = \core_course\management\helper::get_category_listitem_actions($category);
|
||||
$hasactions = !empty($actions) || $category->can_create_course();
|
||||
|
||||
$html = html_writer::start_tag('li', $attributes);
|
||||
$html .= html_writer::start_div('clearfix');
|
||||
$html .= html_writer::start_div('float-left ba-checkbox');
|
||||
$html .= html_writer::empty_tag('input', $bcatinput).' ';
|
||||
$html .= html_writer::end_div();
|
||||
$html = \html_writer::start_tag('li', $attributes);
|
||||
$html .= \html_writer::start_div('clearfix');
|
||||
$html .= \html_writer::start_div('float-left ba-checkbox');
|
||||
$html .= \html_writer::empty_tag('input', $bcatinput).' ';
|
||||
$html .= \html_writer::end_div();
|
||||
$html .= $icon;
|
||||
if ($hasactions) {
|
||||
$textattributes = array('class' => 'float-left categoryname');
|
||||
@ -332,26 +332,26 @@ class renderer extends \core_course_management_renderer {
|
||||
if (isset($textlabel)) {
|
||||
$textattributes['aria-label'] = $textlabel;
|
||||
}
|
||||
$html .= html_writer::link($viewcaturl, $text, $textattributes);
|
||||
$html .= html_writer::start_div('float-right');
|
||||
$html .= \html_writer::link($viewcaturl, $text, $textattributes);
|
||||
$html .= \html_writer::start_div('float-right');
|
||||
if ($category->idnumber) {
|
||||
$html .= html_writer::tag('span', s($category->idnumber), array('class' => 'dimmed idnumber'));
|
||||
$html .= \html_writer::tag('span', s($category->idnumber), array('class' => 'dimmed idnumber'));
|
||||
}
|
||||
if ($hasactions) {
|
||||
$html .= $this->category_listitem_actions($category, $actions);
|
||||
}
|
||||
$countid = 'course-count-'.$category->id;
|
||||
$html .= html_writer::span(
|
||||
html_writer::span($category->get_courses_count()) .
|
||||
html_writer::span(get_string('courses'), 'accesshide', array('id' => $countid)) .
|
||||
$html .= \html_writer::span(
|
||||
\html_writer::span($category->get_courses_count()) .
|
||||
\html_writer::span(get_string('courses'), 'accesshide', array('id' => $countid)) .
|
||||
$courseicon,
|
||||
'course-count dimmed',
|
||||
array('aria-labelledby' => $countid)
|
||||
);
|
||||
$html .= html_writer::end_div();
|
||||
$html .= html_writer::end_div();
|
||||
$html .= \html_writer::end_div();
|
||||
$html .= \html_writer::end_div();
|
||||
if ($isexpanded) {
|
||||
$html .= html_writer::start_tag('ul',
|
||||
$html .= \html_writer::start_tag('ul',
|
||||
array('class' => 'ml', 'role' => 'group', 'id' => 'subcategoryof'.$category->id));
|
||||
$catatlevel = \core_course\management\helper::get_expanded_categories($category->path);
|
||||
$catatlevel[] = array_shift($selectedcategories);
|
||||
@ -366,9 +366,9 @@ class renderer extends \core_course_management_renderer {
|
||||
$selectedcategories
|
||||
);
|
||||
}
|
||||
$html .= html_writer::end_tag('ul');
|
||||
$html .= \html_writer::end_tag('ul');
|
||||
}
|
||||
$html .= html_writer::end_tag('li');
|
||||
$html .= \html_writer::end_tag('li');
|
||||
return $html;
|
||||
}
|
||||
|
||||
@ -392,15 +392,15 @@ class renderer extends \core_course_management_renderer {
|
||||
|
||||
if ($cancreatecategory) {
|
||||
$url = new moodle_url('/course/editcategory.php', array('parent' => $category->id));
|
||||
$actions[] = html_writer::link($url, get_string('createnewcategory'));
|
||||
$actions[] = \html_writer::link($url, get_string('createnewcategory'));
|
||||
}
|
||||
if (core_course_category::can_approve_course_requests()) {
|
||||
$actions[] = html_writer::link(new moodle_url('/course/pending.php'), get_string('coursespending'));
|
||||
$actions[] = \html_writer::link(new moodle_url('/course/pending.php'), get_string('coursespending'));
|
||||
}
|
||||
if (count($actions) === 0) {
|
||||
return '';
|
||||
}
|
||||
return html_writer::div(join(' | ', $actions), 'listing-actions category-listing-actions');
|
||||
return \html_writer::div(join(' | ', $actions), 'listing-actions category-listing-actions');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -418,11 +418,11 @@ class renderer extends \core_course_management_renderer {
|
||||
$viewmode = 'default') {
|
||||
|
||||
if ($category === null) {
|
||||
$html = html_writer::start_div('select-a-category');
|
||||
$html .= html_writer::tag('h3', get_string('courses'),
|
||||
$html = \html_writer::start_div('select-a-category');
|
||||
$html .= \html_writer::tag('h3', get_string('courses'),
|
||||
array('id' => 'course-listing-title', 'tabindex' => '0'));
|
||||
$html .= $this->output->notification(get_string('selectacategory'), 'notifymessage');
|
||||
$html .= html_writer::end_div();
|
||||
$html .= \html_writer::end_div();
|
||||
return $html;
|
||||
}
|
||||
|
||||
@ -446,25 +446,25 @@ class renderer extends \core_course_management_renderer {
|
||||
$class .= ' lastpage';
|
||||
}
|
||||
|
||||
$html = html_writer::start_div('course-listing'.$class, array(
|
||||
$html = \html_writer::start_div('course-listing'.$class, array(
|
||||
'data-category' => $category->id,
|
||||
'data-page' => $page,
|
||||
'data-totalpages' => $totalpages,
|
||||
'data-totalcourses' => $totalcourses,
|
||||
'data-canmoveoutof' => $category->can_move_courses_out_of() && $category->can_move_courses_into()
|
||||
));
|
||||
$html .= html_writer::tag('h3', $category->get_formatted_name(),
|
||||
$html .= \html_writer::tag('h3', $category->get_formatted_name(),
|
||||
array('id' => 'course-listing-title', 'tabindex' => '0'));
|
||||
$html .= $this->course_listing_actions($category, $course, $perpage);
|
||||
$html .= $this->listing_pagination($category, $page, $perpage, false, $viewmode);
|
||||
$html .= html_writer::start_tag('ul', array('class' => 'ml course-list', 'role' => 'group'));
|
||||
$html .= \html_writer::start_tag('ul', array('class' => 'ml course-list', 'role' => 'group'));
|
||||
foreach ($category->get_courses($options) as $listitem) {
|
||||
$html .= $this->course_listitem($category, $listitem, $courseid);
|
||||
}
|
||||
$html .= html_writer::end_tag('ul');
|
||||
$html .= \html_writer::end_tag('ul');
|
||||
$html .= $this->listing_pagination($category, $page, $perpage, true, $viewmode);
|
||||
$html .= $this->course_bulk_actions($category);
|
||||
$html .= html_writer::end_div();
|
||||
$html .= \html_writer::end_div();
|
||||
return $html;
|
||||
}
|
||||
|
||||
@ -503,26 +503,26 @@ class renderer extends \core_course_management_renderer {
|
||||
|
||||
$viewcourseurl = new moodle_url($this->page->url, array('courseid' => $course->id));
|
||||
|
||||
$html = html_writer::start_tag('li', $attributes);
|
||||
$html .= html_writer::start_div('clearfix');
|
||||
$html = \html_writer::start_tag('li', $attributes);
|
||||
$html .= \html_writer::start_div('clearfix');
|
||||
|
||||
if ($category->can_resort_courses()) {
|
||||
// In order for dnd to be available the user must be able to resort the category children..
|
||||
$html .= html_writer::div($this->output->pix_icon('i/move_2d', get_string('dndcourse')), 'float-left drag-handle');
|
||||
$html .= \html_writer::div($this->output->pix_icon('i/move_2d', get_string('dndcourse')), 'float-left drag-handle');
|
||||
}
|
||||
|
||||
$html .= html_writer::start_div('ba-checkbox float-left');
|
||||
$html .= html_writer::empty_tag('input', $bulkcourseinput).' ';
|
||||
$html .= html_writer::end_div();
|
||||
$html .= html_writer::link($viewcourseurl, $text, array('class' => 'float-left coursename'));
|
||||
$html .= html_writer::start_div('float-right');
|
||||
$html .= \html_writer::start_div('ba-checkbox float-left');
|
||||
$html .= \html_writer::empty_tag('input', $bulkcourseinput).' ';
|
||||
$html .= \html_writer::end_div();
|
||||
$html .= \html_writer::link($viewcourseurl, $text, array('class' => 'float-left coursename'));
|
||||
$html .= \html_writer::start_div('float-right');
|
||||
if ($course->idnumber) {
|
||||
$html .= html_writer::tag('span', s($course->idnumber), array('class' => 'dimmed idnumber'));
|
||||
$html .= \html_writer::tag('span', s($course->idnumber), array('class' => 'dimmed idnumber'));
|
||||
}
|
||||
$html .= $this->course_listitem_actions($category, $course);
|
||||
$html .= html_writer::end_div();
|
||||
$html .= html_writer::end_div();
|
||||
$html .= html_writer::end_tag('li');
|
||||
$html .= \html_writer::end_div();
|
||||
$html .= \html_writer::end_div();
|
||||
$html .= \html_writer::end_tag('li');
|
||||
return $html;
|
||||
}
|
||||
|
||||
@ -540,12 +540,12 @@ class renderer extends \core_course_management_renderer {
|
||||
$actions = array();
|
||||
if ($category->can_create_course()) {
|
||||
$url = new moodle_url('/course/edit.php', array('category' => $category->id, 'returnto' => 'catmanage'));
|
||||
$actions[] = html_writer::link($url, get_string('createnewcourse'));
|
||||
$actions[] = \html_writer::link($url, get_string('createnewcourse'));
|
||||
}
|
||||
if ($category->can_request_course()) {
|
||||
// Request a new course.
|
||||
$url = new moodle_url('/course/request.php', array('return' => 'management'));
|
||||
$actions[] = html_writer::link($url, get_string('requestcourse'));
|
||||
$actions[] = \html_writer::link($url, get_string('requestcourse'));
|
||||
}
|
||||
if ($category->can_resort_courses()) {
|
||||
$params = $this->page->url->params();
|
||||
@ -604,7 +604,7 @@ class renderer extends \core_course_management_renderer {
|
||||
$menu->attributes['class'] .= ' courses-per-page';
|
||||
$menu->set_menu_trigger(get_string('perpagea', 'moodle', $perpage));
|
||||
$actions[] = $this->render($menu);
|
||||
return html_writer::div(join(' | ', $actions), 'listing-actions course-listing-actions');
|
||||
return \html_writer::div(join(' | ', $actions), 'listing-actions course-listing-actions');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -631,15 +631,15 @@ class renderer extends \core_course_management_renderer {
|
||||
$last = false;
|
||||
$i = $page * $perpage;
|
||||
|
||||
$html = html_writer::start_div('course-listing', array(
|
||||
$html = \html_writer::start_div('course-listing', array(
|
||||
'data-category' => 'search',
|
||||
'data-page' => $page,
|
||||
'data-totalpages' => $totalpages,
|
||||
'data-totalcourses' => $totalcourses
|
||||
));
|
||||
$html .= html_writer::tag('h3', get_string('courses'));
|
||||
$html .= \html_writer::tag('h3', get_string('courses'));
|
||||
$html .= $this->search_pagination($totalcourses, $page, $perpage);
|
||||
$html .= html_writer::start_tag('ul', array('class' => 'ml'));
|
||||
$html .= \html_writer::start_tag('ul', array('class' => 'ml'));
|
||||
foreach ($courses as $listitem) {
|
||||
$i++;
|
||||
if ($i == $totalcourses) {
|
||||
@ -648,10 +648,10 @@ class renderer extends \core_course_management_renderer {
|
||||
$html .= $this->search_listitem($listitem, $courseid, $first, $last);
|
||||
$first = false;
|
||||
}
|
||||
$html .= html_writer::end_tag('ul');
|
||||
$html .= \html_writer::end_tag('ul');
|
||||
$html .= $this->search_pagination($totalcourses, $page, $perpage, true, $search);
|
||||
$html .= $this->course_search_bulk_actions();
|
||||
$html .= html_writer::end_div();
|
||||
$html .= \html_writer::end_div();
|
||||
return $html;
|
||||
}
|
||||
|
||||
@ -687,21 +687,21 @@ class renderer extends \core_course_management_renderer {
|
||||
$viewcourseurl = new moodle_url($this->page->url, array('courseid' => $course->id));
|
||||
$categoryname = core_course_category::get($course->category)->get_formatted_name();
|
||||
|
||||
$html = html_writer::start_tag('li', $attributes);
|
||||
$html .= html_writer::start_div('clearfix');
|
||||
$html .= html_writer::start_div('float-left');
|
||||
$html = \html_writer::start_tag('li', $attributes);
|
||||
$html .= \html_writer::start_div('clearfix');
|
||||
$html .= \html_writer::start_div('float-left');
|
||||
if ($bulkcourseinput) {
|
||||
$html .= html_writer::empty_tag('input', $bulkcourseinput).' ';
|
||||
$html .= \html_writer::empty_tag('input', $bulkcourseinput).' ';
|
||||
}
|
||||
$html .= html_writer::end_div();
|
||||
$html .= html_writer::link($viewcourseurl, $text, array('class' => 'float-left coursename'));
|
||||
$html .= html_writer::tag('span', $categoryname, array('class' => 'float-left categoryname'));
|
||||
$html .= html_writer::start_div('float-right');
|
||||
$html .= \html_writer::end_div();
|
||||
$html .= \html_writer::link($viewcourseurl, $text, array('class' => 'float-left coursename'));
|
||||
$html .= \html_writer::tag('span', $categoryname, array('class' => 'float-left categoryname'));
|
||||
$html .= \html_writer::start_div('float-right');
|
||||
$html .= $this->search_listitem_actions($course);
|
||||
$html .= html_writer::tag('span', s($course->idnumber), array('class' => 'dimmed idnumber'));
|
||||
$html .= html_writer::end_div();
|
||||
$html .= html_writer::end_div();
|
||||
$html .= html_writer::end_tag('li');
|
||||
$html .= \html_writer::tag('span', s($course->idnumber), array('class' => 'dimmed idnumber'));
|
||||
$html .= \html_writer::end_div();
|
||||
$html .= \html_writer::end_div();
|
||||
$html .= \html_writer::end_tag('li');
|
||||
return $html;
|
||||
}
|
||||
|
||||
@ -714,10 +714,10 @@ class renderer extends \core_course_management_renderer {
|
||||
* @return string
|
||||
*/
|
||||
protected function detail_pair($key, $value, $class ='') {
|
||||
$html = html_writer::start_div('detail-pair row yui3-g '.preg_replace('#[^a-zA-Z0-9_\-]#', '-', $class));
|
||||
$html .= html_writer::div(html_writer::span($key), 'pair-key span3 col-md-3 yui3-u-1-4');
|
||||
$html .= html_writer::div(html_writer::span($value), 'pair-value span9 col-md-9 m-b-1 yui3-u-3-4 form-inline');
|
||||
$html .= html_writer::end_div();
|
||||
$html = \html_writer::start_div('detail-pair row yui3-g '.preg_replace('#[^a-zA-Z0-9_\-]#', '-', $class));
|
||||
$html .= \html_writer::div(html_writer::span($key), 'pair-key span3 col-md-3 yui3-u-1-4');
|
||||
$html .= \html_writer::div(html_writer::span($value), 'pair-value span9 col-md-9 m-b-1 yui3-u-3-4 form-inline');
|
||||
$html .= \html_writer::end_div();
|
||||
return $html;
|
||||
}
|
||||
|
||||
@ -736,7 +736,7 @@ class renderer extends \core_course_management_renderer {
|
||||
foreach ($actions as $action) {
|
||||
$options[] = $this->action_link($action['url'], $action['string']);
|
||||
}
|
||||
return html_writer::div(join(' | ', $options), 'listing-actions course-detail-listing-actions');
|
||||
return \html_writer::div(join(' | ', $options), 'listing-actions course-detail-listing-actions');
|
||||
}
|
||||
|
||||
}
|
||||
|
470
theme/bootstrapbase/classes/output/core_renderer.php
Normal file
470
theme/bootstrapbase/classes/output/core_renderer.php
Normal file
@ -0,0 +1,470 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace theme_bootstrapbase\output;
|
||||
|
||||
use coding_exception;
|
||||
use \html_writer;
|
||||
use tabobject;
|
||||
use tabtree;
|
||||
use custom_menu_item;
|
||||
use custom_menu;
|
||||
use block_contents;
|
||||
use navigation_node;
|
||||
use action_link;
|
||||
use stdClass;
|
||||
use moodle_url;
|
||||
use preferences_groups;
|
||||
use action_menu;
|
||||
use help_icon;
|
||||
use single_button;
|
||||
use context_course;
|
||||
use pix_icon;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
/**
|
||||
* Renderers to align Moodle's HTML with that expected by Bootstrap
|
||||
*
|
||||
* @package theme_bootstrapbase
|
||||
* @copyright 2012 Bas Brands, www.basbrands.nl
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
class core_renderer extends \core_renderer {
|
||||
|
||||
/**
|
||||
* Wrapper for header elements.
|
||||
*
|
||||
* @return string HTML to display the main header.
|
||||
*/
|
||||
public function full_header() {
|
||||
$html = \html_writer::start_tag('header', array('id' => 'page-header', 'class' => 'clearfix'));
|
||||
$html .= $this->context_header();
|
||||
$html .= \html_writer::start_div('clearfix', array('id' => 'page-navbar'));
|
||||
$html .= \html_writer::tag('div', $this->navbar(), array('class' => 'breadcrumb-nav'));
|
||||
$html .= \html_writer::div($this->page_heading_button(), 'breadcrumb-button');
|
||||
$html .= html_writer::end_div();
|
||||
$html .= html_writer::tag('div', $this->course_header(), array('id' => 'course-header'));
|
||||
$html .= html_writer::end_tag('header');
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the navbar content so that it can be echoed out by the layout
|
||||
*
|
||||
* @return string XHTML navbar
|
||||
*/
|
||||
public function navbar() {
|
||||
$items = $this->page->navbar->get_items();
|
||||
$itemcount = count($items);
|
||||
if ($itemcount === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$htmlblocks = array();
|
||||
// Iterate the navarray and display each node
|
||||
$separator = get_separator();
|
||||
for ($i=0;$i < $itemcount;$i++) {
|
||||
$item = $items[$i];
|
||||
$item->hideicon = true;
|
||||
if ($i===0) {
|
||||
$content = html_writer::tag('li', $this->render($item));
|
||||
} else {
|
||||
$content = html_writer::tag('li', $separator.$this->render($item));
|
||||
}
|
||||
$htmlblocks[] = $content;
|
||||
}
|
||||
|
||||
//accessibility: heading for navbar list (MDL-20446)
|
||||
$navbarcontent = html_writer::tag('span', get_string('pagepath'),
|
||||
array('class' => 'accesshide', 'id' => 'navbar-label'));
|
||||
$navbarcontent .= html_writer::tag('nav',
|
||||
html_writer::tag('ul', join('', $htmlblocks)),
|
||||
array('aria-labelledby' => 'navbar-label'));
|
||||
// XHTML
|
||||
return $navbarcontent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns HTML to display a "Turn editing on/off" button in a form.
|
||||
*
|
||||
* @param moodle_url $url The URL + params to send through when clicking the button
|
||||
* @return string HTML the button
|
||||
*/
|
||||
public function edit_button(moodle_url $url) {
|
||||
|
||||
$url->param('sesskey', sesskey());
|
||||
if ($this->page->user_is_editing()) {
|
||||
$url->param('edit', 'off');
|
||||
$editstring = get_string('turneditingoff');
|
||||
} else {
|
||||
$url->param('edit', 'on');
|
||||
$editstring = get_string('turneditingon');
|
||||
}
|
||||
|
||||
return $this->single_button($url, $editstring);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the compact logo URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_compact_logo_url($maxwidth = 100, $maxheight = 100) {
|
||||
return parent::get_compact_logo_url(null, 70);
|
||||
}
|
||||
|
||||
/*
|
||||
* Overriding the custom_menu function ensures the custom menu is
|
||||
* always shown, even if no menu items are configured in the global
|
||||
* theme settings page.
|
||||
*/
|
||||
public function custom_menu($custommenuitems = '') {
|
||||
global $CFG;
|
||||
if (empty($custommenuitems) && !empty($CFG->custommenuitems)) {
|
||||
$custommenuitems = $CFG->custommenuitems;
|
||||
}
|
||||
if (empty($custommenuitems)) {
|
||||
return '';
|
||||
}
|
||||
$custommenu = new custom_menu($custommenuitems, current_language());
|
||||
return $this->render($custommenu);
|
||||
}
|
||||
|
||||
/*
|
||||
* This renders the bootstrap top menu.
|
||||
*
|
||||
* This renderer is needed to enable the Bootstrap style navigation.
|
||||
*/
|
||||
protected function render_custom_menu(custom_menu $menu) {
|
||||
static $menucount = 0;
|
||||
// If the menu has no children return an empty string
|
||||
if (!$menu->has_children()) {
|
||||
return '';
|
||||
}
|
||||
// Increment the menu count. This is used for ID's that get worked with
|
||||
// in JavaScript as is essential
|
||||
$menucount++;
|
||||
// Initialise this custom menu (the custom menu object is contained in javascript-static
|
||||
$jscode = js_writer::function_call_with_Y('M.core_custom_menu.init', array('custom_menu_'.$menucount));
|
||||
$jscode = "(function(){{$jscode}})";
|
||||
$this->page->requires->yui_module('node-menunav', $jscode);
|
||||
// Build the root nodes as required by YUI
|
||||
$content = html_writer::start_tag('div', array('id'=>'custom_menu_'.$menucount, 'class'=>'yui3-menu yui3-menu-horizontal javascript-disabled custom-menu'));
|
||||
$content .= html_writer::start_tag('div', array('class'=>'yui3-menu-content'));
|
||||
$content .= html_writer::start_tag('ul');
|
||||
// Render each child
|
||||
foreach ($menu->get_children() as $item) {
|
||||
$content .= $this->render_custom_menu_item($item);
|
||||
}
|
||||
// Close the open tags
|
||||
$content .= html_writer::end_tag('ul');
|
||||
$content .= html_writer::end_tag('div');
|
||||
$content .= html_writer::end_tag('div');
|
||||
// Return the custom menu
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders tabtree
|
||||
*
|
||||
* @param tabtree $tabtree
|
||||
* @return string
|
||||
*/
|
||||
protected function render_tabtree(tabtree $tabtree) {
|
||||
if (empty($tabtree->subtree)) {
|
||||
return '';
|
||||
}
|
||||
$str = '';
|
||||
$str .= html_writer::start_tag('div', array('class' => 'tabtree'));
|
||||
$str .= $this->render_tabobject($tabtree);
|
||||
$str .= html_writer::end_tag('div').
|
||||
html_writer::tag('div', ' ', array('class' => 'clearer'));
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders tabobject (part of tabtree)
|
||||
*
|
||||
* This function is called from {@link core_renderer::render_tabtree()}
|
||||
* and also it calls itself when printing the $tabobject subtree recursively.
|
||||
*
|
||||
* @param tabobject $tabobject
|
||||
* @return string HTML fragment
|
||||
*/
|
||||
protected function render_tabobject(tabobject $tab) {
|
||||
throw new coding_exception('Tab objects should not be directly rendered.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a nice side block with an optional header.
|
||||
*
|
||||
* The content is described
|
||||
* by a {@link core_renderer::block_contents} object.
|
||||
*
|
||||
* <div id="inst{$instanceid}" class="block_{$blockname} block">
|
||||
* <div class="header"></div>
|
||||
* <div class="content">
|
||||
* ...CONTENT...
|
||||
* <div class="footer">
|
||||
* </div>
|
||||
* </div>
|
||||
* <div class="annotation">
|
||||
* </div>
|
||||
* </div>
|
||||
*
|
||||
* @param block_contents $bc HTML for the content
|
||||
* @param string $region the region the block is appearing in.
|
||||
* @return string the HTML to be output.
|
||||
*/
|
||||
public function block(block_contents $bc, $region) {
|
||||
$bc = clone($bc); // Avoid messing up the object passed in.
|
||||
if (empty($bc->blockinstanceid) || !strip_tags($bc->title)) {
|
||||
$bc->collapsible = block_contents::NOT_HIDEABLE;
|
||||
}
|
||||
if (!empty($bc->blockinstanceid)) {
|
||||
$bc->attributes['data-instanceid'] = $bc->blockinstanceid;
|
||||
}
|
||||
$skiptitle = strip_tags($bc->title);
|
||||
if ($bc->blockinstanceid && !empty($skiptitle)) {
|
||||
$bc->attributes['aria-labelledby'] = 'instance-'.$bc->blockinstanceid.'-header';
|
||||
} else if (!empty($bc->arialabel)) {
|
||||
$bc->attributes['aria-label'] = $bc->arialabel;
|
||||
}
|
||||
if ($bc->dockable) {
|
||||
$bc->attributes['data-dockable'] = 1;
|
||||
}
|
||||
if ($bc->collapsible == block_contents::HIDDEN) {
|
||||
$bc->add_class('hidden');
|
||||
}
|
||||
if (!empty($bc->controls)) {
|
||||
$bc->add_class('block_with_controls');
|
||||
}
|
||||
|
||||
|
||||
if (empty($skiptitle)) {
|
||||
$output = '';
|
||||
$skipdest = '';
|
||||
} else {
|
||||
$output = html_writer::link('#sb-'.$bc->skipid, get_string('skipa', 'access', $skiptitle),
|
||||
array('class' => 'skip skip-block', 'id' => 'fsb-' . $bc->skipid));
|
||||
$skipdest = html_writer::span('', 'skip-block-to',
|
||||
array('id' => 'sb-' . $bc->skipid));
|
||||
}
|
||||
|
||||
$output .= html_writer::start_tag('div', $bc->attributes);
|
||||
|
||||
$output .= $this->block_header($bc);
|
||||
$output .= $this->block_content($bc);
|
||||
|
||||
$output .= html_writer::end_tag('div');
|
||||
|
||||
$output .= $this->block_annotation($bc);
|
||||
|
||||
$output .= $skipdest;
|
||||
|
||||
$this->init_block_hider_js($bc);
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CSS classes to apply to the body tag.
|
||||
*
|
||||
* @since Moodle 2.5.1 2.6
|
||||
* @param array $additionalclasses Any additional classes to apply.
|
||||
* @return string
|
||||
*/
|
||||
public function body_css_classes(array $additionalclasses = array()) {
|
||||
// Add a class for each block region on the page.
|
||||
// We use the block manager here because the theme object makes get_string calls.
|
||||
$usedregions = array();
|
||||
foreach ($this->page->blocks->get_regions() as $region) {
|
||||
$additionalclasses[] = 'has-region-'.$region;
|
||||
if ($this->page->blocks->region_has_content($region, $this)) {
|
||||
$additionalclasses[] = 'used-region-'.$region;
|
||||
$usedregions[] = $region;
|
||||
} else {
|
||||
$additionalclasses[] = 'empty-region-'.$region;
|
||||
}
|
||||
if ($this->page->blocks->region_completely_docked($region, $this)) {
|
||||
$additionalclasses[] = 'docked-region-'.$region;
|
||||
}
|
||||
}
|
||||
if (!$usedregions) {
|
||||
// No regions means there is only content, add 'content-only' class.
|
||||
$additionalclasses[] = 'content-only';
|
||||
} else if (count($usedregions) === 1) {
|
||||
// Add the -only class for the only used region.
|
||||
$region = array_shift($usedregions);
|
||||
$additionalclasses[] = $region . '-only';
|
||||
}
|
||||
foreach ($this->page->layout_options as $option => $value) {
|
||||
if ($value) {
|
||||
$additionalclasses[] = 'layout-option-'.$option;
|
||||
}
|
||||
}
|
||||
$css = $this->page->bodyclasses .' '. join(' ', $additionalclasses);
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders preferences groups.
|
||||
*
|
||||
* @param preferences_groups $renderable The renderable
|
||||
* @return string The output.
|
||||
*/
|
||||
public function render_preferences_groups(preferences_groups $renderable) {
|
||||
$html = '';
|
||||
$html .= html_writer::start_div('row-fluid');
|
||||
$html .= html_writer::start_tag('div', array('class' => 'span12 preferences-groups'));
|
||||
$i = 0;
|
||||
$open = false;
|
||||
foreach ($renderable->groups as $group) {
|
||||
if ($i == 0 || $i % 3 == 0) {
|
||||
if ($open) {
|
||||
$html .= html_writer::end_tag('div');
|
||||
}
|
||||
$html .= html_writer::start_tag('div', array('class' => 'row-fluid'));
|
||||
$open = true;
|
||||
}
|
||||
$html .= $this->render($group);
|
||||
$i++;
|
||||
}
|
||||
|
||||
$html .= html_writer::end_tag('div');
|
||||
|
||||
$html .= html_writer::end_tag('ul');
|
||||
$html .= html_writer::end_tag('div');
|
||||
$html .= html_writer::end_div();
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an action menu component.
|
||||
*
|
||||
* ARIA references:
|
||||
* - http://www.w3.org/WAI/GL/wiki/Using_ARIA_menus
|
||||
* - http://stackoverflow.com/questions/12279113/recommended-wai-aria-implementation-for-navigation-bar-menu
|
||||
*
|
||||
* @param action_menu $menu
|
||||
* @return string HTML
|
||||
*/
|
||||
public function render_action_menu(action_menu $menu) {
|
||||
$context = $menu->export_for_template($this);
|
||||
return $this->render_from_template('core/action_menu', $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of user image rendering.
|
||||
*
|
||||
* @param help_icon $helpicon A help icon instance
|
||||
* @return string HTML fragment
|
||||
*/
|
||||
protected function render_help_icon(help_icon $helpicon) {
|
||||
return $this->render_from_template('core/help_icon', $helpicon->export_for_template($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a single button widget.
|
||||
*
|
||||
* This will return HTML to display a form containing a single button.
|
||||
*
|
||||
* @param single_button $button
|
||||
* @return string HTML fragment
|
||||
*/
|
||||
protected function render_single_button(single_button $button) {
|
||||
$attributes = array('type' => 'submit',
|
||||
'value' => $button->label,
|
||||
'disabled' => $button->disabled ? 'disabled' : null,
|
||||
'title' => $button->tooltip);
|
||||
|
||||
if ($button->actions) {
|
||||
$id = html_writer::random_id('single_button');
|
||||
$attributes['id'] = $id;
|
||||
foreach ($button->actions as $action) {
|
||||
$this->add_action_handler($action, $id);
|
||||
}
|
||||
}
|
||||
|
||||
// first the input element
|
||||
$output = html_writer::empty_tag('input', $attributes);
|
||||
|
||||
// then hidden fields
|
||||
$params = $button->url->params();
|
||||
if ($button->method === 'post') {
|
||||
$params['sesskey'] = sesskey();
|
||||
}
|
||||
foreach ($params as $var => $val) {
|
||||
$output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => $var, 'value' => $val));
|
||||
}
|
||||
|
||||
// then div wrapper for xhtml strictness
|
||||
$output = html_writer::tag('div', $output);
|
||||
|
||||
// now the form itself around it
|
||||
if ($button->method === 'get') {
|
||||
$url = $button->url->out_omit_querystring(true); // url without params, the anchor part allowed
|
||||
} else {
|
||||
$url = $button->url->out_omit_querystring(); // url without params, the anchor part not allowed
|
||||
}
|
||||
if ($url === '') {
|
||||
$url = '#'; // there has to be always some action
|
||||
}
|
||||
$attributes = array('method' => $button->method,
|
||||
'action' => $url,
|
||||
'id' => $button->formid);
|
||||
$output = html_writer::tag('form', $output, $attributes);
|
||||
|
||||
// and finally one more wrapper with class
|
||||
return html_writer::tag('div', $output, array('class' => $button->class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the login form.
|
||||
*
|
||||
* @param \core_auth\output\login $form The renderable.
|
||||
* @return string
|
||||
*/
|
||||
public function render_login(\core_auth\output\login $form) {
|
||||
global $CFG;
|
||||
|
||||
$context = $form->export_for_template($this);
|
||||
|
||||
// Override because rendering is not supported in template yet.
|
||||
if ($CFG->rememberusername == 0) {
|
||||
$context->cookieshelpiconformatted = $this->help_icon('cookiesenabledonlysession');
|
||||
} else {
|
||||
$context->cookieshelpiconformatted = $this->help_icon('cookiesenabled');
|
||||
}
|
||||
$context->errorformatted = $this->error_text($context->error);
|
||||
|
||||
return $this->render_from_template('core/loginform', $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the login signup form into a nice template for the theme.
|
||||
*
|
||||
* @param mform $form
|
||||
* @return string
|
||||
*/
|
||||
public function render_login_signup_form($form) {
|
||||
$context = $form->export_for_template($this);
|
||||
|
||||
return $this->render_from_template('core/signup_form_layout', $context);
|
||||
}
|
||||
|
||||
}
|
@ -22,5 +22,10 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once('renderers/core_renderer.php');
|
||||
|
||||
require_once($CFG->dirroot . '/theme/bootstrapbase/renderers/core_renderer.php');
|
||||
require_once($CFG->dirroot . '/theme/bootstrapbase/renderers/block_settings_renderer.php');
|
||||
require_once($CFG->dirroot . '/theme/bootstrapbase/renderers/gradereport_history_renderer.php');
|
||||
require_once($CFG->dirroot . '/theme/bootstrapbase/renderers/core/course_renderer.php');
|
||||
require_once($CFG->dirroot . '/theme/bootstrapbase/renderers/core/files_renderer.php');
|
||||
require_once($CFG->dirroot . '/theme/bootstrapbase/renderers/core_course/management/renderer.php');
|
||||
require_once($CFG->dirroot . '/theme/bootstrapbase/renderers/core_question/bank_renderer.php');
|
||||
|
@ -77,6 +77,30 @@ class theme_bootstrapbase_core_renderer extends core_renderer {
|
||||
$list_items . '</ul></nav>';
|
||||
}
|
||||
|
||||
/**
|
||||
* This code renders the navbar button to control the display of the custom menu
|
||||
* on smaller screens.
|
||||
*
|
||||
* Do not display the button if the menu is empty.
|
||||
*
|
||||
* @return string HTML fragment
|
||||
*/
|
||||
protected function navbar_button() {
|
||||
global $CFG;
|
||||
|
||||
if (empty($CFG->custommenuitems) && $this->lang_menu() == '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$iconbar = html_writer::tag('span', '', array('class' => 'icon-bar'));
|
||||
$button = html_writer::tag('a', $iconbar . "\n" . $iconbar. "\n" . $iconbar, array(
|
||||
'class' => 'btn btn-navbar',
|
||||
'data-toggle' => 'collapse',
|
||||
'data-target' => '.nav-collapse'
|
||||
));
|
||||
return $button;
|
||||
}
|
||||
|
||||
/*
|
||||
* Overriding the custom_menu function ensures the custom menu is
|
||||
* always shown, even if no menu items are configured in the global
|
||||
@ -187,30 +211,6 @@ class theme_bootstrapbase_core_renderer extends core_renderer {
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* This code renders the navbar button to control the display of the custom menu
|
||||
* on smaller screens.
|
||||
*
|
||||
* Do not display the button if the menu is empty.
|
||||
*
|
||||
* @return string HTML fragment
|
||||
*/
|
||||
protected function navbar_button() {
|
||||
global $CFG;
|
||||
|
||||
if (empty($CFG->custommenuitems) && $this->lang_menu() == '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$iconbar = html_writer::tag('span', '', array('class' => 'icon-bar'));
|
||||
$button = html_writer::tag('a', $iconbar . "\n" . $iconbar. "\n" . $iconbar, array(
|
||||
'class' => 'btn btn-navbar',
|
||||
'data-toggle' => 'collapse',
|
||||
'data-target' => '.nav-collapse'
|
||||
));
|
||||
return $button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders tabtree
|
||||
*
|
||||
@ -256,6 +256,340 @@ class theme_bootstrapbase_core_renderer extends core_renderer {
|
||||
return html_writer::tag('li', $link, $params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for header elements.
|
||||
*
|
||||
* @return string HTML to display the main header.
|
||||
*/
|
||||
public function full_header() {
|
||||
$html = html_writer::start_tag('header', array('id' => 'page-header', 'class' => 'clearfix'));
|
||||
$html .= $this->context_header();
|
||||
$html .= html_writer::start_div('clearfix', array('id' => 'page-navbar'));
|
||||
$html .= html_writer::tag('div', $this->navbar(), array('class' => 'breadcrumb-nav'));
|
||||
$html .= html_writer::div($this->page_heading_button(), 'breadcrumb-button');
|
||||
$html .= html_writer::end_div();
|
||||
$html .= html_writer::tag('div', $this->course_header(), array('id' => 'course-header'));
|
||||
$html .= html_writer::end_tag('header');
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the compact logo URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_compact_logo_url($maxwidth = 100, $maxheight = 100) {
|
||||
return parent::get_compact_logo_url(null, 70);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a nice side block with an optional header.
|
||||
*
|
||||
* The content is described
|
||||
* by a {@link core_renderer::block_contents} object.
|
||||
*
|
||||
* <div id="inst{$instanceid}" class="block_{$blockname} block">
|
||||
* <div class="header"></div>
|
||||
* <div class="content">
|
||||
* ...CONTENT...
|
||||
* <div class="footer">
|
||||
* </div>
|
||||
* </div>
|
||||
* <div class="annotation">
|
||||
* </div>
|
||||
* </div>
|
||||
*
|
||||
* @param block_contents $bc HTML for the content
|
||||
* @param string $region the region the block is appearing in.
|
||||
* @return string the HTML to be output.
|
||||
*/
|
||||
public function block(block_contents $bc, $region) {
|
||||
$bc = clone($bc); // Avoid messing up the object passed in.
|
||||
if (empty($bc->blockinstanceid) || !strip_tags($bc->title)) {
|
||||
$bc->collapsible = block_contents::NOT_HIDEABLE;
|
||||
}
|
||||
if (!empty($bc->blockinstanceid)) {
|
||||
$bc->attributes['data-instanceid'] = $bc->blockinstanceid;
|
||||
}
|
||||
$skiptitle = strip_tags($bc->title);
|
||||
if ($bc->blockinstanceid && !empty($skiptitle)) {
|
||||
$bc->attributes['aria-labelledby'] = 'instance-'.$bc->blockinstanceid.'-header';
|
||||
} else if (!empty($bc->arialabel)) {
|
||||
$bc->attributes['aria-label'] = $bc->arialabel;
|
||||
}
|
||||
if ($bc->dockable) {
|
||||
$bc->attributes['data-dockable'] = 1;
|
||||
}
|
||||
if ($bc->collapsible == block_contents::HIDDEN) {
|
||||
$bc->add_class('hidden');
|
||||
}
|
||||
if (!empty($bc->controls)) {
|
||||
$bc->add_class('block_with_controls');
|
||||
}
|
||||
|
||||
|
||||
if (empty($skiptitle)) {
|
||||
$output = '';
|
||||
$skipdest = '';
|
||||
} else {
|
||||
$output = html_writer::link('#sb-'.$bc->skipid, get_string('skipa', 'access', $skiptitle),
|
||||
array('class' => 'skip skip-block', 'id' => 'fsb-' . $bc->skipid));
|
||||
$skipdest = html_writer::span('', 'skip-block-to',
|
||||
array('id' => 'sb-' . $bc->skipid));
|
||||
}
|
||||
|
||||
$output .= html_writer::start_tag('div', $bc->attributes);
|
||||
|
||||
$output .= $this->block_header($bc);
|
||||
$output .= $this->block_content($bc);
|
||||
|
||||
$output .= html_writer::end_tag('div');
|
||||
|
||||
$output .= $this->block_annotation($bc);
|
||||
|
||||
$output .= $skipdest;
|
||||
|
||||
$this->init_block_hider_js($bc);
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a header for a block
|
||||
*
|
||||
* @param block_contents $bc
|
||||
* @return string
|
||||
*/
|
||||
protected function block_header(block_contents $bc) {
|
||||
|
||||
$title = '';
|
||||
if ($bc->title) {
|
||||
$attributes = array();
|
||||
if ($bc->blockinstanceid) {
|
||||
$attributes['id'] = 'instance-'.$bc->blockinstanceid.'-header';
|
||||
}
|
||||
$title = html_writer::tag('h2', $bc->title, $attributes);
|
||||
}
|
||||
|
||||
$blockid = null;
|
||||
if (isset($bc->attributes['id'])) {
|
||||
$blockid = $bc->attributes['id'];
|
||||
}
|
||||
$controlshtml = $this->block_controls($bc->controls, $blockid);
|
||||
|
||||
$output = '';
|
||||
if ($title || $controlshtml) {
|
||||
$output .= html_writer::tag('div', html_writer::tag('div', html_writer::tag('div', '', array('class'=>'block_action')). $title . $controlshtml, array('class' => 'title')), array('class' => 'header'));
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the content area for a block
|
||||
*
|
||||
* @param block_contents $bc
|
||||
* @return string
|
||||
*/
|
||||
protected function block_content(block_contents $bc) {
|
||||
$output = html_writer::start_tag('div', array('class' => 'content'));
|
||||
if (!$bc->title && !$this->block_controls($bc->controls)) {
|
||||
$output .= html_writer::tag('div', '', array('class'=>'block_action notitle'));
|
||||
}
|
||||
$output .= $bc->content;
|
||||
$output .= $this->block_footer($bc);
|
||||
$output .= html_writer::end_tag('div');
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the footer for a block
|
||||
*
|
||||
* @param block_contents $bc
|
||||
* @return string
|
||||
*/
|
||||
protected function block_footer(block_contents $bc) {
|
||||
$output = '';
|
||||
if ($bc->footer) {
|
||||
$output .= html_writer::tag('div', $bc->footer, array('class' => 'footer'));
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the annotation for a block
|
||||
*
|
||||
* @param block_contents $bc
|
||||
* @return string
|
||||
*/
|
||||
protected function block_annotation(block_contents $bc) {
|
||||
$output = '';
|
||||
if ($bc->annotation) {
|
||||
$output .= html_writer::tag('div', $bc->annotation, array('class' => 'blockannotation'));
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the JS require function to hide a block.
|
||||
*
|
||||
* @param block_contents $bc A block_contents object
|
||||
*/
|
||||
protected function init_block_hider_js(block_contents $bc) {
|
||||
if (!empty($bc->attributes['id']) and $bc->collapsible != block_contents::NOT_HIDEABLE) {
|
||||
$config = new stdClass;
|
||||
$config->id = $bc->attributes['id'];
|
||||
$config->title = strip_tags($bc->title);
|
||||
$config->preference = 'block' . $bc->blockinstanceid . 'hidden';
|
||||
$config->tooltipVisible = get_string('hideblocka', 'access', $config->title);
|
||||
$config->tooltipHidden = get_string('showblocka', 'access', $config->title);
|
||||
|
||||
$this->page->requires->js_init_call('M.util.init_block_hider', array($config));
|
||||
user_preference_allow_ajax_update($config->preference, PARAM_BOOL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CSS classes to apply to the body tag.
|
||||
*
|
||||
* @since Moodle 2.5.1 2.6
|
||||
* @param array $additionalclasses Any additional classes to apply.
|
||||
* @return string
|
||||
*/
|
||||
public function body_css_classes(array $additionalclasses = array()) {
|
||||
// Add a class for each block region on the page.
|
||||
// We use the block manager here because the theme object makes get_string calls.
|
||||
$usedregions = array();
|
||||
foreach ($this->page->blocks->get_regions() as $region) {
|
||||
$additionalclasses[] = 'has-region-'.$region;
|
||||
if ($this->page->blocks->region_has_content($region, $this)) {
|
||||
$additionalclasses[] = 'used-region-'.$region;
|
||||
$usedregions[] = $region;
|
||||
} else {
|
||||
$additionalclasses[] = 'empty-region-'.$region;
|
||||
}
|
||||
if ($this->page->blocks->region_completely_docked($region, $this)) {
|
||||
$additionalclasses[] = 'docked-region-'.$region;
|
||||
}
|
||||
}
|
||||
if (!$usedregions) {
|
||||
// No regions means there is only content, add 'content-only' class.
|
||||
$additionalclasses[] = 'content-only';
|
||||
} else if (count($usedregions) === 1) {
|
||||
// Add the -only class for the only used region.
|
||||
$region = array_shift($usedregions);
|
||||
$additionalclasses[] = $region . '-only';
|
||||
}
|
||||
foreach ($this->page->layout_options as $option => $value) {
|
||||
if ($value) {
|
||||
$additionalclasses[] = 'layout-option-'.$option;
|
||||
}
|
||||
}
|
||||
$css = $this->page->bodyclasses .' '. join(' ', $additionalclasses);
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders preferences groups.
|
||||
*
|
||||
* @param preferences_groups $renderable The renderable
|
||||
* @return string The output.
|
||||
*/
|
||||
public function render_preferences_groups(preferences_groups $renderable) {
|
||||
$html = '';
|
||||
$html .= html_writer::start_div('row-fluid');
|
||||
$html .= html_writer::start_tag('div', array('class' => 'span12 preferences-groups'));
|
||||
$i = 0;
|
||||
$open = false;
|
||||
foreach ($renderable->groups as $group) {
|
||||
if ($i == 0 || $i % 3 == 0) {
|
||||
if ($open) {
|
||||
$html .= html_writer::end_tag('div');
|
||||
}
|
||||
$html .= html_writer::start_tag('div', array('class' => 'row-fluid'));
|
||||
$open = true;
|
||||
}
|
||||
$html .= $this->render($group);
|
||||
$i++;
|
||||
}
|
||||
|
||||
$html .= html_writer::end_tag('div');
|
||||
|
||||
$html .= html_writer::end_tag('ul');
|
||||
$html .= html_writer::end_tag('div');
|
||||
$html .= html_writer::end_div();
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an action menu component.
|
||||
*
|
||||
* ARIA references:
|
||||
* - http://www.w3.org/WAI/GL/wiki/Using_ARIA_menus
|
||||
* - http://stackoverflow.com/questions/12279113/recommended-wai-aria-implementation-for-navigation-bar-menu
|
||||
*
|
||||
* @param action_menu $menu
|
||||
* @return string HTML
|
||||
*/
|
||||
public function render_action_menu(action_menu $menu) {
|
||||
$context = $menu->export_for_template($this);
|
||||
return $this->render_from_template('core/action_menu', $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a single button widget.
|
||||
*
|
||||
* This will return HTML to display a form containing a single button.
|
||||
*
|
||||
* @param single_button $button
|
||||
* @return string HTML fragment
|
||||
*/
|
||||
protected function render_single_button(single_button $button) {
|
||||
$attributes = array('type' => 'submit',
|
||||
'value' => $button->label,
|
||||
'disabled' => $button->disabled ? 'disabled' : null,
|
||||
'title' => $button->tooltip);
|
||||
|
||||
if ($button->actions) {
|
||||
$id = html_writer::random_id('single_button');
|
||||
$attributes['id'] = $id;
|
||||
foreach ($button->actions as $action) {
|
||||
$this->add_action_handler($action, $id);
|
||||
}
|
||||
}
|
||||
|
||||
// first the input element
|
||||
$output = html_writer::empty_tag('input', $attributes);
|
||||
|
||||
// then hidden fields
|
||||
$params = $button->url->params();
|
||||
if ($button->method === 'post') {
|
||||
$params['sesskey'] = sesskey();
|
||||
}
|
||||
foreach ($params as $var => $val) {
|
||||
$output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => $var, 'value' => $val));
|
||||
}
|
||||
|
||||
// then div wrapper for xhtml strictness
|
||||
$output = html_writer::tag('div', $output);
|
||||
|
||||
// now the form itself around it
|
||||
if ($button->method === 'get') {
|
||||
$url = $button->url->out_omit_querystring(true); // url without params, the anchor part allowed
|
||||
} else {
|
||||
$url = $button->url->out_omit_querystring(); // url without params, the anchor part not allowed
|
||||
}
|
||||
if ($url === '') {
|
||||
$url = '#'; // there has to be always some action
|
||||
}
|
||||
$attributes = array('method' => $button->method,
|
||||
'action' => $url,
|
||||
'id' => $button->formid);
|
||||
$output = html_writer::tag('form', $output, $attributes);
|
||||
|
||||
// and finally one more wrapper with class
|
||||
return html_writer::tag('div', $output, array('class' => $button->class));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -258,7 +258,7 @@ class behat_theme_bootstrapbase_behat_course extends behat_course {
|
||||
public function i_navigate_to_course_participants() {
|
||||
$coursestr = behat_context_helper::escape(get_string('courses'));
|
||||
$mycoursestr = behat_context_helper::escape(get_string('mycourses'));
|
||||
$xpath = "//div[contains(@class,'block')]//li[p/*[string(.)=$coursestr or string(.)=$mycoursestr]]";
|
||||
$xpath = "//section[contains(@class,'block')]//li[p/*[string(.)=$coursestr or string(.)=$mycoursestr]]";
|
||||
$this->execute('behat_general::i_click_on_in_the', [get_string('participants'), 'link', $xpath, 'xpath_element']);
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ class behat_theme_bootstrapbase_behat_navigation extends behat_navigation {
|
||||
public function should_exist_in_current_page_administration($element, $selectortype) {
|
||||
$parentnodes = array_map('trim', explode('>', $element));
|
||||
// Find the name of the first category of the administration block tree.
|
||||
$xpath = '//div[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span';
|
||||
$xpath = '//section[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span';
|
||||
$node = $this->find('xpath', $xpath);
|
||||
array_unshift($parentnodes, $node->getText());
|
||||
$lastnode = array_pop($parentnodes);
|
||||
@ -110,7 +110,7 @@ class behat_theme_bootstrapbase_behat_navigation extends behat_navigation {
|
||||
public function should_not_exist_in_current_page_administration($element, $selectortype) {
|
||||
$parentnodes = array_map('trim', explode('>', $element));
|
||||
// Find the name of the first category of the administration block tree.
|
||||
$xpath = '//div[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span';
|
||||
$xpath = '//section[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span';
|
||||
$node = $this->find('xpath', $xpath);
|
||||
array_unshift($parentnodes, $node->getText());
|
||||
$lastnode = array_pop($parentnodes);
|
||||
@ -124,7 +124,7 @@ class behat_theme_bootstrapbase_behat_navigation extends behat_navigation {
|
||||
public function i_navigate_to_in_current_page_administration($nodetext) {
|
||||
$parentnodes = array_map('trim', explode('>', $nodetext));
|
||||
// Find the name of the first category of the administration block tree.
|
||||
$xpath = '//div[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span';
|
||||
$xpath = '//section[contains(@class,\'block_settings\')]//div[@id=\'settingsnav\']/ul/li[1]/p[1]/span';
|
||||
$node = $this->find('xpath', $xpath);
|
||||
array_unshift($parentnodes, $node->getText());
|
||||
$lastnode = array_pop($parentnodes);
|
||||
|
Loading…
x
Reference in New Issue
Block a user