MediaWiki REL1_39
BaseTemplate.php
Go to the documentation of this file.
1<?php
21use Wikimedia\WrappedString;
22use Wikimedia\WrappedStringList;
23
33abstract class BaseTemplate extends QuickTemplate {
34
42 public function getMsg( $name, ...$params ) {
43 return $this->getSkin()->msg( $name, ...$params );
44 }
45
46 public function msg( $str ) {
47 echo $this->getMsg( $str )->escaped();
48 }
49
61 public function getToolbox() {
62 wfDeprecated( __METHOD__, '1.35' );
63
64 $toolbox = $this->getSkin()->makeToolbox(
65 $this->data['nav_urls'],
66 $this->data['feeds']
67 );
68
69 // Merge content that might be added to the toolbox section by hook
70 if ( isset( $this->data['sidebar']['TOOLBOX'] ) ) {
71 $toolbox = array_merge( $toolbox, $this->data['sidebar']['TOOLBOX'] ?? [] );
72 }
73
74 return $toolbox;
75 }
76
81 public function getPersonalTools() {
82 return $this->getSkin()->getPersonalToolsForMakeListItem( $this->get( 'personal_urls' ) );
83 }
84
90 protected function getSidebar( $options = [] ) {
91 // Force the rendering of the following portals
92 $sidebar = $this->data['sidebar'];
93 if ( !isset( $sidebar['SEARCH'] ) ) {
94 $sidebar['SEARCH'] = true;
95 }
96 if ( !isset( $sidebar['TOOLBOX'] ) ) {
97 $sidebar['TOOLBOX'] = true;
98 }
99 if ( !isset( $sidebar['LANGUAGES'] ) ) {
100 $sidebar['LANGUAGES'] = true;
101 }
102
103 if ( !isset( $options['search'] ) || $options['search'] !== true ) {
104 unset( $sidebar['SEARCH'] );
105 }
106 if ( isset( $options['toolbox'] ) && $options['toolbox'] === false ) {
107 unset( $sidebar['TOOLBOX'] );
108 }
109 if ( isset( $options['languages'] ) && $options['languages'] === false ) {
110 unset( $sidebar['LANGUAGES'] );
111 }
112
113 $boxes = [];
114 foreach ( $sidebar as $boxName => $content ) {
115 if ( $content === false ) {
116 continue;
117 }
118 switch ( $boxName ) {
119 case 'SEARCH':
120 // Search is a special case, skins should custom implement this
121 $boxes[$boxName] = [
122 'id' => 'p-search',
123 'header' => $this->getMsg( 'search' )->text(),
124 'generated' => false,
125 'content' => true,
126 ];
127 break;
128 case 'TOOLBOX':
129 $msgObj = $this->getMsg( 'toolbox' );
130 $boxes[$boxName] = [
131 'id' => 'p-tb',
132 'header' => $msgObj->exists() ? $msgObj->text() : 'toolbox',
133 'generated' => false,
134 'content' => $content,
135 ];
136 break;
137 case 'LANGUAGES':
138 if ( $this->data['language_urls'] !== false ) {
139 $msgObj = $this->getMsg( 'otherlanguages' );
140 $boxes[$boxName] = [
141 'id' => 'p-lang',
142 'header' => $msgObj->exists() ? $msgObj->text() : 'otherlanguages',
143 'generated' => false,
144 'content' => $this->data['language_urls'] ?: [],
145 ];
146 }
147 break;
148 default:
149 $msgObj = $this->getMsg( $boxName );
150 $boxes[$boxName] = [
151 'id' => "p-$boxName",
152 'header' => $msgObj->exists() ? $msgObj->text() : $boxName,
153 'generated' => true,
154 'content' => $content,
155 ];
156 break;
157 }
158 }
159
160 if ( isset( $options['htmlOnly'] ) && $options['htmlOnly'] === true ) {
161 foreach ( $boxes as $boxName => $box ) {
162 if ( is_array( $box['content'] ) ) {
163 $content = '<ul>';
164 foreach ( $box['content'] as $key => $val ) {
165 $content .= "\n " . $this->getSkin()->makeListItem( $key, $val );
166 }
167 $content .= "\n</ul>\n";
168 $boxes[$boxName]['content'] = $content;
169 }
170 }
171 }
172
173 return $boxes;
174 }
175
180 protected function renderAfterPortlet( $name ) {
181 wfDeprecated( __METHOD__, '1.35' );
182 echo $this->getAfterPortlet( $name );
183 }
184
195 protected function getAfterPortlet( $name ) {
196 wfDeprecated( __METHOD__, '1.35' );
197 $html = '';
198 $content = '';
199 $this->getHookRunner()->onBaseTemplateAfterPortlet( $this, $name, $content );
200 $content .= $this->getSkin()->getAfterPortlet( $name );
201
202 if ( $content !== '' ) {
203 $html = Html::rawElement(
204 'div',
205 [ 'class' => [ 'after-portlet', 'after-portlet-' . $name ] ],
207 );
208 }
209
210 return $html;
211 }
212
217 protected function makeLink( $key, $item, $options = [] ) {
218 return $this->getSkin()->makeLink( $key, $item, $options );
219 }
220
225 public function makeListItem( $key, $item, $options = [] ) {
226 return $this->getSkin()->makeListItem( $key, $item, $options );
227 }
228
232 protected function makeSearchInput( $attrs = [] ) {
233 return $this->getSkin()->makeSearchInput( $attrs );
234 }
235
239 protected function makeSearchButton( $mode, $attrs = [] ) {
240 return $this->getSkin()->makeSearchButton( $mode, $attrs );
241 }
242
252 protected function getFooterLinks( $option = null ) {
253 $footerlinks = $this->get( 'footerlinks' );
254
255 // Reduce footer links down to only those which are being used
256 $validFooterLinks = [];
257 foreach ( $footerlinks as $category => $links ) {
258 $validFooterLinks[$category] = [];
259 foreach ( $links as $link ) {
260 if ( isset( $this->data[$link] ) && $this->data[$link] ) {
261 $validFooterLinks[$category][] = $link;
262 }
263 }
264 if ( count( $validFooterLinks[$category] ) <= 0 ) {
265 unset( $validFooterLinks[$category] );
266 }
267 }
268
269 if ( $option == 'flat' && count( $validFooterLinks ) ) {
270 // fold footerlinks into a single array using a bit of trickery
271 $validFooterLinks = array_merge( ...array_values( $validFooterLinks ) );
272 }
273
274 return $validFooterLinks;
275 }
276
291 protected function getFooterIcons( $option = null ) {
292 wfDeprecated( __METHOD__, '1.35' );
293 // Generate additional footer icons
294 $footericons = $this->get( 'footericons' );
295
296 if ( $option == 'icononly' ) {
297 // Unset any icons which don't have an image
298 $this->unsetIconsWithoutImages( $footericons );
299 } elseif ( $option == 'nocopyright' ) {
300 unset( $footericons['copyright'] );
301 }
302
303 return $footericons;
304 }
305
312 private function unsetIconsWithoutImages( array &$icons ) {
313 // Unset any icons which don't have an image
314 foreach ( $icons as $iconsKey => &$iconsBlock ) {
315 foreach ( $iconsBlock as $iconKey => $icon ) {
316 if ( !is_string( $icon ) && !isset( $icon['src'] ) ) {
317 unset( $iconsBlock[$iconKey] );
318 }
319 }
320 if ( $iconsBlock === [] ) {
321 unset( $icons[$iconsKey] );
322 }
323 }
324 }
325
336 protected function getFooter( $iconStyle = 'icononly', $linkStyle = 'flat' ) {
337 $validFooterIcons = $this->get( 'footericons' );
338 if ( $iconStyle === 'icononly' ) {
339 $this->unsetIconsWithoutImages( $validFooterIcons );
340 } else {
341 // take a deprecated unsupported path
342 $validFooterIcons = $this->getFooterIcons( $iconStyle );
343 }
344 $validFooterLinks = $this->getFooterLinks( $linkStyle );
345
346 $html = '';
347
348 if ( count( $validFooterIcons ) + count( $validFooterLinks ) > 0 ) {
349 $html .= Html::openElement( 'div', [
350 'id' => 'footer-bottom',
351 'class' => 'mw-footer',
352 'role' => 'contentinfo',
353 'lang' => $this->get( 'userlang' ),
354 'dir' => $this->get( 'dir' )
355 ] );
356 $footerEnd = Html::closeElement( 'div' );
357 } else {
358 $footerEnd = '';
359 }
360 foreach ( $validFooterIcons as $blockName => $footerIcons ) {
361 $html .= Html::openElement( 'div', [
362 'id' => Sanitizer::escapeIdForAttribute( "f-{$blockName}ico" ),
363 'class' => 'footer-icons'
364 ] );
365 foreach ( $footerIcons as $icon ) {
366 $html .= $this->getSkin()->makeFooterIcon( $icon );
367 }
368 $html .= Html::closeElement( 'div' );
369 }
370 if ( count( $validFooterLinks ) > 0 ) {
371 $html .= Html::openElement( 'ul', [ 'id' => 'f-list', 'class' => 'footer-places' ] );
372 foreach ( $validFooterLinks as $aLink ) {
373 $html .= Html::rawElement(
374 'li',
375 [ 'id' => Sanitizer::escapeIdForAttribute( $aLink ) ],
376 $this->get( $aLink )
377 );
378 }
379 $html .= Html::closeElement( 'ul' );
380 }
381
382 $html .= $this->getClear() . $footerEnd;
383
384 return $html;
385 }
386
393 protected function getClear() {
394 return Html::element( 'div', [ 'class' => 'visualClear' ] );
395 }
396
412 public function getIndicators() {
413 $out = "<div class=\"mw-indicators\">\n";
414 foreach ( $this->data['indicators'] as $id => $content ) {
415 $out .= Html::rawElement(
416 'div',
417 [
418 'id' => Sanitizer::escapeIdForAttribute( "mw-indicator-$id" ),
419 'class' => 'mw-indicator',
420 ],
422 ) .
423 // Add whitespace between the <div>s because
424 // they get displayed with display: inline-block
425 "\n";
426 }
427 $out .= "</div>\n";
428 return $out;
429 }
430
435 protected function printTrail() {
436 wfDeprecated( __METHOD__, '1.39' );
437 echo $this->getTrail();
438 }
439
449 public function getTrail() {
450 wfDeprecated( __METHOD__, '1.39' );
451 $skin = $this->getSkin();
452 $options = $skin->getOptions();
453
454 return $options['bodyOnly'] ? '' : WrappedString::join( "\n", [
455 MWDebug::getDebugHTML( $skin->getContext() ),
456 $this->get( 'bottomscripts' ),
457 $this->get( 'reporttime' )
458 ] );
459 }
460}
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
Extended QuickTemplate with additional MediaWiki-specific helper methods.
getFooterLinks( $option=null)
Returns an array of footerlinks trimmed down to only those footer links that are valid.
makeSearchButton( $mode, $attrs=[])
renderAfterPortlet( $name)
getToolbox()
Create an array of common toolbox items from the data in the quicktemplate stored by SkinTemplate and...
getTrail()
Get the basic end-page trail including bottomscripts, reporttime, and debug stuff.
printTrail()
Output getTrail.
makeLink( $key, $item, $options=[])
getSidebar( $options=[])
getFooterIcons( $option=null)
Returns an array of footer icons filtered down by options relevant to how the skin wishes to display ...
makeListItem( $key, $item, $options=[])
getMsg( $name,... $params)
Get a Message object with its context set.
getIndicators()
Get the suggested HTML for page status indicators: icons (or short text snippets) usually displayed i...
makeSearchInput( $attrs=[])
getFooter( $iconStyle='icononly', $linkStyle='flat')
Renderer for getFooterIcons and getFooterLinks.
getClear()
Get a div with the core visualClear class, for clearing floats.
getAfterPortlet( $name)
Allows extensions to hook into known portlets and add stuff to them.
PHP-based skin template that holds data.
getSkin()
Get the Skin object related to this object.
$content
Definition router.php:76