Skip to content

Commit

Permalink
MDL-81597 theme_boost: Fix header bar alignment
Browse files Browse the repository at this point in the history
- Refactot context_header class to implement named templatable so
render_context_header in core and theme_boost can be removed
- Refactor context_header to use templates
- Fix context header layout and styles
  • Loading branch information
roland04 committed May 28, 2024
1 parent e1d2a04 commit 78db6bb
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 167 deletions.
5 changes: 5 additions & 0 deletions .upgradenotes/MDL-81597-2024052802370704.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
issueNumber: MDL-81597
notes:
theme:
- message: New `core/contextheader` mustache template has been added. This template can be overridden by themes to modify the context header
type: improved
54 changes: 53 additions & 1 deletion lib/outputcomponents.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
*/

use core\output\local\action_menu\subpanel;
use core\output\named_templatable;

defined('MOODLE_INTERNAL') || die();

Expand Down Expand Up @@ -4109,7 +4110,7 @@ public function export_for_template(renderer_base $output) {
* @copyright 2015 Adrian Greeve <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class context_header implements renderable {
class context_header implements renderable, named_templatable {

/**
* @var string $heading Main heading.
Expand Down Expand Up @@ -4190,6 +4191,57 @@ protected function format_button_images() {
array('class' => $class));
}
}

/**
* Export for template.
*
* @param renderer_base $output Renderer.
* @return array
*/
public function export_for_template(renderer_base $output): array {
// Heading.
$headingtext = isset($this->heading) ? $this->heading : $output->get_page()->heading;
$heading = $output->heading($headingtext, $this->headinglevel, "h2 mb-0");

// Buttons.
if (isset($this->additionalbuttons)) {
$additionalbuttons = [];
foreach ($this->additionalbuttons as $button) {
if (!isset($button->page)) {
// Include js for messaging.
if ($button['buttontype'] === 'togglecontact') {
\core_message\helper::togglecontact_requirejs();
}
if ($button['buttontype'] === 'message') {
\core_message\helper::messageuser_requirejs();
}
}
foreach ($button['linkattributes'] as $key => $value) {
$button['attributes'][] = ['name' => $key, 'value' => $value];
}
$additionalbuttons[] = $button;
}
}

return [
'heading' => $heading,
'headinglevel' => $this->headinglevel,
'imagedata' => $this->imagedata,
'prefix' => $this->prefix,
'hasadditionalbuttons' => !empty($additionalbuttons),
'additionalbuttons' => $additionalbuttons ?? [],
];
}

/**
* Get the template name.
*
* @param renderer_base $renderer Renderer.
* @return string
*/
public function get_template_name(renderer_base $renderer): string {
return 'core/contextheader';
}
}

/**
Expand Down
74 changes: 5 additions & 69 deletions lib/outputrenderers.php
Original file line number Diff line number Diff line change
Expand Up @@ -4589,9 +4589,13 @@ public function context_header($headerinfo = null, $headinglevel = 1) {
}
}

// Return the heading wrapped in an sr-only element so it is only visible to screen-readers for nocontextheader layouts.
if (!empty($this->page->layout_options['nocontextheader'])) {
return html_writer::div($heading, 'sr-only');
}

$contextheader = new context_header($heading, $headinglevel, $imagedata, $userbuttons);
return $this->render_context_header($contextheader);
return $this->render($contextheader);
}

/**
Expand All @@ -4610,74 +4614,6 @@ public function render_skip_links($links) {
return $this->render_from_template('core/skip_links', $context);
}

/**
* Renders the header bar.
*
* @param context_header $contextheader Header bar object.
* @return string HTML for the header bar.
*/
protected function render_context_header(context_header $contextheader) {

// Generate the heading first and before everything else as we might have to do an early return.
if (!isset($contextheader->heading)) {
$heading = $this->heading($this->page->heading, $contextheader->headinglevel);
} else {
$heading = $this->heading($contextheader->heading, $contextheader->headinglevel);
}

$showheader = empty($this->page->layout_options['nocontextheader']);
if (!$showheader) {
// Return the heading wrapped in an sr-only element so it is only visible to screen-readers.
return html_writer::div($heading, 'sr-only');
}

// All the html stuff goes here.
$html = html_writer::start_div('page-context-header');

// Image data.
if (isset($contextheader->imagedata)) {
// Header specific image.
$html .= html_writer::div($contextheader->imagedata, 'page-header-image icon-size-7');
}

// Headings.
if (isset($contextheader->prefix)) {
$prefix = html_writer::div($contextheader->prefix, 'text-muted');
$heading = $prefix . $heading;
}
$html .= html_writer::tag('div', $heading, array('class' => 'page-header-headings'));

// Buttons.
if (isset($contextheader->additionalbuttons)) {
$html .= html_writer::start_div('btn-group header-button-group');
foreach ($contextheader->additionalbuttons as $button) {
if (!isset($button->page)) {
// Include js for messaging.
if ($button['buttontype'] === 'togglecontact') {
\core_message\helper::togglecontact_requirejs();
}
if ($button['buttontype'] === 'message') {
\core_message\helper::messageuser_requirejs();
}
$image = $this->pix_icon($button['formattedimage'], '', 'moodle', array(
'class' => 'iconsmall',
));
$image .= html_writer::span($button['title'], 'header-button-title');
} else {
$image = html_writer::empty_tag('img', array(
'src' => $button['formattedimage'],
'alt' => $button['title'],
));
}
$html .= html_writer::link($button['url'], html_writer::tag('span', $image), $button['linkattributes']);
}
$html .= html_writer::end_div();
}
$html .= html_writer::end_div();

return $html;
}

/**
* Wrapper for header elements.
*
Expand Down
75 changes: 75 additions & 0 deletions lib/templates/contextheader.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{{!
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/>.
}}
{{!
@template core/contextheader
Context header template.
Example context (json):
{
"heading": "<h2>Page title</h2>",
"prefix": "Page prefix",
"hasadditionalbuttons": true,
"additionalbuttons": [
{
"url": "http://example.com",
"title": "Button title",
"formattedimage": "http://example.com/image.jpg",
"attributes": [
{
"name": "data-attribute",
"value": "attribute value"
},
{
"name": "class",
"value": "btn btn-primary"
}
]
}
]
}
}}
<div class="page-context-header d-flex align-items-center mb-2">
{{#imagedata}}
<div class="page-header-image">
{{{imagedata}}}
</div>
{{/imagedata}}
<div class="page-header-headings">
{{#prefix}}
<div class="text-muted text-uppercase small line-height-3">
{{{prefix}}}
</div>
{{/prefix}}
{{{heading}}}
</div>
{{#hasadditionalbuttons}}
<div class="btn-group header-button-group mx-3">
{{#additionalbuttons}}
<a href="{{url}}" {{#attributes}} {{name}}="{{value}}" {{/attributes}}>
{{#page}}
{{#pix}}{{formattedimage}}{{/pix}}
<span class="header-button-title">{{title}}</span>
{{/page}}
{{^page}}
<img src="{{formattedimage}}" alt="{{title}}">
{{/page}}
</a>
{{/additionalbuttons}}
</div>
{{/hasadditionalbuttons}}
</div>
64 changes: 1 addition & 63 deletions theme/boost/classes/output/core_renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,69 +179,7 @@ public function context_header($headerinfo = null, $headinglevel = 1): string {
}

$contextheader = new \context_header($heading, $headinglevel, $imagedata, $userbuttons, $prefix);
return $this->render_context_header($contextheader);
}

/**
* Renders the header bar.
*
* @param context_header $contextheader Header bar object.
* @return string HTML for the header bar.
*/
protected function render_context_header(\context_header $contextheader) {

// Generate the heading first and before everything else as we might have to do an early return.
if (!isset($contextheader->heading)) {
$heading = $this->heading($this->page->heading, $contextheader->headinglevel, 'h2');
} else {
$heading = $this->heading($contextheader->heading, $contextheader->headinglevel, 'h2');
}

// All the html stuff goes here.
$html = html_writer::start_div('page-context-header');

// Image data.
if (isset($contextheader->imagedata)) {
// Header specific image.
$html .= html_writer::div($contextheader->imagedata, 'page-header-image mr-2');
}

// Headings.
if (isset($contextheader->prefix)) {
$prefix = html_writer::div($contextheader->prefix, 'text-muted text-uppercase small line-height-3');
$heading = $prefix . $heading;
}
$html .= html_writer::tag('div', $heading, array('class' => 'page-header-headings'));

// Buttons.
if (isset($contextheader->additionalbuttons)) {
$html .= html_writer::start_div('btn-group header-button-group');
foreach ($contextheader->additionalbuttons as $button) {
if (!isset($button->page)) {
// Include js for messaging.
if ($button['buttontype'] === 'togglecontact') {
\core_message\helper::togglecontact_requirejs();
}
if ($button['buttontype'] === 'message') {
\core_message\helper::messageuser_requirejs();
}
$image = $this->pix_icon($button['formattedimage'], '', 'moodle', array(
'class' => 'iconsmall',
));
$image .= html_writer::span($button['title'], 'header-button-title');
} else {
$image = html_writer::empty_tag('img', array(
'src' => $button['formattedimage'],
'alt' => $button['title'],
));
}
$html .= html_writer::link($button['url'], html_writer::tag('span', $image), $button['linkattributes']);
}
$html .= html_writer::end_div();
}
$html .= html_writer::end_div();

return $html;
return $this->render($contextheader);
}

/**
Expand Down
18 changes: 4 additions & 14 deletions theme/boost/scss/moodle/core.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1955,24 +1955,14 @@ nav.navbar .logo img {
overflow: hidden;
padding: 0.25rem 0;

display: flex;

.page-header-image {
& > a {
display: inline-block;
}
}

.page-header-headings,
.header-button-group {
position: relative;
line-height: 24px;
vertical-align: middle;
}

.header-button-group {
display: block;
float: left;
.userinitials,
.userpicture {
margin-right: map-get($spacers, 3);
}
}
}

Expand Down
13 changes: 3 additions & 10 deletions theme/boost/style/moodle.css
Original file line number Diff line number Diff line change
Expand Up @@ -24954,20 +24954,13 @@ nav.navbar .logo img {
.page-context-header {
overflow: hidden;
padding: 0.25rem 0;
display: flex;
}
.page-context-header .page-header-image > a {
display: inline-block;
}
.page-context-header .page-header-headings,
.page-context-header .header-button-group {
position: relative;
line-height: 24px;
vertical-align: middle;
}
.page-context-header .header-button-group {
display: block;
float: left;
.page-context-header .page-header-image .userinitials,
.page-context-header .page-header-image .userpicture {
margin-right: 1rem;
}

ul.dragdrop-keyboard-drag li {
Expand Down
13 changes: 3 additions & 10 deletions theme/classic/style/moodle.css
Original file line number Diff line number Diff line change
Expand Up @@ -24954,20 +24954,13 @@ nav.navbar .logo img {
.page-context-header {
overflow: hidden;
padding: 0.25rem 0;
display: flex;
}
.page-context-header .page-header-image > a {
display: inline-block;
}
.page-context-header .page-header-headings,
.page-context-header .header-button-group {
position: relative;
line-height: 24px;
vertical-align: middle;
}
.page-context-header .header-button-group {
display: block;
float: left;
.page-context-header .page-header-image .userinitials,
.page-context-header .page-header-image .userpicture {
margin-right: 1rem;
}

ul.dragdrop-keyboard-drag li {
Expand Down

0 comments on commit 78db6bb

Please sign in to comment.