From b7f8d0f41d5976f3fa0bf2e0e2816827edab0106 Mon Sep 17 00:00:00 2001 From: Alexandre Emsenhuber Date: Sat, 2 Apr 2011 18:38:42 +0000 Subject: [PATCH] * Moved all definitions in OutputPage::getHeadLinks() instead of having them in a *lot* of different functions * Also moved there generic and removed OutputPage::addDefaultMeta() with its $called static local variable which was breaking the output when generating multiple pages on the same request (rebuildFileCache.php, dumpHTML.php) since that function could only be executed completely once for all instances, and not once per instance * Moved default module from OutputPage::output() to its own function and don't call it when executing a body only request, since it's useless in that case * Call Skin::setMembers() from Skin::initPage() instead of Skin::outputPage() --- includes/OutputPage.php | 326 ++++++++++++++++++++++++++------------ includes/Skin.php | 121 +------------- includes/SkinTemplate.php | 1 - 3 files changed, 228 insertions(+), 220 deletions(-) diff --git a/includes/OutputPage.php b/includes/OutputPage.php index e68dca5de7..cd53914978 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -286,11 +286,24 @@ class OutputPage { * "rel" attribute will be automatically added */ function addMetadataLink( $linkarr ) { + $linkarr['rel'] = $this->getMetadataAttribute(); + $this->addLink( $linkarr ); + } + + /** + * Get the value of the "rel" attribute for metadata links + * + * @return String + */ + private function getMetadataAttribute() { # note: buggy CC software only reads first "meta" link static $haveMeta = false; - $linkarr['rel'] = $haveMeta ? 'alternate meta' : 'meta'; - $this->addLink( $linkarr ); - $haveMeta = true; + if ( $haveMeta ) { + return 'alternate meta'; + } else { + $haveMeta = true; + return 'meta'; + } } /** @@ -1757,105 +1770,62 @@ class OutputPage { public function output() { global $wgUser, $wgOutputEncoding, $wgRequest; global $wgLanguageCode, $wgDebugRedirects, $wgMimeType; - global $wgUseAjax, $wgAjaxWatch; - global $wgEnableMWSuggest, $wgUniversalEditButton; if( $this->mDoNothing ) { return; } + wfProfileIn( __METHOD__ ); + + $response = $wgRequest->response(); + if ( $this->mRedirect != '' ) { # Standards require redirect URLs to be absolute $this->mRedirect = wfExpandUrl( $this->mRedirect ); if( $this->mRedirectCode == '301' || $this->mRedirectCode == '303' ) { if( !$wgDebugRedirects ) { $message = self::getStatusMessage( $this->mRedirectCode ); - $wgRequest->response()->header( "HTTP/1.1 {$this->mRedirectCode} $message" ); + $response->header( "HTTP/1.1 {$this->mRedirectCode} $message" ); } $this->mLastModified = wfTimestamp( TS_RFC2822 ); } $this->sendCacheControl(); - $wgRequest->response()->header( "Content-Type: text/html; charset=utf-8" ); + $response->header( "Content-Type: text/html; charset=utf-8" ); if( $wgDebugRedirects ) { $url = htmlspecialchars( $this->mRedirect ); print "\n\nRedirect\n\n\n"; print "

Location: $url

\n"; print "\n\n"; } else { - $wgRequest->response()->header( 'Location: ' . $this->mRedirect ); + $response->header( 'Location: ' . $this->mRedirect ); } wfProfileOut( __METHOD__ ); return; } elseif ( $this->mStatusCode ) { $message = self::getStatusMessage( $this->mStatusCode ); if ( $message ) { - $wgRequest->response()->header( 'HTTP/1.1 ' . $this->mStatusCode . ' ' . $message ); - } - } - - // Add base resources - $this->addModules( 'mediawiki.util' ); - global $wgIncludeLegacyJavaScript; - if( $wgIncludeLegacyJavaScript ){ - $this->addModules( 'mediawiki.legacy.wikibits' ); - } - - // Add various resources if required - if ( $wgUseAjax ) { - $this->addModules( 'mediawiki.legacy.ajax' ); - - wfRunHooks( 'AjaxAddScript', array( &$this ) ); - - if( $wgAjaxWatch && $wgUser->isLoggedIn() ) { - $this->addModules( 'mediawiki.action.watch.ajax' ); - } - - if ( $wgEnableMWSuggest && !$wgUser->getOption( 'disablesuggest', false ) ) { - $this->addModules( 'mediawiki.legacy.mwsuggest' ); - } - } - - if( $wgUser->getBoolOption( 'editsectiononrightclick' ) ) { - $this->addModules( 'mediawiki.action.view.rightClickEdit' ); - } - - if( $wgUniversalEditButton ) { - if( $this->isArticleRelated() && $this->getTitle() && $this->getTitle()->quickUserCan( 'edit' ) - && ( $this->getTitle()->exists() || $this->getTitle()->quickUserCan( 'create' ) ) ) { - // Original UniversalEditButton - $msg = wfMsg( 'edit' ); - $this->addLink( array( - 'rel' => 'alternate', - 'type' => 'application/x-wiki', - 'title' => $msg, - 'href' => $this->getTitle()->getLocalURL( 'action=edit' ) - ) ); - // Alternate edit link - $this->addLink( array( - 'rel' => 'edit', - 'title' => $msg, - 'href' => $this->getTitle()->getLocalURL( 'action=edit' ) - ) ); + $response->header( 'HTTP/1.1 ' . $this->mStatusCode . ' ' . $message ); } } - # Buffer output; final headers may depend on later processing ob_start(); - $wgRequest->response()->header( "Content-type: $wgMimeType; charset={$wgOutputEncoding}" ); - $wgRequest->response()->header( 'Content-language: ' . $wgLanguageCode ); + $response->header( "Content-type: $wgMimeType; charset={$wgOutputEncoding}" ); + $response->header( 'Content-language: ' . $wgLanguageCode ); // Prevent framing, if requested $frameOptions = $this->getFrameOptions(); if ( $frameOptions ) { - $wgRequest->response()->header( "X-Frame-Options: $frameOptions" ); + $response->header( "X-Frame-Options: $frameOptions" ); } if ( $this->mArticleBodyOnly ) { $this->out( $this->mBodytext ); } else { + $this->addDefaultModules(); + $sk = $wgUser->getSkin( $this->getTitle() ); // Hook that allows last minute changes to the output page, e.g. @@ -2315,18 +2285,10 @@ class OutputPage { $ret .= "$openHead\n"; } - if ( $wgHtml5 ) { - # More succinct than , has the - # same effect - $ret .= Html::element( 'meta', array( 'charset' => $wgOutputEncoding ) ) . "\n"; - } else { - $this->addMeta( 'http:Content-Type', "$wgMimeType; charset=$wgOutputEncoding" ); - } - $ret .= Html::element( 'title', null, $this->getHTMLTitle() ) . "\n"; $ret .= implode( "\n", array( - $this->getHeadLinks( $sk ), + $this->getHeadLinks( $sk, true ), $this->buildCssLinks( $sk ), $this->getHeadItems() ) ); @@ -2373,6 +2335,39 @@ class OutputPage { return $ret; } + /** + * Add the default ResourceLoader modules to this object + */ + private function addDefaultModules() { + global $wgUser, $wgIncludeLegacyJavaScript, + $wgUseAjax, $wgAjaxWatch, $wgEnableMWSuggest; + + // Add base resources + $this->addModules( 'mediawiki.util' ); + if( $wgIncludeLegacyJavaScript ){ + $this->addModules( 'mediawiki.legacy.wikibits' ); + } + + // Add various resources if required + if ( $wgUseAjax ) { + $this->addModules( 'mediawiki.legacy.ajax' ); + + wfRunHooks( 'AjaxAddScript', array( &$this ) ); + + if( $wgAjaxWatch && $wgUser->isLoggedIn() ) { + $this->addModules( 'mediawiki.action.watch.ajax' ); + } + + if ( $wgEnableMWSuggest && !$wgUser->getOption( 'disablesuggest', false ) ) { + $this->addModules( 'mediawiki.legacy.mwsuggest' ); + } + } + + if( $wgUser->getBoolOption( 'editsectiononrightclick' ) ) { + $this->addModules( 'mediawiki.action.view.rightClickEdit' ); + } + } + /** * Get a ResourceLoader object associated with this OutputPage * @@ -2651,28 +2646,48 @@ class OutputPage { } /** - * Add default \ tags + * @return string HTML tag links to be put in the header. */ - protected function addDefaultMeta() { - global $wgVersion, $wgHtml5; + public function getHeadLinks( Skin $sk, $addContentType = false ) { + global $wgUniversalEditButton, $wgFavicon, $wgAppleTouchIcon, $wgEnableAPI, + $wgSitename, $wgVersion, $wgHtml5, $wgMimeType, $wgOutputEncoding, + $wgFeed, $wgOverrideSiteFeed, $wgAdvertisedFeedTypes, + $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf, + $wgDisableLangConversion, $wgCanonicalLanguageLinks, $wgContLang, + $wgRightsPage, $wgRightsUrl; - static $called = false; - if ( $called ) { - # Don't run this twice - return; - } - $called = true; + $tags = array(); - if ( !$wgHtml5 ) { - $this->addMeta( 'http:Content-Style-Type', 'text/css' ); // bug 15835 + if ( $addContentType ) { + if ( $wgHtml5 ) { + # More succinct than , has the + # same effect + $tags[] = Html::element( 'meta', array( 'charset' => $wgOutputEncoding ) ); + } else { + $tags[] = Html::element( 'meta', array( + 'http-equiv' => 'Content-Type', + 'content' => "$wgMimeType; charset=$wgOutputEncoding" + ) ); + $tags[] = Html::element( 'meta', array( // bug 15835 + 'http-equiv' => 'Content-Style-Type', + 'content' => 'text/css' + ) ); + } } - $this->addMeta( 'generator', "MediaWiki $wgVersion" ); + + $tags[] = Html::element( 'meta', array( + 'name' => 'generator', + 'content' => "MediaWiki $wgVersion", + ) ); $p = "{$this->mIndexPolicy},{$this->mFollowPolicy}"; if( $p !== 'index,follow' ) { // http://www.robotstxt.org/wc/meta-user.html // Only show if it's different from the default robots policy - $this->addMeta( 'robots', $p ); + $tags[] = Html::element( 'meta', array( + 'name' => 'robots', + 'content' => $p, + ) ); } if ( count( $this->mKeywords ) > 0 ) { @@ -2680,27 +2695,15 @@ class OutputPage { "/<.*?" . ">/" => '', "/_/" => ' ' ); - $this->addMeta( - 'keywords', - preg_replace( + $tags[] = Html::element( 'meta', array( + 'name' => 'keywords', + 'content' => preg_replace( array_keys( $strip ), array_values( $strip ), implode( ',', $this->mKeywords ) ) - ); + ) ); } - } - - /** - * @return string HTML tag links to be put in the header. - */ - public function getHeadLinks( Skin $sk ) { - global $wgFeed; - - // Ideally this should happen earlier, somewhere. :P - $this->addDefaultMeta(); - - $tags = array(); foreach ( $this->mMetatags as $tag ) { if ( 0 == strcasecmp( 'http:', substr( $tag[0], 0, 5 ) ) ) { @@ -2716,11 +2719,137 @@ class OutputPage { ) ); } + foreach ( $this->mLinktags as $tag ) { $tags[] = Html::element( 'link', $tag ); } - if( $wgFeed ) { + # Universal edit button + if ( $wgUniversalEditButton ) { + if ( $this->isArticleRelated() && $this->getTitle() && $this->getTitle()->quickUserCan( 'edit' ) + && ( $this->getTitle()->exists() || $this->getTitle()->quickUserCan( 'create' ) ) ) { + // Original UniversalEditButton + $msg = wfMsg( 'edit' ); + $tags[] = Html::element( 'link', array( + 'rel' => 'alternate', + 'type' => 'application/x-wiki', + 'title' => $msg, + 'href' => $this->getTitle()->getLocalURL( 'action=edit' ) + ) ); + // Alternate edit link + $tags[] = Html::element( 'link', array( + 'rel' => 'edit', + 'title' => $msg, + 'href' => $this->getTitle()->getLocalURL( 'action=edit' ) + ) ); + } + } + + # Generally the order of the favicon and apple-touch-icon links + # should not matter, but Konqueror (3.5.9 at least) incorrectly + # uses whichever one appears later in the HTML source. Make sure + # apple-touch-icon is specified first to avoid this. + if ( $wgAppleTouchIcon !== false ) { + $tags[] = Html::element( 'link', array( 'rel' => 'apple-touch-icon', 'href' => $wgAppleTouchIcon ) ); + } + + if ( $wgFavicon !== false ) { + $tags[] = Html::element( 'link', array( 'rel' => 'shortcut icon', 'href' => $wgFavicon ) ); + } + + # OpenSearch description link + $tags[] = Html::element( 'link', array( + 'rel' => 'search', + 'type' => 'application/opensearchdescription+xml', + 'href' => wfScript( 'opensearch_desc' ), + 'title' => wfMsgForContent( 'opensearch-desc' ), + ) ); + + if ( $wgEnableAPI ) { + # Real Simple Discovery link, provides auto-discovery information + # for the MediaWiki API (and potentially additional custom API + # support such as WordPress or Twitter-compatible APIs for a + # blogging extension, etc) + $tags[] = Html::element( 'link', array( + 'rel' => 'EditURI', + 'type' => 'application/rsd+xml', + 'href' => wfExpandUrl( wfAppendQuery( wfScript( 'api' ), array( 'action' => 'rsd' ) ) ), + ) ); + } + + # Metadata links + # - Creative Commons + # See http://wiki.creativecommons.org/Extend_Metadata. + # - Dublin Core + # Use hreflang to specify canonical and alternate links + # See http://www.google.com/support/webmasters/bin/answer.py?answer=189077 + if ( $this->isArticleRelated() ) { + # note: buggy CC software only reads first "meta" link + if ( $wgEnableCreativeCommonsRdf ) { + $tags[] = Html::element( 'link', array( + 'rel' => $this->getMetadataAttribute(), + 'title' => 'Creative Commons', + 'type' => 'application/rdf+xml', + 'href' => $this->getTitle()->getLocalURL( 'action=creativecommons' ) ) + ); + } + + if ( $wgEnableDublinCoreRdf ) { + $tags[] = Html::element( 'link', array( + 'rel' => $this->getMetadataAttribute(), + 'title' => 'Dublin Core', + 'type' => 'application/rdf+xml', + 'href' => $this->getTitle()->getLocalURL( 'action=dublincore' ) ) + ); + } + } + + # Language variants + if ( !$wgDisableLangConversion && $wgCanonicalLanguageLinks + && $wgContLang->hasVariants() ) { + + $urlvar = $wgContLang->getURLVariant(); + + if ( !$urlvar ) { + $variants = $wgContLang->getVariants(); + foreach ( $variants as $_v ) { + $tags[] = Html::element( 'link', array( + 'rel' => 'alternate', + 'hreflang' => $_v, + 'href' => $this->getTitle()->getLocalURL( '', $_v ) ) + ); + } + } else { + $tags[] = Html::element( 'link', array( + 'rel' => 'canonical', + 'href' => $this->getTitle()->getFullURL() ) + ); + } + } + + # Copyright + $copyright = ''; + if ( $wgRightsPage ) { + $copy = Title::newFromText( $wgRightsPage ); + + if ( $copy ) { + $copyright = $copy->getLocalURL(); + } + } + + if ( !$copyright && $wgRightsUrl ) { + $copyright = $wgRightsUrl; + } + + if ( $copyright ) { + $tags[] = Html::element( 'link', array( + 'rel' => 'copyright', + 'href' => $copyright ) + ); + } + + # Feeds + if ( $wgFeed ) { foreach( $this->getSyndicationLinks() as $format => $link ) { # Use the page name for the title (accessed through $wgTitle since # there's no other way). In principle, this could lead to issues @@ -2743,7 +2872,6 @@ class OutputPage { # or "Breaking news" one). For this, we see if $wgOverrideSiteFeed is defined. # If so, use it instead. - global $wgOverrideSiteFeed, $wgSitename, $wgAdvertisedFeedTypes; $rctitle = SpecialPage::getTitleFor( 'Recentchanges' ); if ( $wgOverrideSiteFeed ) { diff --git a/includes/Skin.php b/includes/Skin.php index 2fd3e112b9..1a0ce50c1d 100644 --- a/includes/Skin.php +++ b/includes/Skin.php @@ -183,47 +183,11 @@ abstract class Skin extends Linker { } function initPage( OutputPage $out ) { - global $wgFavicon, $wgAppleTouchIcon, $wgEnableAPI; - wfProfileIn( __METHOD__ ); - # Generally the order of the favicon and apple-touch-icon links - # should not matter, but Konqueror (3.5.9 at least) incorrectly - # uses whichever one appears later in the HTML source. Make sure - # apple-touch-icon is specified first to avoid this. - if ( false !== $wgAppleTouchIcon ) { - $out->addLink( array( 'rel' => 'apple-touch-icon', 'href' => $wgAppleTouchIcon ) ); - } - - if ( false !== $wgFavicon ) { - $out->addLink( array( 'rel' => 'shortcut icon', 'href' => $wgFavicon ) ); - } - - # OpenSearch description link - $out->addLink( array( - 'rel' => 'search', - 'type' => 'application/opensearchdescription+xml', - 'href' => wfScript( 'opensearch_desc' ), - 'title' => wfMsgForContent( 'opensearch-desc' ), - ) ); - - if ( $wgEnableAPI ) { - # Real Simple Discovery link, provides auto-discovery information - # for the MediaWiki API (and potentially additional custom API - # support such as WordPress or Twitter-compatible APIs for a - # blogging extension, etc) - $out->addLink( array( - 'rel' => 'EditURI', - 'type' => 'application/rsd+xml', - 'href' => wfExpandUrl( wfAppendQuery( wfScript( 'api' ), array( 'action' => 'rsd' ) ) ), - ) ); - } - - $this->addMetadataLinks( $out ); - $this->mRevisionId = $out->mRevisionId; - $this->preloadExistence(); + $this->setMembers(); wfProfileOut( __METHOD__ ); } @@ -251,88 +215,6 @@ abstract class Skin extends Linker { $lb->execute(); } - /** - * Adds metadata links below to the HTML output. - *
    - *
  1. Creative Commons - *
    See http://wiki.creativecommons.org/Extend_Metadata. - *
  2. - *
  3. Dublin Core
  4. - *
  5. Use hreflang to specify canonical and alternate links - *
    See http://www.google.com/support/webmasters/bin/answer.py?answer=189077 - *
  6. - *
  7. Copyright
  8. - *
      - * - * @param $out Object: instance of OutputPage - */ - function addMetadataLinks( OutputPage $out ) { - global $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf; - global $wgDisableLangConversion, $wgCanonicalLanguageLinks, $wgContLang; - global $wgRightsPage, $wgRightsUrl; - - if ( $out->isArticleRelated() ) { - # note: buggy CC software only reads first "meta" link - if ( $wgEnableCreativeCommonsRdf ) { - $out->addMetadataLink( array( - 'title' => 'Creative Commons', - 'type' => 'application/rdf+xml', - 'href' => $this->mTitle->getLocalURL( 'action=creativecommons' ) ) - ); - } - - if ( $wgEnableDublinCoreRdf ) { - $out->addMetadataLink( array( - 'title' => 'Dublin Core', - 'type' => 'application/rdf+xml', - 'href' => $this->mTitle->getLocalURL( 'action=dublincore' ) ) - ); - } - } - - if ( !$wgDisableLangConversion && $wgCanonicalLanguageLinks - && $wgContLang->hasVariants() ) { - - $urlvar = $wgContLang->getURLVariant(); - - if ( !$urlvar ) { - $variants = $wgContLang->getVariants(); - foreach ( $variants as $_v ) { - $out->addLink( array( - 'rel' => 'alternate', - 'hreflang' => $_v, - 'href' => $this->mTitle->getLocalURL( '', $_v ) ) - ); - } - } else { - $out->addLink( array( - 'rel' => 'canonical', - 'href' => $this->mTitle->getFullURL() ) - ); - } - } - - $copyright = ''; - if ( $wgRightsPage ) { - $copy = Title::newFromText( $wgRightsPage ); - - if ( $copy ) { - $copyright = $copy->getLocalURL(); - } - } - - if ( !$copyright && $wgRightsUrl ) { - $copyright = $wgRightsUrl; - } - - if ( $copyright ) { - $out->addLink( array( - 'rel' => 'copyright', - 'href' => $copyright ) - ); - } - } - /** * Set some local variables */ @@ -437,7 +319,6 @@ abstract class Skin extends Linker { global $wgDebugComments; wfProfileIn( __METHOD__ ); - $this->setMembers(); $this->initPage( $out ); // See self::afterContentHook() for documentation diff --git a/includes/SkinTemplate.php b/includes/SkinTemplate.php index 2eea639c45..7a91b37dbb 100644 --- a/includes/SkinTemplate.php +++ b/includes/SkinTemplate.php @@ -154,7 +154,6 @@ class SkinTemplate extends Skin { wfProfileIn( __METHOD__ . '-init' ); $this->initPage( $out ); - $this->setMembers(); $tpl = $this->setupTemplate( $this->template, 'skins' ); wfProfileOut( __METHOD__ . '-init' ); -- 2.20.1