MediaWiki  REL1_22
CologneBlue.php
Go to the documentation of this file.
00001 <?php
00025 if ( !defined( 'MEDIAWIKI' ) ) {
00026     die( -1 );
00027 }
00028 
00033 class SkinCologneBlue extends SkinTemplate {
00034     var $skinname = 'cologneblue', $stylename = 'cologneblue',
00035         $template = 'CologneBlueTemplate';
00036     var $useHeadElement = true;
00037 
00041     function setupSkinUserCss( OutputPage $out ) {
00042         parent::setupSkinUserCss( $out );
00043         $out->addModuleStyles( 'mediawiki.legacy.oldshared' );
00044         $out->addModuleStyles( 'skins.cologneblue' );
00045     }
00046 
00051     function formatLanguageName( $name ) {
00052         return $name;
00053     }
00054 }
00055 
00056 class CologneBlueTemplate extends BaseTemplate {
00057     function execute() {
00058         // Suppress warnings to prevent notices about missing indexes in $this->data
00059         wfSuppressWarnings();
00060         $this->html( 'headelement' );
00061         echo $this->beforeContent();
00062         $this->html( 'bodytext' );
00063         echo "\n";
00064         echo $this->afterContent();
00065         $this->html( 'dataAfterContent' );
00066         $this->printTrail();
00067         echo "\n</body></html>";
00068         wfRestoreWarnings();
00069     }
00070 
00075     function variantLinks() {
00076         $s = array();
00077 
00078         $variants = $this->data['content_navigation']['variants'];
00079 
00080         foreach ( $variants as $key => $link ) {
00081             $s[] = $this->makeListItem( $key, $link, array( 'tag' => 'span' ) );
00082         }
00083 
00084         return $this->getSkin()->getLanguage()->pipeList( $s );
00085     }
00086 
00087     function otherLanguages() {
00088         global $wgHideInterlanguageLinks;
00089         if ( $wgHideInterlanguageLinks ) {
00090             return "";
00091         }
00092 
00093         // We override SkinTemplate->formatLanguageName() in SkinCologneBlue
00094         // not to capitalize the language names.
00095         $language_urls = $this->data['language_urls'];
00096         if ( empty( $language_urls ) ) {
00097             return "";
00098         }
00099 
00100         $s = array();
00101         foreach ( $language_urls as $key => $data ) {
00102             $s[] = $this->makeListItem( $key, $data, array( 'tag' => 'span' ) );
00103         }
00104 
00105         return wfMessage( 'otherlanguages' )->text()
00106             . wfMessage( 'colon-separator' )->text()
00107             . $this->getSkin()->getLanguage()->pipeList( $s );
00108     }
00109 
00110     function pageTitleLinks() {
00111         $s = array();
00112         $footlinks = $this->getFooterLinks();
00113 
00114         foreach ( $footlinks['places'] as $item ) {
00115             $s[] = $this->data[$item];
00116         }
00117 
00118         return $this->getSkin()->getLanguage()->pipeList( $s );
00119     }
00120 
00130     function processBottomLink( $key, $navlink, $message = null ) {
00131         if ( !$navlink ) {
00132             // Empty navlinks might be passed.
00133             return null;
00134         }
00135 
00136         if ( $message ) {
00137             $navlink['text'] = wfMessage( $message )->escaped();
00138         }
00139 
00140         return $this->makeListItem( $key, $this->processNavlinkForDocument( $navlink ), array( 'tag' => 'span' ) );
00141     }
00142 
00143     function bottomLinks() {
00144         $toolbox = $this->getToolbox();
00145         $content_nav = $this->data['content_navigation'];
00146 
00147         $lines = array();
00148 
00149         if ( $this->getSkin()->getOutput()->isArticleRelated() ) {
00150             // First row. Regular actions.
00151             $element = array();
00152 
00153             $editLinkMessage = $this->getSkin()->getTitle()->exists() ? 'editthispage' : 'create-this-page';
00154             $element[] = $this->processBottomLink( 'edit', $content_nav['views']['edit'], $editLinkMessage );
00155             $element[] = $this->processBottomLink( 'viewsource', $content_nav['views']['viewsource'], 'viewsource' );
00156 
00157             $element[] = $this->processBottomLink( 'watch', $content_nav['actions']['watch'], 'watchthispage' );
00158             $element[] = $this->processBottomLink( 'unwatch', $content_nav['actions']['unwatch'], 'unwatchthispage' );
00159 
00160             $element[] = $this->talkLink();
00161 
00162             $element[] = $this->processBottomLink( 'history', $content_nav['views']['history'], 'history' );
00163             $element[] = $this->processBottomLink( 'info', $toolbox['info'] );
00164             $element[] = $this->processBottomLink( 'whatlinkshere', $toolbox['whatlinkshere'] );
00165             $element[] = $this->processBottomLink( 'recentchangeslinked', $toolbox['recentchangeslinked'] );
00166 
00167             $element[] = $this->processBottomLink( 'contributions', $toolbox['contributions'] );
00168             $element[] = $this->processBottomLink( 'emailuser', $toolbox['emailuser'] );
00169 
00170             $lines[] = $this->getSkin()->getLanguage()->pipeList( array_filter( $element ) );
00171 
00172 
00173             // Second row. Privileged actions.
00174             $element = array();
00175 
00176             $element[] = $this->processBottomLink( 'delete', $content_nav['actions']['delete'], 'deletethispage' );
00177             $element[] = $this->processBottomLink( 'undelete', $content_nav['actions']['undelete'], 'undeletethispage' );
00178 
00179             $element[] = $this->processBottomLink( 'protect', $content_nav['actions']['protect'], 'protectthispage' );
00180             $element[] = $this->processBottomLink( 'unprotect', $content_nav['actions']['unprotect'], 'unprotectthispage' );
00181 
00182             $element[] = $this->processBottomLink( 'move', $content_nav['actions']['move'], 'movethispage' );
00183 
00184             $lines[] = $this->getSkin()->getLanguage()->pipeList( array_filter( $element ) );
00185 
00186 
00187             // Third row. Language links.
00188             $lines[] = $this->otherLanguages();
00189         }
00190 
00191         return implode( array_filter( $lines ), "<br />\n" ) . "<br />\n";
00192     }
00193 
00194     function talkLink() {
00195         $title = $this->getSkin()->getTitle();
00196 
00197         if ( $title->getNamespace() == NS_SPECIAL ) {
00198             // No discussion links for special pages
00199             return "";
00200         }
00201 
00202         $companionTitle = $title->isTalkPage() ? $title->getSubjectPage() : $title->getTalkPage();
00203         $companionNamespace = $companionTitle->getNamespace();
00204 
00205         // TODO these messages are only be used by CologneBlue,
00206         // kill and replace with something more sensibly named?
00207         $nsToMessage = array(
00208             NS_MAIN => 'articlepage',
00209             NS_USER => 'userpage',
00210             NS_PROJECT => 'projectpage',
00211             NS_FILE => 'imagepage',
00212             NS_MEDIAWIKI => 'mediawikipage',
00213             NS_TEMPLATE => 'templatepage',
00214             NS_HELP => 'viewhelppage',
00215             NS_CATEGORY => 'categorypage',
00216             NS_FILE => 'imagepage',
00217         );
00218 
00219         // Find out the message to use for link text. Use either the array above or,
00220         // for non-talk pages, a generic "discuss this" message.
00221         // Default is the same as for main namespace.
00222         if ( isset( $nsToMessage[$companionNamespace] ) ) {
00223             $message = $nsToMessage[$companionNamespace];
00224         } else {
00225             $message = $companionTitle->isTalkPage() ? 'talkpage' : 'articlepage';
00226         }
00227 
00228         // Obviously this can't be reasonable and just return the key for talk namespace, only for content ones.
00229         // Thus we have to mangle it in exactly the same way SkinTemplate does. (bug 40805)
00230         $key = $companionTitle->getNamespaceKey( '' );
00231         if ( $companionTitle->isTalkPage() ) {
00232             $key = ( $key == 'main' ? 'talk' : $key . "_talk" );
00233         }
00234 
00235         // Use the regular navigational link, but replace its text. Everything else stays unmodified.
00236         $namespacesLinks = $this->data['content_navigation']['namespaces'];
00237         return $this->processBottomLink( $message, $namespacesLinks[$key], $message );
00238     }
00239 
00249     function processNavlinkForDocument( $navlink, $idPrefix = 'cb-' ) {
00250         if ( $navlink['id'] ) {
00251             $navlink['single-id'] = $navlink['id']; // to allow for tooltip generation
00252             $navlink['tooltiponly'] = true; // but no accesskeys
00253 
00254             // mangle or remove the id
00255             if ( $idPrefix === false ) {
00256                 unset( $navlink['id'] );
00257             } else {
00258                 $navlink['id'] = $idPrefix . $navlink['id'];
00259             }
00260         }
00261 
00262         return $navlink;
00263     }
00264 
00268     function beforeContent() {
00269         ob_start();
00270 ?>
00271 <div id="content">
00272     <div id="topbar">
00273         <p id="sitetitle" role="banner">
00274             <a href="<?php echo htmlspecialchars( $this->data['nav_urls']['mainpage']['href'] ) ?>">
00275                 <?php echo wfMessage( 'sitetitle' )->escaped() ?>
00276             </a>
00277         </p>
00278         <p id="sitesub"><?php echo wfMessage( 'sitesubtitle' )->escaped() ?></p>
00279         <div id="linkcollection" role="navigation">
00280             <div id="langlinks"><?php echo str_replace( '<br />', '', $this->otherLanguages() ) ?></div>
00281             <?php echo $this->getSkin()->getCategories() ?>
00282             <div id="titlelinks"><?php echo $this->pageTitleLinks() ?></div>
00283             <?php if ( $this->data['newtalk'] ) { ?>
00284             <div class="usermessage"><strong><?php echo $this->data['newtalk'] ?></strong></div>
00285             <?php } ?>
00286         </div>
00287     </div>
00288     <div id="article" role="main">
00289         <?php if ( $this->getSkin()->getSiteNotice() ) { ?>
00290         <div id="siteNotice"><?php echo $this->getSkin()->getSiteNotice() ?></div>
00291         <?php } ?>
00292         <h1 id="firstHeading" lang="<?php
00293             $this->data['pageLanguage'] = $this->getSkin()->getTitle()->getPageViewLanguage()->getHtmlCode();
00294             $this->text( 'pageLanguage' );
00295         ?>"><span dir="auto"><?php echo $this->data['title'] ?></span></h1>
00296         <?php if ( $this->translator->translate( 'tagline' ) ) { ?>
00297         <p class="tagline"><?php echo htmlspecialchars( $this->translator->translate( 'tagline' ) ) ?></p>
00298         <?php } ?>
00299         <?php if ( $this->getSkin()->getOutput()->getSubtitle() ) { ?>
00300         <p class="subtitle"><?php echo $this->getSkin()->getOutput()->getSubtitle() ?></p>
00301         <?php } ?>
00302         <?php if ( $this->getSkin()->subPageSubtitle() ) { ?>
00303         <p class="subpages"><?php echo $this->getSkin()->subPageSubtitle() ?></p>
00304         <?php } ?>
00305 <?php
00306         $s = ob_get_contents();
00307         ob_end_clean();
00308 
00309         return $s;
00310     }
00311 
00315     function afterContent() {
00316         ob_start();
00317 ?>
00318     </div>
00319     <div id="footer">
00320         <div id="footer-navigation" role="navigation">
00321 <?php
00322         // Page-related links
00323         echo $this->bottomLinks();
00324         echo "\n<br />";
00325 
00326         // Footer and second searchbox
00327         echo $this->getSkin()->getLanguage()->pipeList( array(
00328             $this->getSkin()->mainPageLink(),
00329             $this->getSkin()->aboutLink(),
00330             $this->searchForm( 'footer' )
00331         ) );
00332 ?>
00333         </div>
00334         <div id="footer-info" role="contentinfo">
00335 <?php
00336         // Standard footer info
00337         $footlinks = $this->getFooterLinks();
00338         if ( $footlinks['info'] ) {
00339             foreach ( $footlinks['info'] as $item ) {
00340                 echo $this->data[$item] . ' ';
00341             }
00342         }
00343 ?>
00344         </div>
00345     </div>
00346 </div>
00347 <div id="mw-navigation">
00348     <h2><?php echo wfMessage( 'navigation-heading' )->escaped() ?></h2>
00349     <div id="toplinks" role="navigation">
00350         <p id="syslinks"><?php echo $this->sysLinks() ?></p>
00351         <p id="variantlinks"><?php echo $this->variantLinks() ?></p>
00352     </div>
00353     <?php echo $this->quickBar() ?>
00354 </div>
00355 <?php
00356         $s = ob_get_contents();
00357         ob_end_clean();
00358 
00359         return $s;
00360     }
00361 
00365     function sysLinks() {
00366         $s = array(
00367             $this->getSkin()->mainPageLink(),
00368             Linker::linkKnown(
00369                 Title::newFromText( wfMessage( 'aboutpage' )->inContentLanguage()->text() ),
00370                 wfMessage( 'about' )->text()
00371             ),
00372             Linker::makeExternalLink(
00373                 Skin::makeInternalOrExternalUrl( wfMessage( 'helppage' )->inContentLanguage()->text() ),
00374                 wfMessage( 'help' )->text(),
00375                 false
00376             ),
00377             Linker::linkKnown(
00378                 Title::newFromText( wfMessage( 'faqpage' )->inContentLanguage()->text() ),
00379                 wfMessage( 'faq' )->text()
00380             ),
00381         );
00382 
00383         $personalUrls = $this->getPersonalTools();
00384         foreach ( array( 'logout', 'createaccount', 'login', 'anonlogin' ) as $key ) {
00385             if ( $personalUrls[$key] ) {
00386                 $s[] = $this->makeListItem( $key, $personalUrls[$key], array( 'tag' => 'span' ) );
00387             }
00388         }
00389 
00390         return $this->getSkin()->getLanguage()->pipeList( $s );
00391     }
00392 
00399     function sidebarAdditions( $bar ) {
00400         // "This page" and "Edit" menus
00401         // We need to do some massaging here... we reuse all of the items, except for $...['views']['view'],
00402         // as $...['namespaces']['main'] and $...['namespaces']['talk'] together serve the same purpose.
00403         // We also don't use $...['variants'], these are displayed in the top menu.
00404         $content_navigation = $this->data['content_navigation'];
00405         $qbpageoptions = array_merge(
00406             $content_navigation['namespaces'],
00407             array(
00408                 'history' => $content_navigation['views']['history'],
00409                 'watch' => $content_navigation['actions']['watch'],
00410                 'unwatch' => $content_navigation['actions']['unwatch'],
00411             )
00412         );
00413         $content_navigation['actions']['watch'] = null;
00414         $content_navigation['actions']['unwatch'] = null;
00415         $qbedit = array_merge(
00416             array(
00417                 'edit' => $content_navigation['views']['edit'],
00418                 'addsection' => $content_navigation['views']['addsection'],
00419             ),
00420             $content_navigation['actions']
00421         );
00422 
00423         // Personal tools ("My pages")
00424         $qbmyoptions = $this->getPersonalTools();
00425         foreach ( array( 'logout', 'createaccount', 'login', 'anonlogin' ) as $key ) {
00426             $qbmyoptions[$key] = null;
00427         }
00428 
00429         // Use the closest reasonable name
00430         $bar['cactions'] = $qbedit;
00431         $bar['pageoptions'] = $qbpageoptions; // this is a non-standard portlet name, but nothing fits
00432         $bar['personal'] = $qbmyoptions;
00433 
00434         return $bar;
00435     }
00436 
00443     function quickBar() {
00444         // Massage the sidebar. We want to:
00445         // * place SEARCH at the beginning
00446         // * add new portlets before TOOLBOX (or at the end, if it's missing)
00447         // * remove LANGUAGES (langlinks are displayed elsewhere)
00448         $orig_bar = $this->data['sidebar'];
00449         $bar = array();
00450         $hasToolbox = false;
00451 
00452         // Always display search first
00453         $bar['SEARCH'] = true;
00454         // Copy everything except for langlinks, inserting new items before toolbox
00455         foreach ( $orig_bar as $heading => $data ) {
00456             if ( $heading == 'TOOLBOX' ) {
00457                 // Insert the stuff
00458                 $bar = $this->sidebarAdditions( $bar );
00459                 $hasToolbox = true;
00460             }
00461 
00462             if ( $heading != 'LANGUAGES' ) {
00463                 $bar[$heading] = $data;
00464             }
00465         }
00466         // If toolbox is missing, add our items at the end
00467         if ( !$hasToolbox ) {
00468             $bar = $this->sidebarAdditions( $bar );
00469         }
00470 
00471 
00472         // Fill out special sidebar items with content
00473         $orig_bar = $bar;
00474         $bar = array();
00475         foreach ( $orig_bar as $heading => $data ) {
00476             if ( $heading == 'SEARCH' ) {
00477                 $bar['search'] = $this->searchForm( 'sidebar' );
00478             } elseif ( $heading == 'TOOLBOX' ) {
00479                 $bar['tb'] = $this->getToolbox();
00480             } else {
00481                 $bar[$heading] = $data;
00482             }
00483         }
00484 
00485 
00486         // Output the sidebar
00487         // CologneBlue uses custom messages for some portlets, but we should keep the ids for consistency
00488         $idToMessage = array(
00489             'search' => 'qbfind',
00490             'navigation' => 'qbbrowse',
00491             'tb' => 'toolbox',
00492             'cactions' => 'qbedit',
00493             'personal' => 'qbmyoptions',
00494             'pageoptions' => 'qbpageoptions',
00495         );
00496 
00497         $s = "<div id='quickbar'>\n";
00498 
00499         foreach ( $bar as $heading => $data ) {
00500             $portletId = Sanitizer::escapeId( "p-$heading" );
00501             $headingMsg = wfMessage( $idToMessage[$heading] ? $idToMessage[$heading] : $heading );
00502             $headingHTML = "<h3>" . ( $headingMsg->exists() ? $headingMsg->escaped() : htmlspecialchars( $heading ) ) . "</h3>";
00503             $listHTML = "";
00504 
00505             if ( is_array( $data ) ) {
00506                 // $data is an array of links
00507                 foreach ( $data as $key => $link ) {
00508                     // Can be empty due to how the sidebar additions are done
00509                     if ( $link ) {
00510                         $listHTML .= $this->makeListItem( $key, $link );
00511                     }
00512                 }
00513                 if ( $listHTML ) {
00514                     $listHTML = "<ul>$listHTML</ul>";
00515                 }
00516             } else {
00517                 // $data is a HTML <ul>-list string
00518                 $listHTML = $data;
00519             }
00520 
00521             if ( $listHTML ) {
00522                 $role = ( $heading == 'search' ) ? 'search' : 'navigation';
00523                 $s .= "<div class=\"portlet\" id=\"$portletId\" role=\"$role\">\n$headingHTML\n$listHTML\n</div>\n";
00524             }
00525         }
00526 
00527         $s .= "</div>\n";
00528         return $s;
00529     }
00530 
00535     function searchForm( $which ) {
00536         global $wgUseTwoButtonsSearchForm;
00537 
00538         $search = $this->getSkin()->getRequest()->getText( 'search' );
00539         $action = $this->data['searchaction'];
00540         $s = "<form id=\"searchform-" . htmlspecialchars( $which ) . "\" method=\"get\" class=\"inline\" action=\"$action\">";
00541         if ( $which == 'footer' ) {
00542             $s .= wfMessage( 'qbfind' )->text() . ": ";
00543         }
00544 
00545         $s .= $this->makeSearchInput( array( 'class' => 'mw-searchInput', 'type' => 'text', 'size' => '14' ) );
00546         $s .= ( $which == 'footer' ? " " : "<br />" );
00547         $s .= $this->makeSearchButton( 'go', array( 'class' => 'searchButton' ) );
00548 
00549         if ( $wgUseTwoButtonsSearchForm ) {
00550             $s .= $this->makeSearchButton( 'fulltext', array( 'class' => 'searchButton' ) );
00551         } else {
00552             $s .= '<div><a href="' . $action . '" rel="search">' . wfMessage( 'powersearch-legend' )->escaped() . "</a></div>\n";
00553         }
00554 
00555         $s .= '</form>';
00556 
00557         return $s;
00558     }
00559 }