MediaWiki master
BaseTemplate.php
Go to the documentation of this file.
1<?php
22
28
38abstract class BaseTemplate extends QuickTemplate {
39
49 public function getMsg( $name, ...$params ) {
50 return $this->getSkin()->msg( $name, ...$params );
51 }
52
53 public function msg( $str ) {
54 echo $this->getMsg( $str )->escaped();
55 }
56
60 public function getPersonalTools() {
61 return $this->getSkin()->getPersonalToolsForMakeListItem( $this->get( 'personal_urls' ) );
62 }
63
69 protected function getSidebar( $options = [] ) {
70 // Force the rendering of the following portals
71 $sidebar = $this->data['sidebar'];
72 if ( !isset( $sidebar['SEARCH'] ) ) {
73 // @phan-suppress-next-line PhanTypeMismatchDimAssignment False positive
74 $sidebar['SEARCH'] = true;
75 }
76 if ( !isset( $sidebar['TOOLBOX'] ) ) {
77 $sidebar['TOOLBOX'] = true;
78 }
79 if ( !isset( $sidebar['LANGUAGES'] ) ) {
80 $sidebar['LANGUAGES'] = true;
81 }
82
83 if ( !isset( $options['search'] ) || $options['search'] !== true ) {
84 unset( $sidebar['SEARCH'] );
85 }
86 if ( isset( $options['toolbox'] ) && $options['toolbox'] === false ) {
87 unset( $sidebar['TOOLBOX'] );
88 }
89 if ( isset( $options['languages'] ) && $options['languages'] === false ) {
90 unset( $sidebar['LANGUAGES'] );
91 }
92
93 $boxes = [];
94 foreach ( $sidebar as $boxName => $content ) {
95 if ( $content === false ) {
96 continue;
97 }
98 switch ( $boxName ) {
99 case 'SEARCH':
100 // Search is a special case, skins should custom implement this
101 $boxes[$boxName] = [
102 'id' => 'p-search',
103 'header' => $this->getMsg( 'search' )->text(),
104 'generated' => false,
105 'content' => true,
106 ];
107 break;
108 case 'TOOLBOX':
109 $msgObj = $this->getMsg( 'toolbox' );
110 $boxes[$boxName] = [
111 'id' => 'p-tb',
112 'header' => $msgObj->exists() ? $msgObj->text() : 'toolbox',
113 'generated' => false,
114 'content' => $content,
115 ];
116 break;
117 case 'LANGUAGES':
118 if ( $this->data['language_urls'] !== false ) {
119 $msgObj = $this->getMsg( 'otherlanguages' );
120 $boxes[$boxName] = [
121 'id' => 'p-lang',
122 'header' => $msgObj->exists() ? $msgObj->text() : 'otherlanguages',
123 'generated' => false,
124 'content' => $this->data['language_urls'] ?: [],
125 ];
126 }
127 break;
128 default:
129 $msgObj = $this->getMsg( $boxName );
130 $boxes[$boxName] = [
131 'id' => "p-$boxName",
132 'header' => $msgObj->exists() ? $msgObj->text() : $boxName,
133 'generated' => true,
134 'content' => $content,
135 ];
136 break;
137 }
138 }
139
140 if ( isset( $options['htmlOnly'] ) && $options['htmlOnly'] === true ) {
141 foreach ( $boxes as $boxName => $box ) {
142 if ( is_array( $box['content'] ) ) {
143 $content = '<ul>';
144 foreach ( $box['content'] as $key => $val ) {
145 $content .= "\n " . $this->getSkin()->makeListItem( $key, $val );
146 }
147 $content .= "\n</ul>\n";
148 $boxes[$boxName]['content'] = $content;
149 }
150 }
151 }
152
153 return $boxes;
154 }
155
164 protected function makeLink( $key, $item, $options = [] ) {
165 return $this->getSkin()->makeLink( $key, $item, $options );
166 }
167
176 public function makeListItem( $key, $item, $options = [] ) {
177 return $this->getSkin()->makeListItem( $key, $item, $options );
178 }
179
186 protected function makeSearchInput( $attrs = [] ) {
187 return $this->getSkin()->makeSearchInput( $attrs );
188 }
189
197 protected function makeSearchButton( $mode, $attrs = [] ) {
198 return $this->getSkin()->makeSearchButton( $mode, $attrs );
199 }
200
210 protected function getFooterLinks( $option = null ) {
211 $footerlinks = $this->get( 'footerlinks' );
212
213 // Reduce footer links down to only those which are being used
214 $validFooterLinks = [];
215 foreach ( $footerlinks as $category => $links ) {
216 $validFooterLinks[$category] = [];
217 foreach ( $links as $link ) {
218 if ( isset( $this->data[$link] ) && $this->data[$link] ) {
219 $validFooterLinks[$category][] = $link;
220 }
221 }
222 if ( count( $validFooterLinks[$category] ) <= 0 ) {
223 unset( $validFooterLinks[$category] );
224 }
225 }
226
227 if ( $option == 'flat' && count( $validFooterLinks ) ) {
228 // fold footerlinks into a single array using a bit of trickery
229 $validFooterLinks = array_merge( ...array_values( $validFooterLinks ) );
230 }
231
232 return $validFooterLinks;
233 }
234
239 private function unsetIconsWithoutImages( array &$icons ) {
240 // Unset any icons which don't have an image
241 foreach ( $icons as $iconsKey => &$iconsBlock ) {
242 foreach ( $iconsBlock as $iconKey => $icon ) {
243 if ( !is_string( $icon ) && !isset( $icon['src'] ) ) {
244 unset( $iconsBlock[$iconKey] );
245 }
246 }
247 if ( $iconsBlock === [] ) {
248 unset( $icons[$iconsKey] );
249 }
250 }
251 }
252
263 protected function getFooter( $iconStyle = 'icononly', $linkStyle = 'flat' ) {
264 $validFooterIcons = $this->get( 'footericons' );
265 if ( $iconStyle === 'icononly' ) {
266 $this->unsetIconsWithoutImages( $validFooterIcons );
267 }
268 $validFooterLinks = $this->getFooterLinks( $linkStyle );
269
270 $html = '';
271
272 if ( count( $validFooterIcons ) + count( $validFooterLinks ) > 0 ) {
273 $html .= Html::openElement( 'div', [
274 'id' => 'footer-bottom',
275 'class' => 'mw-footer',
276 'role' => 'contentinfo',
277 'lang' => $this->get( 'userlang' ),
278 'dir' => $this->get( 'dir' )
279 ] );
280 $footerEnd = Html::closeElement( 'div' );
281 } else {
282 $footerEnd = '';
283 }
284 foreach ( $validFooterIcons as $blockName => $footerIcons ) {
285 $html .= Html::openElement( 'div', [
286 'id' => Sanitizer::escapeIdForAttribute( "f-{$blockName}ico" ),
287 'class' => 'footer-icons'
288 ] );
289 foreach ( $footerIcons as $icon ) {
290 $html .= $this->getSkin()->makeFooterIcon( $icon );
291 }
292 $html .= Html::closeElement( 'div' );
293 }
294 if ( count( $validFooterLinks ) > 0 ) {
295 $html .= Html::openElement( 'ul', [ 'id' => 'f-list', 'class' => 'footer-places' ] );
296 foreach ( $validFooterLinks as $aLink ) {
297 $html .= Html::rawElement(
298 'li',
299 [ 'id' => Sanitizer::escapeIdForAttribute( $aLink ) ],
300 $this->get( $aLink )
301 );
302 }
303 $html .= Html::closeElement( 'ul' );
304 }
305
306 $html .= $this->getClear() . $footerEnd;
307
308 return $html;
309 }
310
317 protected function getClear() {
318 return Html::element( 'div', [ 'class' => 'visualClear' ] );
319 }
320
336 public function getIndicators() {
337 $out = "<div class=\"mw-indicators\">\n";
338 foreach ( $this->data['indicators'] as $id => $content ) {
339 $out .= Html::rawElement(
340 'div',
341 [
342 'id' => Sanitizer::escapeIdForAttribute( "mw-indicator-$id" ),
343 'class' => 'mw-indicator',
344 ],
345 $content
346 ) .
347 // Add whitespace between the <div>s because
348 // they get displayed with display: inline-block
349 "\n";
350 }
351 $out .= "</div>\n";
352 return $out;
353 }
354}
355
357class_alias( BaseTemplate::class, 'BaseTemplate' );
This class is a collection of static functions that serve two purposes:
Definition Html.php:57
The Message class deals with fetching and processing of interface message into a variety of formats.
Definition Message.php:157
HTML sanitizer for MediaWiki.
Definition Sanitizer.php:46
Extended QuickTemplate with additional MediaWiki-specific helper methods.
makeSearchInput( $attrs=[])
Wrapper for Skin method.
getIndicators()
Get the suggested HTML for page status indicators: icons (or short text snippets) usually displayed i...
getClear()
Get a div with the core visualClear class, for clearing floats.
makeLink( $key, $item, $options=[])
Wrapper for Skin method.
makeListItem( $key, $item, $options=[])
Wrapper for Skin method.
getFooterLinks( $option=null)
Returns an array of footerlinks trimmed down to only those footer links that are valid.
makeSearchButton( $mode, $attrs=[])
Wrapper for Skin method.
getFooter( $iconStyle='icononly', $linkStyle='flat')
Renderer for getFooterLinks.
getMsg( $name,... $params)
Get a Message object with its context set.
PHP-based skin template that holds data.
getSkin()
Get the Skin object related to this object.
Value object representing a message parameter that consists of a list of values.
element(SerializerNode $parent, SerializerNode $node, $contents)
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Ge...