MediaWiki REL1_33
VectorTemplate.php
Go to the documentation of this file.
1<?php
30
34 public function execute() {
35 $this->data['namespace_urls'] = $this->data['content_navigation']['namespaces'];
36 $this->data['view_urls'] = $this->data['content_navigation']['views'];
37 $this->data['action_urls'] = $this->data['content_navigation']['actions'];
38 $this->data['variant_urls'] = $this->data['content_navigation']['variants'];
39
40 // Move the watch/unwatch star outside of the collapsed "actions" menu to the main "views" menu
41 if ( $this->config->get( 'VectorUseIconWatch' ) ) {
42 $mode = $this->getSkin()->getUser()->isWatched( $this->getSkin()->getRelevantTitle() )
43 ? 'unwatch'
44 : 'watch';
45
46 if ( isset( $this->data['action_urls'][$mode] ) ) {
47 $this->data['view_urls'][$mode] = $this->data['action_urls'][$mode];
48 unset( $this->data['action_urls'][$mode] );
49 }
50 }
51
52 // Naming conventions for Mustache parameters:
53 // - Prefix "is" for boolean values.
54 // - Prefix "msg-" for interface messages.
55 // - Prefix "page-" for data relating to the current page (e.g. Title, WikiPage, or OutputPage).
56 // - Prefix "html-" for raw HTML (in front of other keys, if applicable).
57 // - Conditional values are null if absent.
58 $params = [
59 'html-headelement' => $this->get( 'headelement', '' ),
60 'html-sitenotice' => $this->get( 'sitenotice', null ),
61 'html-indicators' => $this->getIndicators(),
62 'page-langcode' => $this->getSkin()->getTitle()->getPageViewLanguage()->getHtmlCode(),
63 'page-isarticle' => (bool)$this->data['isarticle'],
64
65 // Remember that the string '0' is a valid title.
66 // From OutputPage::getPageTitle, via ::setPageTitle().
67 'html-title' => $this->get( 'title', '' ),
68
69 'html-prebodyhtml' => $this->get( 'prebodyhtml', '' ),
70 'msg-tagline' => $this->getMsg( 'tagline' )->text(),
71 // TODO: mediawiki/SkinTemplate should expose langCode and langDir properly.
72 'html-userlangattributes' => $this->get( 'userlangattributes', '' ),
73 // From OutputPage::getSubtitle()
74 'html-subtitle' => $this->get( 'subtitle', '' ),
75
76 // TODO: Use directly Skin::getUndeleteLink() directly.
77 // Always returns string, cast to null if empty.
78 'html-undelete' => $this->get( 'undelete', null ) ?: null,
79
80 // From Skin::getNewtalks(). Always returns string, cast to null if empty.
81 'html-newtalk' => $this->get( 'newtalk', '' ) ?: null,
82
83 'msg-jumptonavigation' => $this->getMsg( 'vector-jumptonavigation' )->text(),
84 'msg-jumptosearch' => $this->getMsg( 'vector-jumptosearch' )->text(),
85
86 // Result of OutputPage::addHTML calls
87 'html-bodycontent' => $this->get( 'bodycontent' ),
88
89 'html-printfooter' => $this->get( 'printfooter', null ),
90 'html-catlinks' => $this->get( 'catlinks', '' ),
91 'html-dataAfterContent' => $this->get( 'dataAfterContent', '' ),
92 // From MWDebug::getHTMLDebugLog (when $wgShowDebug is enabled)
93 'html-debuglog' => $this->get( 'debughtml', '' ),
94 // From BaseTemplate::getTrail (handles bottom JavaScript)
95 'html-printtail' => $this->getTrail(),
96 ];
97
98 // TODO: Convert the rest to Mustache
99 ob_start();
100 ?>
101 <div id="mw-navigation">
102 <h2><?php $this->msg( 'navigation-heading' ) ?></h2>
103 <div id="mw-head">
104 <?php $this->renderNavigation( [ 'PERSONAL' ] ); ?>
105 <div id="left-navigation">
106 <?php $this->renderNavigation( [ 'NAMESPACES', 'VARIANTS' ] ); ?>
107 </div>
108 <div id="right-navigation">
109 <?php $this->renderNavigation( [ 'VIEWS', 'ACTIONS', 'SEARCH' ] ); ?>
110 </div>
111 </div>
112 <div id="mw-panel">
113 <div id="p-logo" role="banner"><a class="mw-wiki-logo" href="<?php
114 echo htmlspecialchars( $this->data['nav_urls']['mainpage']['href'] )
115 ?>"<?php
116 echo Xml::expandAttributes( Linker::tooltipAndAccesskeyAttribs( 'p-logo' ) )
117 ?>></a></div>
118 <?php $this->renderPortals( $this->data['sidebar'] ); ?>
119 </div>
120 </div>
121 <?php Hooks::run( 'VectorBeforeFooter' ); ?>
122 <div id="footer" role="contentinfo"<?php $this->html( 'userlangattributes' ) ?>>
123 <?php
124 foreach ( $this->getFooterLinks() as $category => $links ) {
125 ?>
126 <ul id="footer-<?php echo $category ?>">
127 <?php
128 foreach ( $links as $link ) {
129 ?>
130 <li id="footer-<?php echo $category ?>-<?php echo $link ?>"><?php $this->html( $link ) ?></li>
131 <?php
132 }
133 ?>
134 </ul>
135 <?php
136 }
137 ?>
138 <?php $footericons = $this->getFooterIcons( 'icononly' );
139 if ( count( $footericons ) > 0 ) {
140 ?>
141 <ul id="footer-icons" class="noprint">
142 <?php
143 foreach ( $footericons as $blockName => $footerIcons ) {
144 ?>
145 <li id="footer-<?php echo htmlspecialchars( $blockName ); ?>ico">
146 <?php
147 foreach ( $footerIcons as $icon ) {
148 echo $this->getSkin()->makeFooterIcon( $icon );
149 }
150 ?>
151 </li>
152 <?php
153 }
154 ?>
155 </ul>
156 <?php
157 }
158 ?>
159 <div style="clear: both;"></div>
160 </div>
161 <?php
162 $params['html-unported'] = ob_get_contents();
163 ob_end_clean();
164
165 // Prepare and output the HTML response
166 $templates = new TemplateParser( __DIR__ . '/templates' );
167 echo $templates->processTemplate( 'index', $params );
168 }
169
175 protected function renderPortals( array $portals ) {
176 // Force the rendering of the following portals
177 if ( !isset( $portals['TOOLBOX'] ) ) {
178 $portals['TOOLBOX'] = true;
179 }
180 if ( !isset( $portals['LANGUAGES'] ) ) {
181 $portals['LANGUAGES'] = true;
182 }
183 // Render portals
184 foreach ( $portals as $name => $content ) {
185 if ( $content === false ) {
186 continue;
187 }
188
189 // Numeric strings gets an integer when set as key, cast back - T73639
190 $name = (string)$name;
191
192 switch ( $name ) {
193 case 'SEARCH':
194 break;
195 case 'TOOLBOX':
196 $this->renderPortal( 'tb', $this->getToolbox(), 'toolbox', 'SkinTemplateToolboxEnd' );
197 Hooks::run( 'VectorAfterToolbox' );
198 break;
199 case 'LANGUAGES':
200 if ( $this->data['language_urls'] !== false ) {
201 $this->renderPortal( 'lang', $this->data['language_urls'], 'otherlanguages' );
202 }
203 break;
204 default:
205 $this->renderPortal( $name, $content );
206 break;
207 }
208 }
209 }
210
217 protected function renderPortal( $name, $content, $msg = null, $hook = null ) {
218 if ( $msg === null ) {
219 $msg = $name;
220 }
221 $msgObj = $this->getMsg( $msg );
222 $labelId = Sanitizer::escapeIdForAttribute( "p-$name-label" );
223 ?>
224 <div class="portal" role="navigation" id="<?php
225 echo htmlspecialchars( Sanitizer::escapeIdForAttribute( "p-$name" ) )
226 ?>"<?php
227 echo Linker::tooltip( 'p-' . $name )
228 ?> aria-labelledby="<?php echo htmlspecialchars( $labelId ) ?>">
229 <h3<?php $this->html( 'userlangattributes' ) ?> id="<?php echo htmlspecialchars( $labelId )
230 ?>"><?php
231 echo htmlspecialchars( $msgObj->exists() ? $msgObj->text() : $msg );
232 ?></h3>
233 <div class="body">
234 <?php
235 if ( is_array( $content ) ) {
236 ?>
237 <ul>
238 <?php
239 foreach ( $content as $key => $val ) {
240 echo $this->makeListItem( $key, $val );
241 }
242 if ( $hook !== null ) {
243 // Avoid PHP 7.1 warning
244 $skin = $this;
245 Hooks::run( $hook, [ &$skin, true ] );
246 }
247 ?>
248 </ul>
249 <?php
250 } else {
251 // Allow raw HTML block to be defined by extensions
252 echo $content;
253 }
254
255 $this->renderAfterPortlet( $name );
256 ?>
257 </div>
258 </div>
259 <?php
260 }
261
268 protected function renderNavigation( array $elements ) {
269 // Render elements
270 foreach ( $elements as $name => $element ) {
271 switch ( $element ) {
272 case 'NAMESPACES':
273 ?>
274 <div id="p-namespaces" role="navigation" class="vectorTabs<?php
275 if ( count( $this->data['namespace_urls'] ) == 0 ) {
276 echo ' emptyPortlet';
277 }
278 ?>" aria-labelledby="p-namespaces-label">
279 <h3 id="p-namespaces-label"><?php $this->msg( 'namespaces' ) ?></h3>
280 <ul<?php $this->html( 'userlangattributes' ) ?>>
281 <?php
282 foreach ( $this->data['namespace_urls'] as $key => $item ) {
283 echo $this->makeListItem( $key, $item, [
284 'vector-wrap' => true,
285 ] );
286 }
287 ?>
288 </ul>
289 </div>
290 <?php
291 break;
292 case 'VARIANTS':
293 ?>
294 <div id="p-variants" role="navigation" class="vectorMenu<?php
295 if ( count( $this->data['variant_urls'] ) == 0 ) {
296 echo ' emptyPortlet';
297 }
298 ?>" aria-labelledby="p-variants-label">
299 <?php
300 // Replace the label with the name of currently chosen variant, if any
301 $variantLabel = $this->getMsg( 'variants' )->text();
302 foreach ( $this->data['variant_urls'] as $item ) {
303 if ( isset( $item['class'] ) && stripos( $item['class'], 'selected' ) !== false ) {
304 $variantLabel = $item['text'];
305 break;
306 }
307 }
308 ?>
309 <input type="checkbox" class="vectorMenuCheckbox" aria-labelledby="p-variants-label" />
310 <h3 id="p-variants-label">
311 <span><?php echo htmlspecialchars( $variantLabel ) ?></span>
312 </h3>
313 <ul class="menu">
314 <?php
315 foreach ( $this->data['variant_urls'] as $key => $item ) {
316 echo $this->makeListItem( $key, $item );
317 }
318 ?>
319 </ul>
320 </div>
321 <?php
322 break;
323 case 'VIEWS':
324 ?>
325 <div id="p-views" role="navigation" class="vectorTabs<?php
326 if ( count( $this->data['view_urls'] ) == 0 ) {
327 echo ' emptyPortlet';
328 }
329 ?>" aria-labelledby="p-views-label">
330 <h3 id="p-views-label"><?php $this->msg( 'views' ) ?></h3>
331 <ul<?php $this->html( 'userlangattributes' ) ?>>
332 <?php
333 foreach ( $this->data['view_urls'] as $key => $item ) {
334 echo $this->makeListItem( $key, $item, [
335 'vector-wrap' => true,
336 'vector-collapsible' => true,
337 ] );
338 }
339 ?>
340 </ul>
341 </div>
342 <?php
343 break;
344 case 'ACTIONS':
345 ?>
346 <div id="p-cactions" role="navigation" class="vectorMenu<?php
347 if ( count( $this->data['action_urls'] ) == 0 ) {
348 echo ' emptyPortlet';
349 }
350 ?>" aria-labelledby="p-cactions-label">
351 <input type="checkbox" class="vectorMenuCheckbox" aria-labelledby="p-cactions-label" />
352 <h3 id="p-cactions-label"><span><?php
353 $this->msg( 'vector-more-actions' )
354 ?></span></h3>
355 <ul class="menu"<?php $this->html( 'userlangattributes' ) ?>>
356 <?php
357 foreach ( $this->data['action_urls'] as $key => $item ) {
358 echo $this->makeListItem( $key, $item );
359 }
360 ?>
361 </ul>
362 </div>
363 <?php
364 break;
365 case 'PERSONAL':
366 ?>
367 <div id="p-personal" role="navigation"<?php
368 if ( count( $this->data['personal_urls'] ) == 0 ) {
369 echo ' class="emptyPortlet"';
370 }
371 ?> aria-labelledby="p-personal-label">
372 <h3 id="p-personal-label"><?php $this->msg( 'personaltools' ) ?></h3>
373 <ul<?php $this->html( 'userlangattributes' ) ?>>
374 <?php
375 $notLoggedIn = '';
376
377 if ( !$this->getSkin()->getUser()->isLoggedIn() &&
378 User::groupHasPermission( '*', 'edit' )
379 ) {
380 $notLoggedIn =
381 Html::element( 'li',
382 [ 'id' => 'pt-anonuserpage' ],
383 $this->getMsg( 'notloggedin' )->text()
384 );
385 }
386
387 $personalTools = $this->getPersonalTools();
388
389 $langSelector = '';
390 if ( array_key_exists( 'uls', $personalTools ) ) {
391 $langSelector = $this->makeListItem( 'uls', $personalTools[ 'uls' ] );
392 unset( $personalTools[ 'uls' ] );
393 }
394
395 echo $langSelector;
396 echo $notLoggedIn;
397 foreach ( $personalTools as $key => $item ) {
398 echo $this->makeListItem( $key, $item );
399 }
400 ?>
401 </ul>
402 </div>
403 <?php
404 break;
405 case 'SEARCH':
406 ?>
407 <div id="p-search" role="search">
408 <h3<?php $this->html( 'userlangattributes' ) ?>>
409 <label for="searchInput"><?php $this->msg( 'search' ) ?></label>
410 </h3>
411 <form action="<?php $this->text( 'wgScript' ) ?>" id="searchform">
412 <div<?php echo $this->config->get( 'VectorUseSimpleSearch' ) ? ' id="simpleSearch"' : '' ?>>
413 <?php
414 echo $this->makeSearchInput( [ 'id' => 'searchInput' ] );
415 echo Html::hidden( 'title', $this->get( 'searchtitle' ) );
416 /* We construct two buttons (for 'go' and 'fulltext' search modes),
417 * but only one will be visible and actionable at a time (they are
418 * overlaid on top of each other in CSS).
419 * * Browsers will use the 'fulltext' one by default (as it's the
420 * first in tree-order), which is desirable when they are unable
421 * to show search suggestions (either due to being broken or
422 * having JavaScript turned off).
423 * * The mediawiki.searchSuggest module, after doing tests for the
424 * broken browsers, removes the 'fulltext' button and handles
425 * 'fulltext' search itself; this will reveal the 'go' button and
426 * cause it to be used.
427 */
428 echo $this->makeSearchButton(
429 'fulltext',
430 [ 'id' => 'mw-searchButton', 'class' => 'searchButton mw-fallbackSearchButton' ]
431 );
432 echo $this->makeSearchButton(
433 'go',
434 [ 'id' => 'searchButton', 'class' => 'searchButton' ]
435 );
436 ?>
437 </div>
438 </form>
439 </div>
440 <?php
441
442 break;
443 }
444 }
445 }
446
450 public function makeLink( $key, $item, $options = [] ) {
451 $html = parent::makeLink( $key, $item, $options );
452 // Add an extra wrapper because our CSS is weird
453 if ( isset( $options['vector-wrap'] ) && $options['vector-wrap'] ) {
454 $html = Html::rawElement( 'span', [], $html );
455 }
456 return $html;
457 }
458
462 public function makeListItem( $key, $item, $options = [] ) {
463 // For fancy styling of watch/unwatch star
464 if (
465 $this->config->get( 'VectorUseIconWatch' )
466 && ( $key === 'watch' || $key === 'unwatch' )
467 ) {
468 $item['class'] = rtrim( 'icon ' . $item['class'], ' ' );
469 $item['primary'] = true;
470 }
471
472 // Add CSS class 'collapsible' to links which are not marked as "primary"
473 if (
474 isset( $options['vector-collapsible'] ) && $options['vector-collapsible'] ) {
475 $item['class'] = rtrim( 'collapsible ' . $item['class'], ' ' );
476 }
477
478 // We don't use this, prevent it from popping up in HTML output
479 unset( $item['redundant'] );
480
481 return parent::makeListItem( $key, $item, $options );
482 }
483}
shown</td >< td > a href
This list may contain false positives That usually means there is additional text with links below the first Each row contains links to the first and second as well as the first line of the second redirect text
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two and(2) offer you this license which gives you legal permission to copy
New base template for a skin's template extended from QuickTemplate this class features helper method...
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.
getTrail()
Get the basic end-page trail including bottomscripts, reporttime, and debug stuff.
getPersonalTools()
Create an array of personal tools items from the data in the quicktemplate stored by SkinTemplate.
getFooterIcons( $option=null)
Returns an array of footer icons filtered down by options relevant to how the skin wishes to display ...
getMsg( $name)
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=[])
static tooltip( $name, $options=null)
Returns raw bits of HTML, use titleAttrib()
Definition Linker.php:2158
static tooltipAndAccesskeyAttribs( $name, array $msgParams=[], $options=null)
Returns the attributes for the tooltip and access key.
Definition Linker.php:2130
getSkin()
Get the Skin object related to this object.
static groupHasPermission( $group, $role)
Check, if the given group has the given permission.
Definition User.php:5062
QuickTemplate subclass for Vector.
makeLink( $key, $item, $options=[])
@inheritDoc
makeListItem( $key, $item, $options=[])
@inheritDoc
renderNavigation(array $elements)
Render one or more navigations elements by name, automatically reversed by css when UI is in RTL mode...
renderPortals(array $portals)
Render a series of portals.
execute()
Outputs the entire contents of the HTML page.
renderPortal( $name, $content, $msg=null, $hook=null)
This code would result in ircNotify being run twice when an article is and once for brion Hooks can return three possible true was required This is the default since MediaWiki *some string
Definition hooks.txt:181
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped & $options
Definition hooks.txt:1999
null means default in associative array form
Definition hooks.txt:1994
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not null
Definition hooks.txt:783
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses & $html
Definition hooks.txt:2011
usually copyright or history_copyright This message must be in HTML not wikitext & $link
Definition hooks.txt:3069
Allows to change the fields on the form that will be generated $name
Definition hooks.txt:271
The wiki should then use memcached to cache various data To use multiple just add more items to the array To increase the weight of a make its entry a array("192.168.0.1:11211", 2))
$content
This document describes the state of Postgres support in and is fairly well maintained The main code is very well while extensions are very hit and miss it is probably the most supported database after MySQL Much of the work in making MediaWiki database agnostic came about through the work of creating Postgres but without copying over all the usage comments General notes on the but these can almost always be programmed around *Although Postgres has a true BOOLEAN type
Definition postgres.txt:30
$params
Bar style