3 * Cologne Blue: A nicer-looking alternative to Standard.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
25 if( !defined( 'MEDIAWIKI' ) ) {
33 class SkinCologneBlue
extends SkinTemplate
{
34 var $skinname = 'cologneblue', $stylename = 'cologneblue',
35 $template = 'CologneBlueTemplate';
36 var $useHeadElement = true;
39 * @param $out OutputPage
41 function setupSkinUserCss( OutputPage
$out ){
42 $out->addModuleStyles( 'mediawiki.legacy.shared' );
43 $out->addModuleStyles( 'mediawiki.legacy.oldshared' );
44 $out->addModuleStyles( 'skins.cologneblue' );
49 class CologneBlueTemplate
extends BaseTemplate
{
51 $this->html( 'headelement' );
52 echo $this->beforeContent();
53 $this->html( 'bodytext' );
55 echo $this->afterContent();
56 $this->html( 'dataAfterContent' );
58 echo "\n</body></html>";
63 * Language/charset variant links for classic-style skins
66 function variantLinks() {
69 /* show links to different language variants */
70 global $wgDisableLangConversion, $wgLang;
72 $title = $this->getSkin()->getTitle();
73 $lang = $title->getPageLanguage();
74 $variants = $lang->getVariants();
76 if ( !$wgDisableLangConversion && sizeof( $variants ) > 1
77 && !$title->isSpecialPage() ) {
78 foreach ( $variants as $code ) {
79 $varname = $lang->getVariantname( $code );
81 if ( $varname == 'disable' ) {
84 $s = $wgLang->pipeList( array(
86 '<a href="' . htmlspecialchars( $title->getLocalURL( 'variant=' . $code ) ) . '" lang="' . $code . '" hreflang="' . $code . '">' . htmlspecialchars( $varname ) . '</a>'
94 function otherLanguages() {
95 global $wgOut, $wgLang, $wgHideInterlanguageLinks;
97 if ( $wgHideInterlanguageLinks ) {
101 $a = $wgOut->getLanguageLinks();
103 if ( 0 == count( $a ) ) {
107 $s = wfMessage( 'otherlanguages' )->text() . wfMessage( 'colon-separator' )->text();
110 if ( $wgLang->isRTL() ) {
111 $s .= '<span dir="ltr">';
114 foreach ( $a as $l ) {
116 $s .= wfMessage( 'pipe-separator' )->escaped();
121 $nt = Title
::newFromText( $l );
122 $text = Language
::fetchLanguageName( $nt->getInterwiki() );
124 $s .= Html
::element( 'a',
125 array( 'href' => $nt->getFullURL(), 'title' => $nt->getText(), 'class' => "external" ),
126 $text == '' ?
$l : $text );
129 if ( $wgLang->isRTL() ) {
137 function pageTitleLinks() {
141 $footlinks = $this->getFooterLinks();
143 foreach ( $footlinks['places'] as $item ) {
144 $s[] = $this->data
[$item];
147 return $wgLang->pipeList( $s );
150 function bottomLinks() {
151 global $wgOut, $wgUser;
152 $sep = wfMessage( 'pipe-separator' )->escaped() . "\n";
155 if ( $wgOut->isArticleRelated() ) {
156 $element[] = '<strong>' . $this->editThisPage() . '</strong>';
158 if ( $wgUser->isLoggedIn() ) {
159 $element[] = $this->watchThisPage();
162 $element[] = $this->talkLink();
163 $element[] = $this->historyLink();
164 $element[] = $this->whatLinksHere();
165 $element[] = $this->watchPageLinksLink();
167 $title = $this->getSkin()->getTitle();
170 $title->getNamespace() == NS_USER ||
171 $title->getNamespace() == NS_USER_TALK
173 $id = User
::idFromName( $title->getText() );
174 $ip = User
::isIP( $title->getText() );
176 # Both anons and non-anons have contributions list
178 $element[] = $this->userContribsLink();
181 if ( $this->getSkin()->showEmailUser( $id ) ) {
182 $element[] = $this->emailUserLink();
186 $s = implode( $element, $sep );
188 if ( $title->getArticleID() ) {
191 // Delete/protect/move links for privileged users
192 if ( $wgUser->isAllowed( 'delete' ) ) {
193 $s .= $this->deleteThisPage();
196 if ( $wgUser->isAllowed( 'protect' ) ) {
197 $s .= $sep . $this->protectThisPage();
200 if ( $wgUser->isAllowed( 'move' ) ) {
201 $s .= $sep . $this->moveThisPage();
205 $s .= "<br />\n" . $this->otherLanguages();
211 function editThisPage() {
214 if ( !$wgOut->isArticleRelated() ) {
215 $s = wfMessage( 'protectedpage' )->text();
217 $title = $this->getSkin()->getTitle();
218 if ( $title->quickUserCan( 'edit' ) && $title->exists() ) {
219 $t = wfMessage( 'editthispage' )->text();
220 } elseif ( $title->quickUserCan( 'create' ) && !$title->exists() ) {
221 $t = wfMessage( 'create-this-page' )->text();
223 $t = wfMessage( 'viewsource' )->text();
226 $s = Linker
::linkKnown(
230 $this->getSkin()->editUrlOptions()
237 function deleteThisPage() {
238 global $wgUser, $wgRequest;
240 $diff = $wgRequest->getVal( 'diff' );
241 $title = $this->getSkin()->getTitle();
243 if ( $title->getArticleID() && ( !$diff ) && $wgUser->isAllowed( 'delete' ) ) {
244 $t = wfMessage( 'deletethispage' )->text();
246 $s = Linker
::linkKnown(
250 array( 'action' => 'delete' )
259 function protectThisPage() {
260 global $wgUser, $wgRequest;
262 $diff = $wgRequest->getVal( 'diff' );
263 $title = $this->getSkin()->getTitle();
265 if ( $title->getArticleID() && ( ! $diff ) && $wgUser->isAllowed( 'protect' ) ) {
266 if ( $title->isProtected() ) {
267 $text = wfMessage( 'unprotectthispage' )->text();
268 $query = array( 'action' => 'unprotect' );
270 $text = wfMessage( 'protectthispage' )->text();
271 $query = array( 'action' => 'protect' );
274 $s = Linker
::linkKnown(
287 function watchThisPage() {
288 global $wgOut, $wgUser;
291 $title = $this->getSkin()->getTitle();
293 if ( $wgOut->isArticleRelated() ) {
294 if ( $wgUser->isWatched( $title ) ) {
295 $text = wfMessage( 'unwatchthispage' )->text();
297 'action' => 'unwatch',
298 'token' => UnwatchAction
::getUnwatchToken( $title, $wgUser ),
300 $id = 'mw-unwatch-link';
302 $text = wfMessage( 'watchthispage' )->text();
305 'token' => WatchAction
::getWatchToken( $title, $wgUser ),
307 $id = 'mw-watch-link';
310 $s = Linker
::linkKnown(
313 array( 'id' => $id ),
317 $s = wfMessage( 'notanarticle' )->text();
323 function moveThisPage() {
324 if ( $this->getSkin()->getTitle()->quickUserCan( 'move' ) ) {
325 return Linker
::linkKnown(
326 SpecialPage
::getTitleFor( 'Movepage' ),
327 wfMessage( 'movethispage' )->text(),
329 array( 'target' => $this->getSkin()->getTitle()->getPrefixedDBkey() )
332 // no message if page is protected - would be redundant
337 function historyLink() {
339 $this->getSkin()->getTitle(),
340 wfMessage( 'history' )->escaped(),
341 array( 'rel' => 'archives' ),
342 array( 'action' => 'history' )
346 function whatLinksHere() {
347 return Linker
::linkKnown(
348 SpecialPage
::getTitleFor( 'Whatlinkshere', $this->getSkin()->getTitle()->getPrefixedDBkey() ),
349 wfMessage( 'whatlinkshere' )->escaped()
353 function userContribsLink() {
354 return Linker
::linkKnown(
355 SpecialPage
::getTitleFor( 'Contributions', $this->getSkin()->getTitle()->getDBkey() ),
356 wfMessage( 'contributions' )->escaped()
360 function emailUserLink() {
361 return Linker
::linkKnown(
362 SpecialPage
::getTitleFor( 'Emailuser', $this->getSkin()->getTitle()->getDBkey() ),
363 wfMessage( 'emailuser' )->escaped()
367 function watchPageLinksLink() {
370 if ( !$wgOut->isArticleRelated() ) {
371 return wfMessage( 'parentheses', wfMessage( 'notanarticle' )->text() )->escaped();
373 return Linker
::linkKnown(
374 SpecialPage
::getTitleFor( 'Recentchangeslinked', $this->getSkin()->getTitle()->getPrefixedDBkey() ),
375 wfMessage( 'recentchangeslinked-toolbox' )->escaped()
380 function talkLink() {
381 $title = $this->getSkin()->getTitle();
382 if ( NS_SPECIAL
== $title->getNamespace() ) {
383 # No discussion links for special pages
387 $linkOptions = array();
389 if ( $title->isTalkPage() ) {
390 $link = $title->getSubjectPage();
391 switch( $link->getNamespace() ) {
393 $text = wfMessage( 'articlepage' );
396 $text = wfMessage( 'userpage' );
399 $text = wfMessage( 'projectpage' );
402 $text = wfMessage( 'imagepage' );
403 # Make link known if image exists, even if the desc. page doesn't.
404 if ( wfFindFile( $link ) )
405 $linkOptions[] = 'known';
408 $text = wfMessage( 'mediawikipage' );
411 $text = wfMessage( 'templatepage' );
414 $text = wfMessage( 'viewhelppage' );
417 $text = wfMessage( 'categorypage' );
420 $text = wfMessage( 'articlepage' );
423 $link = $title->getTalkPage();
424 $text = wfMessage( 'talkpage' );
427 $s = Linker
::link( $link, $text->text(), array(), array(), $linkOptions );
437 function beforeContent() {
443 <a href
="<?php echo htmlspecialchars( $this->data['nav_urls']['mainpage']['href'] ) ?>">
444 <?php
echo wfMessage( 'sitetitle' )->escaped() ?
>
447 <p id
="sitesub"><?php
echo wfMessage( 'sitesubtitle' )->escaped() ?
></p
>
450 <span id
="syslinks"><?php
echo $this->sysLinks() ?
></span
>
451 <span id
="variantlinks"><?php
echo $this->variantLinks() ?
></span
>
453 <div id
="linkcollection">
454 <div id
="langlinks"><?php
echo str_replace( '<br />', '', $this->otherLanguages() ) ?
></div
>
455 <?php
echo $this->getSkin()->getCategories() ?
>
456 <div id
="titlelinks"><?php
echo $this->pageTitleLinks() ?
></div
>
457 <?php
if ( $this->data
['newtalk'] ) { ?
>
458 <div
class="usermessage"><strong
><?php
echo $this->data
['newtalk'] ?
></strong
></div
>
463 <?php
if ( $this->getSkin()->getSiteNotice() ) { ?
>
464 <div id
="siteNotice"><?php
echo $this->getSkin()->getSiteNotice() ?
></div
>
466 <h1 id
="firstHeading"><span dir
="auto"><?php
echo $this->data
['title'] ?
></span
></h1
>
467 <?php
if ( $this->translator
->translate( 'tagline' ) ) { ?
>
468 <p
class="tagline"><?php
echo htmlspecialchars( $this->translator
->translate( 'tagline' ) ) ?
></p
>
470 <?php
if ( $this->getSkin()->getOutput()->getSubtitle() ) { ?
>
471 <p
class="subtitle"><?php
echo $this->getSkin()->getOutput()->getSubtitle() ?
></p
>
473 <?php
if ( $this->getSkin()->subPageSubtitle() ) { ?
>
474 <p
class="subpages"><?php
echo $this->getSkin()->subPageSubtitle() ?
></p
>
477 $s = ob_get_contents();
488 function afterContent() {
494 // Page-related links
495 echo $this->bottomLinks();
498 // Footer and second searchbox
499 echo $this->getSkin()->getLanguage()->pipeList( array(
500 $this->getSkin()->mainPageLink(),
501 $this->getSkin()->aboutLink(),
502 $this->searchForm( 'footer' )
506 // Standard footer info
507 $footlinks = $this->getFooterLinks();
508 if ( $footlinks['info'] ) {
509 foreach ( $footlinks['info'] as $item ) {
510 echo $this->data
[$item] . ' ';
516 <?php
echo $this->quickBar() ?
>
518 $s = ob_get_contents();
529 function sysLinks() {
531 $this->getSkin()->mainPageLink(),
533 Title
::newFromText( wfMessage( 'aboutpage' )->inContentLanguage()->text() ),
534 wfMessage( 'about' )->text()
537 Title
::newFromText( wfMessage( 'helppage' )->inContentLanguage()->text() ),
538 wfMessage( 'help' )->text()
541 Title
::newFromText( wfMessage( 'faqpage' )->inContentLanguage()->text() ),
542 wfMessage( 'faq' )->text()
546 $personalUrls = $this->data
['personal_urls'];
547 if ( $this->data
['loggedin'] ) {
548 $s[] = $this->makeLink( 'logout', $personalUrls['logout'] );
550 if ( $personalUrls['createaccount'] ) { // Controlled by $wgUseCombinedLoginLink
551 $s[] = $this->makeLink( 'createaccount', $personalUrls['createaccount'] );
553 if ( $personalUrls['login'] ) {
554 $s[] = $this->makeLink( 'login', $personalUrls['login'] );
556 if ( $personalUrls['anonlogin'] ) {
557 $s[] = $this->makeLink( 'anonlogin', $personalUrls['anonlogin'] );
561 return $this->getSkin()->getLanguage()->pipeList( $s );
568 * @param $heading string
573 function menuHead( $heading ) {
574 return "\n<h6>" . htmlspecialchars( $heading ) . "</h6>";
578 * Compute the sidebar
586 $s = "\n<div id='quickbar'>";
590 $plain_bar = $this->data
['sidebar'];
593 // Massage the sidebar
594 // We want to place SEARCH at the beginning and a lot of stuff before TOOLBOX (or at the end, if it's missing)
595 $additions_done = false;
596 while ( !$additions_done ) {
597 $bar = array(); // Empty it out
599 // Always display search on top
600 $bar['SEARCH'] = true;
602 foreach ( $plain_bar as $heading => $links ) {
603 if ( $heading == 'TOOLBOX' ) {
604 if( $links !== NULL ) {
605 // If this is not a toolbox prosthetic we inserted outselves, fill it out
606 $plain_bar['TOOLBOX'] = $this->getToolbox();
609 // And insert the stuff
611 // "This page" and "Edit" menus
612 // We need to do some massaging here... we reuse all of the items, except for $...['views']['view'],
613 // as $...['namespaces']['main'] and $...['namespaces']['talk'] together serve the same purpose.
614 // We also don't use $...['variants'], these are displayed in the top menu.
615 $content_navigation = $this->data
['content_navigation'];
616 $qbpageoptions = array_merge(
617 $content_navigation['namespaces'],
619 'history' => $content_navigation['views']['history'],
620 'watch' => $content_navigation['actions']['watch'],
621 'unwatch' => $content_navigation['actions']['unwatch'],
624 $content_navigation['actions']['watch'] = null;
625 $content_navigation['actions']['unwatch'] = null;
626 $qbedit = array_merge(
628 'edit' => $content_navigation['views']['edit'],
629 'addsection' => $content_navigation['views']['addsection'],
631 $content_navigation['actions']
633 $bar['qbedit'] = $qbedit;
634 $bar['qbpageoptions'] = $qbpageoptions;
636 // Personal tools ("My pages")
637 $bar['qbmyoptions'] = $this->getPersonalTools();
638 $bar['qbmyoptions']['login'] = false;
639 $bar['qbmyoptions']['anonlogin'] = false;
640 $bar['qbmyoptions']['logout'] = false;
641 $bar['qbmyoptions']['createaccount'] = false;
643 $additions_done = true;
646 // Re-insert current heading, unless it's SEARCH
647 if ( $heading != 'SEARCH' ) {
648 $bar[$heading] = $plain_bar[$heading];
652 // If TOOLBOX is missing, $additions_done is still false
653 if ( !$additions_done ) {
654 $plain_bar['TOOLBOX'] = false;
658 foreach ( $bar as $heading => $links ) {
659 if ( $heading == 'SEARCH' ) {
660 $s .= $this->menuHead( wfMessage( 'qbfind' )->text() );
661 $s .= $this->searchForm( 'sidebar' );
662 } elseif ( $heading == 'LANGUAGES' ) {
663 // discard these; we display languages below page content
666 // Use the navigation heading from standard sidebar as the "browse" section
667 if ( $heading == 'navigation' ) {
668 $heading = 'qbbrowse';
670 if ( $heading == 'TOOLBOX' ) {
671 $heading = 'toolbox';
674 $headingMsg = wfMessage( $heading );
676 $t = $this->menuHead( $headingMsg->exists() ?
$headingMsg->text() : $heading );
678 foreach ( $links as $key => $link ) {
679 // Can be empty due to rampant sidebar massaging we're doing above
682 $t .= $this->makeListItem( $key, $link, array( 'tag' => 'span' ) ) . $sep;
693 $s .= $sep . "\n</div>\n";
698 * @param $label string
703 function searchForm( $which ) {
704 global $wgUseTwoButtonsSearchForm;
706 $search = $this->getSkin()->getRequest()->getText( 'search' );
707 $action = $this->data
['searchaction'];
708 $s = "<form id=\"searchform-" . htmlspecialchars($which) . "\" method=\"get\" class=\"inline\" action=\"$action\">";
709 if( $which == 'footer' ) {
710 $s .= wfMessage( 'qbfind' )->text() . ": ";
713 $s .= "<input type='text' class=\"mw-searchInput\" name=\"search\" size=\"14\" value=\""
714 . htmlspecialchars( substr( $search, 0, 256 ) ) . "\" />"
715 . ($which == 'footer' ?
" " : "<br />")
716 . "<input type='submit' class=\"searchButton\" name=\"go\" value=\"" . wfMessage( 'searcharticle' )->escaped() . "\" />";
718 if( $wgUseTwoButtonsSearchForm ) {
719 $s .= " <input type='submit' class=\"searchButton\" name=\"fulltext\" value=\"" . wfMessage( 'search' )->escaped() . "\" />\n";
721 $s .= '<div><a href="' . $action . '" rel="search">' . wfMessage( 'powersearch-legend' )->escaped() . "</a></div>\n";