Go to the documentation of this file.
28 if ( isset( $this->sidebar[
'wikibase-otherprojects'] ) ) {
29 $this->otherProjects = $this->sidebar[
'wikibase-otherprojects'];
30 unset( $this->sidebar[
'wikibase-otherprojects'] );
33 if ( isset( $this->sidebar[
'coll-print_export'] ) ) {
34 $this->collectionPortlet = $this->sidebar[
'coll-print_export'];
35 unset( $this->sidebar[
'coll-print_export'] );
42 $html = $this->
get(
'headelement' );
44 $html .=
Html::openElement(
'div', [
'id' =>
'mw-wrapper',
'class' => $userLinks[
'class'] ] );
46 $html .=
Html::rawElement(
'div', [
'id' =>
'mw-header-container',
'class' =>
'ts-container' ],
49 $this->
getLogo(
'p-logo-text',
'text' ) .
59 $html .=
Html::rawElement(
'div', [
'id' =>
'mw-content-container',
'class' =>
'ts-container' ],
60 Html::rawElement(
'div', [
'id' =>
'mw-content-block',
'class' =>
'ts-inner' ],
66 $this->
getLogo(
'p-logo',
'image' ) .
73 $this->pileOfTools[
'general'],
87 $html .=
Html::rawElement(
'div', [
'id' =>
'mw-footer-container',
'class' =>
'ts-container' ],
98 $html .= $this->
get(
'bottomscripts' );
99 $html .= $this->
get(
'reporttime' );
117 [
'id' =>
'content',
'class' =>
'mw-body',
'role' =>
'main' ],
123 'id' =>
'firstHeading',
124 'class' =>
'firstHeading',
125 'lang' => $this->
get(
'pageLanguage' )
127 $this->
get(
'title' )
134 $this->pileOfTools[
'namespaces'],
135 'timeless-namespaces',
136 [
'extra-classes' =>
'tools-inline' ]
140 $this->pileOfTools[
'more'],
142 [
'extra-classes' =>
'tools-inline' ]
147 $this->pileOfTools[
'page-primary'],
148 'timeless-pagetools',
149 [
'extra-classes' =>
'tools-inline' ]
153 Html::rawElement(
'div', [
'class' =>
'mw-body-content',
'id' =>
'bodyContent' ],
155 $this->
get(
'bodytext' ) .
193 $options = array_merge( [
194 'role' =>
'navigation',
196 'id' =>
'p-' . $name,
197 'class' => [
'mw-portlet',
'emptyPortlet' => !
$content ],
198 'extra-classes' =>
'',
200 'body-class' =>
'mw-portlet-body',
201 'body-extra-classes' =>
'',
203 'text-wrapper' => [
'tag' =>
'span' ],
209 if ( $msg ===
null ) {
212 } elseif ( is_array( $msg ) ) {
213 $msgString = array_shift( $msg );
219 $msgObj = $this->
getMsg( $msg, $msgParams );
220 if ( $msgObj->exists() ) {
221 $msgString = $msgObj->parse();
223 $msgString = htmlspecialchars( $msg );
230 [
'lang' => $this->
get(
'userlang' ),
'dir' => $this->
get(
'dir' ) ]
232 $contentText .= $options[
'list-prepend'];
233 foreach (
$content as $key => $item ) {
234 if ( is_array( $options[
'text-wrapper'] ) ) {
238 [
'text-wrapper' => $options[
'text-wrapper'] ]
253 'role' => $options[
'role'],
254 'class' => $this->
mergeClasses( $options[
'class'], $options[
'extra-classes'] ),
257 'aria-labelledby' => $labelId
261 'lang' => $this->
get(
'userlang' ),
262 'dir' => $this->
get(
'dir' )
266 'class' => $this->
mergeClasses( $options[
'body-class'], $options[
'body-extra-classes'] )
268 if ( is_string( $options[
'body-id'] ) ) {
269 $bodyDivOptions[
'id'] = $options[
'body-id'];
295 if ( !is_array( $class ) ) {
298 if ( !is_array( $extraClasses ) ) {
299 $extraClasses = [ $extraClasses ];
302 return array_merge( $class, $extraClasses );
322 'class' => array_merge( [
'sidebar-chunk' ], $classes )
343 protected function getLogo( $id =
'p-logo', $part =
'both' ) {
345 $language = $this->
getSkin()->getLanguage();
352 'class' =>
'mw-portlet',
356 if ( $part !==
'image' ) {
360 if ( !$wordmarkImage ) {
361 if ( $language->hasVariants() ) {
362 $siteTitle = $language->convert( $this->
getMsg(
'timeless-sitetitle' )->escaped() );
364 $siteTitle = $this->
getMsg(
'timeless-sitetitle' )->escaped();
367 if ( mb_strlen( $siteTitle ) > 13 ) {
368 $titleClass =
'long';
371 $titleClass =
'wordmark';
375 'class' => [
'mw-wiki-title', $titleClass ],
376 'href' => $this->data[
'nav_urls'][
'mainpage'][
'href']
378 $wordmarkImage ?: $siteTitle
382 if ( $part !==
'text' ) {
389 'class' => [
'mw-wiki-logo', !$logoImage ?
'fallback' :
'timeless-logo' ],
390 'href' => $this->data[
'nav_urls'][
'mainpage'][
'href']
410 $html .=
Html::openElement(
'div', [
'class' =>
'mw-portlet',
'id' =>
'p-search' ] );
414 [
'lang' => $this->
get(
'userlang' ),
'dir' => $this->
get(
'dir' ) ],
418 $html .=
Html::rawElement(
'form', [
'action' => $this->
get(
'wgScript' ),
'id' =>
'searchform' ],
422 'id' =>
'searchInput'
428 [
'id' =>
'mw-searchButton',
'class' =>
'searchButton mw-fallbackSearchButton' ]
432 [
'id' =>
'searchButton',
'class' =>
'searchButton' ]
451 $this->sidebar[
'SEARCH'] =
false;
453 $this->sidebar[
'TOOLBOX'] =
false;
455 $this->sidebar[
'LANGUAGES'] =
false;
457 foreach ( $this->sidebar as $name =>
$content ) {
462 $name = (string)$name;
466 $html = $this->
getSidebarChunk(
'site-navigation',
'navigation', $html );
481 $html .=
Html::rawElement(
'div', [
'id' =>
'mw-header-hack',
'class' =>
'color-bar' ],
510 $this->pileOfTools[
'page-secondary'],
511 'timeless-pageactions'
515 $this->pileOfTools[
'user'],
516 'timeless-userpagetools'
520 $this->pileOfTools[
'page-tertiary'],
523 if ( isset( $this->collectionPortlet ) ) {
526 $this->collectionPortlet[
'content']
530 return $this->
getSidebarChunk(
'page-tools',
'timeless-pageactions', $pageTools );
540 $user = $this->
getSkin()->getUser();
543 $userName = $personalTools[
'userpage'][
'links'][0][
'text'] ?? $user->getName();
549 if ( isset( $personalTools[
'notifications-alert'] ) ) {
550 $extraTools[
'notifications-alert'] = $personalTools[
'notifications-alert'];
551 unset( $personalTools[
'notifications-alert'] );
553 if ( isset( $personalTools[
'notifications-notice'] ) ) {
554 $extraTools[
'notifications-notice'] = $personalTools[
'notifications-notice'];
555 unset( $personalTools[
'notifications-notice'] );
557 $class = empty( $extraTools ) ?
'' :
'extension-icons';
560 if ( isset( $personalTools[
'userpage'] ) ) {
561 $personalTools[
'userpage'][
'links'][0][
'text'] = $this->
getMsg(
'timeless-userpage' )->text();
563 if ( isset( $personalTools[
'mytalk'] ) ) {
564 $personalTools[
'mytalk'][
'links'][0][
'text'] = $this->
getMsg(
'timeless-talkpage' )->text();
568 if ( $user->isLoggedIn() ) {
569 $dropdownHeader = $userName;
570 $headerMsg = [
'timeless-loggedinas', $userName ];
572 $dropdownHeader = $this->
getMsg(
'timeless-anonymous' )->text();
573 $headerMsg =
'timeless-notloggedin';
581 Html::rawElement(
'div', [
'id' =>
'personal-inner',
'class' =>
'dropdown' ],
582 $this->
getPortlet(
'personal', $personalTools, $headerMsg )
587 if ( !empty( $extraTools ) ) {
589 foreach ( $extraTools as $key => $item ) {
595 [
'id' =>
'personal-extra',
'class' =>
'p-body' ],
616 if ( $this->data[
'sitenotice'] ) {
617 $html .=
Html::rawElement(
'div', [
'id' =>
'siteNotice' ], $this->
get(
'sitenotice' ) );
619 if ( $this->data[
'newtalk'] ) {
620 $html .=
Html::rawElement(
'div', [
'class' =>
'usermessage' ], $this->
get(
'newtalk' ) );
635 if ( $this->data[
'subtitle'] ) {
636 $html .= $this->
get(
'subtitle' );
638 if ( $this->data[
'undelete'] ) {
639 $html .= $this->
get(
'undelete' );
655 if ( $this->data[
'catlinks'] || $this->data[
'dataAfterContent'] ) {
657 if ( $this->data[
'catlinks'] ) {
658 $html .= $this->
get(
'catlinks' );
660 if ( $this->data[
'dataAfterContent'] ) {
661 $html .= $this->
get(
'dataAfterContent' );
680 $namespace =
$title->getNamespace();
682 $sortedPileOfTools = [
684 'page-primary' => [],
685 'page-secondary' => [],
687 'page-tertiary' => [],
693 $pileOfEditTools = [];
694 foreach ( $this->data[
'content_navigation'] as $navKey => $navBlock ) {
696 if ( $navKey ==
'namespaces' ) {
697 if ( $namespace < 0 && count( $navBlock ) < 2 ) {
699 $sortedPileOfTools[
'page-tertiary'] = $navBlock;
701 $sortedPileOfTools[
'namespaces'] = $navBlock;
703 } elseif ( $navKey ==
'variants' ) {
705 $sortedPileOfTools[
'variants'] = $navBlock;
707 $pileOfEditTools = array_merge( $pileOfEditTools, $navBlock );
713 if ( $namespace >= 0 ) {
715 'text' => $this->
getMsg(
'timeless-pagelog' )->text(),
717 [
'page' =>
$title->getPrefixedText() ]
725 'text' => $this->
getMsg(
'timeless-more' )->text(),
727 'class' =>
'dropdown-toggle'
729 if ( $this->data[
'language_urls'] !==
false || $sortedPileOfTools[
'variants']
730 || isset( $this->otherProjects ) ) {
732 'text' => $this->
getMsg(
'timeless-languages' )->escaped(),
733 'id' =>
'ca-languages',
734 'class' =>
'dropdown-toggle'
740 foreach ( $pileOfEditTools as $navKey => $navBlock ) {
743 if ( in_array( $navKey, [
747 $currentSet =
'namespaces';
748 } elseif ( in_array( $navKey, [
755 $currentSet =
'page-primary';
756 } elseif ( in_array( $navKey, [
763 $currentSet =
'page-secondary';
766 $currentSet =
'page-primary';
768 $sortedPileOfTools[$currentSet][$navKey] = $navBlock;
773 if ( $navKey ===
'contributions' ) {
774 $currentSet =
'page-primary';
775 } elseif ( in_array( $navKey, [
782 $currentSet =
'user';
783 } elseif ( in_array( $navKey, [
788 'recentchangeslinked',
793 $currentSet =
'page-tertiary';
794 } elseif ( in_array( $navKey, [
798 $currentSet =
'more';
800 $currentSet =
'general';
802 $sortedPileOfTools[$currentSet][$navKey] = $navBlock;
807 'proofreadPagePrevLink',
809 'proofreadPageScanLink',
810 'proofreadPageIndexLink',
811 'proofreadPageNextLink',
813 foreach ( $tabs as $tab ) {
814 if ( isset( $sortedPileOfTools[
'namespaces'][$tab] ) ) {
815 $toMove = $sortedPileOfTools[
'namespaces'][$tab];
816 unset( $sortedPileOfTools[
'namespaces'][$tab] );
819 $toMove[
'title'] = $toMove[
'text'];
821 if ( $tab ===
'proofreadPagePrevLink' ) {
823 $sortedPileOfTools[
'namespaces'] = array_merge(
825 $sortedPileOfTools[
'namespaces']
829 $sortedPileOfTools[
'namespaces'][$tab] = $toMove;
834 return $sortedPileOfTools;
850 $allCats = $skin->getOutput()->getCategoryLinks();
851 if ( !empty( $allCats ) ) {
852 if ( !empty( $allCats[
'normal'] ) ) {
853 $catHeader =
'categories';
857 'mw-normal-catlinks',
861 $catHeader =
'hidden-categories';
864 if ( isset( $allCats[
'hidden'] ) ) {
865 $hiddenCatClass = [
'mw-hidden-catlinks' ];
866 if ( $skin->getUser()->getBoolOption(
'showhiddencats' ) ) {
867 $hiddenCatClass[] =
'mw-hidden-cats-user-shown';
868 } elseif ( $skin->getTitle()->getNamespace() ==
NS_CATEGORY ) {
869 $hiddenCatClass[] =
'mw-hidden-cats-ns-shown';
871 $hiddenCatClass[] =
'mw-hidden-cats-hidden';
877 [
'hidden-categories', count( $allCats[
'hidden'] ) ]
882 if ( $catList !==
'' ) {
883 $html = $this->
getSidebarChunk(
'catlinks-sidebar', $catHeader, $catList );
899 protected function getCatList( $list, $id, $class, $message ) {
900 $html =
Html::openElement(
'div', [
'id' =>
"sidebar-{$id}",
'class' => $class ] );
902 $makeLinkItem =
function ( $linkHtml ) {
906 $categoryItems = array_map( $makeLinkItem, $list );
910 implode(
'', $categoryItems )
913 $html .= $this->
getPortlet( $id, $categoriesHtml, $message );
930 if ( $this->pileOfTools[
'variants'] ) {
933 $this->pileOfTools[
'variants'],
935 [
'body-extra-classes' =>
'dropdown' ]
953 $variantsOnly =
false;
955 if ( $this->pileOfTools[
'variants'] ) {
958 $this->pileOfTools[
'variants']
961 $variantsOnly =
true;
963 if ( $this->data[
'language_urls'] !==
false ) {
966 $this->data[
'language_urls'] ?: [],
970 $variantsOnly =
false;
973 if ( isset( $this->otherProjects ) ) {
975 'wikibase-otherprojects',
976 $this->otherProjects[
'content']
979 $variantsOnly =
false;
987 $variantsOnly ? [
'variants-only' ] : []
1003 if ( $logo ===
null ) {
1009 if ( is_string( $logo ) ) {
1019 $width =
$file->getWidth();
1020 $height =
$file->getHeight();
1021 $bound = $width > $height ? $width : $height;
1028 $large = $doLarge ? 4 : 2;
1030 if ( $bound <= 165 ) {
1032 $logoData[
'width'] = $width;
1033 $logoData[
'height'] = $height;
1036 $logoData[
'1x'] =
$file->createThumb( $logoData[
'width'] );
1037 $logoData[
'1.5x'] =
$file->createThumb( $logoData[
'width'] * 1.5 );
1038 $logoData[
'2x'] =
$file->createThumb( $logoData[
'width'] * $large );
1039 } elseif (
$file->mustRender() ) {
1040 $logoData[
'1x'] =
$file->createThumb( $logoData[
'width'] );
1042 $logoData[
'1x'] =
$file->getUrl();
1045 } elseif ( $bound >= 230 && $bound <= 330 ) {
1047 $logoData[
'width'] = $width / 2;
1048 $logoData[
'height'] = $height / 2;
1050 $logoData[
'1x'] =
$file->createThumb( $logoData[
'width'] );
1051 $logoData[
'1.5x'] =
$file->createThumb( $logoData[
'width'] * 1.5 );
1053 if ( $svg ||
$file->mustRender() ) {
1054 $logoData[
'2x'] =
$file->createThumb( $logoData[
'width'] * 2 );
1056 $logoData[
'2x'] =
$file->getUrl();
1062 $logoData[
'width'] = 155;
1065 $logoData[
'1x'] =
$file->createThumb( $logoData[
'width'] );
1066 if ( $svg || $logoData[
'width'] * 1.5 <= $width ) {
1067 $logoData[
'1.5x'] =
$file->createThumb( $logoData[
'width'] * 1.5 );
1069 if ( $svg || $logoData[
'width'] * 2 <= $width ) {
1070 $logoData[
'2x'] =
$file->createThumb( $logoData[
'width'] * $large );
1073 } elseif ( is_array( $logo ) ) {
1083 'alt' => $this->
getMsg(
'sitetitle' )->text(),
1085 'decoding' =>
'auto',
1086 'width' => $logoData[
'width'],
1087 'height' => $logoData[
'height'],
1090 if ( !isset( $logoData[
'1x'] ) && isset( $logoData[
'2x'] ) ) {
1092 $attribs[
'src'] = $logoData[
'2x'];
1096 $attribs[
'src'] = $logoData[
'1x'];
1099 unset( $logoData[
'1x'], $logoData[
'width'], $logoData[
'height'] );
1101 foreach ( $logoData as
$res =>
$path ) {
1102 if ( $srcset !=
'' ) {
1108 if ( $srcset !==
'' ) {
1109 $attribs[
'srcset'] = $srcset;
getPersonalTools()
Create an array of personal tools items from the data in the quicktemplate stored by SkinTemplate.
static getDebugHTML(IContextSource $context)
Returns the HTML to add to the page for the toolbar.
getPortlet( $name, $content, $msg=null, $setOptions=[])
Generates a block of navigation links with a header This is some random fork of some random fork of w...
getSidebarChunk( $id, $headerMessage, $content, $classes=[])
Sidebar chunk containing one or more portlets.
makeSearchButton( $mode, $attrs=[])
switch( $options['output']) $languages
static escapeIdForAttribute( $id, $mode=self::ID_PRIMARY)
Given a section name or other user-generated or otherwise unsafe string, escapes it to be a valid HTM...
getClear()
Get a div with the core visualClear class, for clearing floats.
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
mergeClasses( $class, $extraClasses)
Helper function for getPortlet.
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
getContentSub()
Links and information that may appear below the firstHeading.
getPageToolSidebar()
Page tools in sidebar.
getLogoImage( $logo, $doLarge=false)
Generate img-based logos for proper HiDPI support.
getSkin()
Get the Skin object related to this object.
static tooltipAndAccesskeyAttribs( $name, array $msgParams=[], $options=null)
Returns the attributes for the tooltip and access key.
getSearch()
The search box at the top.
static closeElement( $element)
Returns "</$element>".
BaseTemplate class for the Timeless skin.
getAfterPortlet( $name)
Allows extensions to hook into known portlets and add stuff to them.
static normalizeExtension( $extension)
Normalize a file extension to the common form, making it lowercase and checking some synonyms,...
makeListItem( $key, $item, $options=[])
Generates a list item for a navigation, portlet, portal, sidebar...
getContentBlock()
Generate the page content block Broken out here due to the excessive indenting, or stuff.
getIndicators()
Get the suggested HTML for page status indicators: icons (or short text snippets) usually displayed i...
getHeaderHack()
The colour bars Split this out so we don't have to look at it/can easily kill it later.
getFooter( $iconStyle='icononly', $linkStyle='flat')
Renderer for getFooterIcons and getFooterLinks.
static hidden( $name, $value, array $attribs=[])
Convenience function to produce an input element with type=hidden.
getSiteNotices()
Notices that may appear above the firstHeading.
makeSearchInput( $attrs=[])
getLogo( $id='p-logo', $part='both')
The logo and (optionally) site title.
getInterwikiLinks()
Interwiki links block.
static titleAttrib( $name, $options=null, array $msgParams=[])
Given the id of an interface element, constructs the appropriate title attribute from the system mess...
wfFindFile( $title, $options=[])
Find a file.
getMainNavigation()
Left sidebar navigation, usually.
array null $otherProjects
static scaleHeight( $srcWidth, $srcHeight, $dstWidth)
Calculate the height of a thumbnail using the source and destination width.
getToolbox()
Create an array of common toolbox items from the data in the quicktemplate stored by SkinTemplate.
getMsg( $name,... $params)
Get a Message object with its context set.
static openElement( $element, $attribs=[])
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing '/'...
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
getPageTools()
Generate pile of all the tools.
getCatList( $list, $id, $class, $message)
List of categories.
getAfterContent()
The data after content, catlinks, and potential other stuff that may appear within the content block ...
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
array null $collectionPortlet
New base template for a skin's template extended from QuickTemplate this class features helper method...
static escapeId( $id, $options=[])
Given a value, escape it so that it can be used in an id attribute and return it.
getUserLinks()
Personal/user links portlet for header.
getVariants()
Interlanguage links block, with variants if applicable Layout sort of assumes we're using ULS compact...
execute()
Outputs the entire contents of the page.
getCategories()
Categories for the sidebar.