40 $html = $this->
get(
'headelement' );
41 $html .= Html::openElement(
'div', [
'id' =>
'globalWrapper' ] );
43 $html .= Html::openElement(
'div', [
'id' =>
'column-content' ] );
44 $html .= Html::rawElement(
'div', [
'id' =>
'content',
'class' =>
'mw-body',
'role' =>
'main' ],
45 Html::element(
'a', [
'id' =>
'top' ] ) .
48 'parameters' => [
'id' =>
'siteNotice',
'class' =>
'mw-body-content' ]
55 'id' =>
'firstHeading',
56 'class' =>
'firstHeading',
57 'lang' => $this->
getSkin()->
getTitle()->getPageViewLanguage()->getHtmlCode()
60 Html::rawElement(
'div', [
'id' =>
'bodyContent',
'class' =>
'mw-body-content' ],
61 Html::rawElement(
'div', [
'id' =>
'siteSub' ], $this->
getMsg(
'tagline' )->parse() ) .
64 [
'id' =>
'contentSub',
'lang' => $this->
get(
'userlang' ),
'dir' => $this->
get(
'dir' ) ],
65 $this->
get(
'subtitle' )
67 $this->
getIfExists(
'undelete', [
'wrapper' =>
'div',
'parameters' => [
70 $this->
getIfExists(
'newtalk', [
'wrapper' =>
'div',
'parameters' => [
71 'class' =>
'usermessage'
73 Html::element(
'div', [
'id' =>
'jump-to-nav' ] ) .
74 Html::element(
'a', [
'href' =>
'#column-one',
'class' =>
'mw-jump-link' ],
75 $this->
getMsg(
'monobook-jumptonavigation' )->
text()
77 Html::element(
'a', [
'href' =>
'#searchInput',
'class' =>
'mw-jump-link' ],
78 $this->
getMsg(
'monobook-jumptosearch' )->
text()
80 '<!-- start content -->' .
82 $this->
get(
'bodytext' ) .
85 '<!-- end content -->' .
91 $html .= Html::closeElement(
'div' );
93 $html .= Html::rawElement(
'div',
96 'lang' => $this->
get(
'userlang' ),
97 'dir' => $this->
get(
'dir' )
99 Html::element(
'h2', [], $this->
getMsg(
'navigation-heading' )->
text() ) .
102 Html::rawElement(
'div', [
'class' =>
'portlet',
'id' =>
'p-logo',
'role' =>
'banner' ],
105 'href' => $this->data[
'nav_urls'][
'mainpage'][
'href'],
106 'class' =>
'mw-wiki-logo',
118 $this->
getMsg(
'monobook-jumptopersonal' )->
text()
125 $html .=
'<!-- end of the left (by default at least) column -->';
129 $html .= Html::closeElement(
'div' );
133 $html .= Html::closeElement(
'body' );
134 $html .= Html::closeElement(
'html' );
151 return Html::element(
'a', [
152 'href' =>
"#$target",
154 'class' =>
'menu-toggle',
155 'id' =>
"$target-toggle"
166 $allTabs = $this->data[
'content_actions'];
167 $tabCount = count( $allTabs );
170 if ( $tabCount > 2 ) {
171 $html .= $this->
getBox(
'cactions', $allTabs,
'monobook-cactions-label' );
174 $html .= $this->
getBox(
'cactions', $allTabs,
'monobook-cactions-label',
175 [
'extra-classes' =>
'nomobile' ]
180 $tabs = $this->data[
'content_navigation'][
'namespaces'];
181 foreach ( $tabs as $tab => $attribs ) {
182 $tabs[$tab][
'id'] = $attribs[
'id'] .
'-mobile';
183 $tabs[$tab][
'title'] = $attribs[
'text'];
186 if ( $tabCount !== 1 ) {
189 'text' => $this->
getMsg(
'monobook-more-actions' )->text(),
190 'href' =>
'#p-cactions',
195 'text' => $this->
getMsg(
'toolbox' )->text(),
198 'title' => $this->
getMsg(
'toolbox' )->text()
200 if ( $this->data[
'language_urls'] !==
false ) {
201 $tabs[
'languages'] = [
202 'text' => $this->
getMsg(
'otherlanguages' )->text(),
204 'id' =>
'ca-languages',
205 'title' => $this->
getMsg(
'otherlanguages' )->text()
209 $html .= $this->
getBox(
'cactions-mobile', $tabs,
'monobook-cactions-label' );
220 $sidebar = $this->data[
'sidebar'];
223 if ( !isset( $sidebar[
'SEARCH'] ) ) {
224 $sidebar[
'SEARCH'] =
true;
226 if ( !isset( $sidebar[
'TOOLBOX'] ) ) {
227 $sidebar[
'TOOLBOX'] =
true;
229 if ( !isset( $sidebar[
'LANGUAGES'] ) ) {
230 $sidebar[
'LANGUAGES'] =
true;
233 foreach ( $sidebar as $boxName =>
$content ) {
239 $boxName = (string)$boxName;
241 if ( $boxName ==
'SEARCH' ) {
243 } elseif ( $boxName ==
'TOOLBOX' ) {
245 } elseif ( $boxName ==
'LANGUAGES' ) {
252 [
'extra-classes' =>
'generated-sidebar' ]
268 if ( $this->config->get(
'UseTwoButtonsSearchForm' ) ) {
271 [
'id' =>
'mw-searchButton',
'class' =>
'searchButton' ]
274 $optionButtons = Html::rawElement(
'div', [],
275 Html::rawElement(
'a', [
'href' => $this->
get(
'searchaction' ),
'rel' =>
'search' ],
276 $this->
getMsg(
'powersearch-legend' )->escaped()
280 $searchInputId =
'searchInput';
281 $searchForm = Html::rawElement(
'form', [
282 'action' => $this->
get(
'wgScript' ),
285 Html::hidden(
'title', $this->
get(
'searchtitle' ) ) .
287 $this->
makeSearchButton(
'go', [
'id' =>
'searchGoButton',
'class' =>
'searchButton' ] ) .
291 $html .= $this->
getBox(
'search', $searchForm,
null, [
292 'search-input-id' => $searchInputId,
294 'body-id' =>
'searchBody'
309 $html .= $this->
getBox(
'tb', $this->
getToolbox(),
'toolbox', [
'hooks' => [
311 'MonoBookTemplateToolboxEnd' => [ &$template ],
312 'SkinTemplateToolboxEnd' => [ &$template,
true ]
328 if ( $this->data[
'language_urls'] !==
false ) {
329 $html .= $this->
getBox(
'lang', $this->data[
'language_urls'],
'otherlanguages' );
346 protected function getBox( $name, $contents, $msg =
null, $setOptions = [] ) {
347 $options = array_merge( [
348 'class' =>
'portlet',
349 'body-class' =>
'pBody',
354 if ( $name ==
'personal' ) {
358 if ( array_key_exists(
'uls', $contents ) ) {
359 $prependiture .= $this->
makeListItem(
'uls', $contents[
'uls'] );
360 unset( $contents[
'uls'] );
365 $prependiture .= Html::rawElement(
367 [
'id' =>
'pt-anonuserpage' ],
368 $this->
getMsg(
'notloggedin' )->escaped()
371 $options[
'list-prepend'] = $prependiture;
374 return $this->
getPortlet( $name, $contents, $msg, $options );
389 $options = array_merge( [
391 'role' =>
'navigation',
392 'search-input-id' =>
'searchInput',
394 'id' =>
'p-' . $name,
395 'class' =>
'mw-portlet',
396 'extra-classes' =>
'',
398 'body-class' =>
'mw-portlet-body',
399 'body-extra-classes' =>
'',
401 'text-wrapper' => [
'tag' =>
'span' ],
409 if ( $msg ===
null ) {
412 } elseif ( is_array( $msg ) ) {
413 $msgString = array_shift( $msg );
419 $msgObj = $this->
getMsg( $msg, $msgParams );
420 if ( $msgObj->exists() ) {
421 $msgString = $msgObj->parse();
423 $msgString = htmlspecialchars( $msg );
426 $labelId = Sanitizer::escapeIdForAttribute(
"p-$name-label" );
429 $contentText = Html::openElement(
'ul',
430 [
'lang' => $this->
get(
'userlang' ),
'dir' => $this->
get(
'dir' ) ]
432 $contentText .= $options[
'list-prepend'];
433 foreach (
$content as $key => $item ) {
434 if ( is_array( $options[
'text-wrapper'] ) ) {
438 [
'text-wrapper' => $options[
'text-wrapper'] ]
448 if ( is_array( $options[
'hooks'] ) ) {
449 foreach ( $options[
'hooks'] as $hook => $hookOptions ) {
454 $contentText .= Html::closeElement(
'ul' );
461 'role' => $options[
'role'],
462 'class' => $this->
mergeClasses( $options[
'class'], $options[
'extra-classes'] ),
463 'id' => Sanitizer::escapeIdForAttribute( $options[
'id'] ),
466 if ( $options[
'role'] !==
'search' ) {
467 $divOptions[
'aria-labelledby'] = $labelId;
471 'lang' => $this->
get(
'userlang' ),
472 'dir' => $this->
get(
'dir' )
474 if ( $options[
'role'] ==
'search' ) {
475 $msgString = Html::rawElement(
'label', [
'for' => $options[
'search-input-id'] ], $msgString );
479 'class' => $this->
mergeClasses( $options[
'body-class'], $options[
'body-extra-classes'] )
481 if ( is_string( $options[
'body-id'] ) ) {
482 $bodyDivOptions[
'id'] = $options[
'body-id'];
485 $html = Html::rawElement(
'div', $divOptions,
486 Html::rawElement(
'h3', $labelOptions, $msgString ) .
487 Html::rawElement(
'div', $bodyDivOptions,
508 if ( !is_array( $class ) ) {
511 if ( !is_array( $extraClasses ) ) {
512 $extraClasses = [ $extraClasses ];
515 return array_merge( $class, $extraClasses );
531 $hookContents = ob_get_contents();
533 if ( !trim( $hookContents ) ) {
537 return $hookContents;
554 foreach ( $setOptions as $key => $value ) {
555 $options[$key] = $value;
560 if ( ( $options[
'loose'] && $this->data[$object] !=
'' ) ||
561 ( !$options[
'loose'] && $this->data[$object] ) ) {
562 if ( $options[
'wrapper'] ==
'none' ) {
563 $html .= $this->
get( $object );
565 $html .= Html::rawElement(
567 $options[
'parameters'],
568 $this->
get( $object )
587 $html .= Html::openElement(
'div', [
589 'role' =>
'contentinfo',
590 'lang' => $this->
get(
'userlang' ),
591 'dir' => $this->
get(
'dir' )
594 foreach ( $validFooterIcons as $blockName => $footerIcons ) {
595 $html .= Html::openElement(
'div', [
596 'id' => Sanitizer::escapeIdForAttribute(
"f-{$blockName}ico" ),
597 'class' =>
'footer-icons'
599 foreach ( $footerIcons as $icon ) {
600 $html .= $this->
getSkin()->makeFooterIcon( $icon );
602 $html .= Html::closeElement(
'div' );
604 if ( count( $validFooterLinks ) > 0 ) {
605 $html .= Html::openElement(
'ul', [
'id' =>
'f-list' ] );
606 foreach ( $validFooterLinks as $aLink ) {
607 $html .= Html::rawElement(
609 [
'id' => Sanitizer::escapeIdForAttribute( $aLink ) ],
613 $html .= Html::closeElement(
'ul' );
615 $html .= Html::closeElement(
'div' );