(bug 45535) Hook for changing language links.
authordaniel <daniel.kinzler@wikimedia.de>
Fri, 19 Apr 2013 11:19:06 +0000 (13:19 +0200)
committerBrad Jorsch <bjorsch@wikimedia.org>
Mon, 29 Apr 2013 13:13:47 +0000 (09:13 -0400)
This adds a new hook called LanguageLinks which is called
whenever a list of language links is returned to the user.
This gives extensions the option to manipulate the links
on the fly.

Note that this change only covers the language links used
in OutputPage and by ApiParse. Adapting ApiQueryLangLinks is
left as a follow-up task.

As explained on bugzilla, this is a precondition to
allowing Wikibase/Wikidata to update languagelinks without
forcing a (redundant) re-parse of the page content.

This change also introduces the notion of link flags that
can be used to associate flags with language links. This
will be integrated with ParserOutput and OutputPage in a
follow-up.

Change-Id: Iaec0faa131413a291fc8f77496e4f371addb3b99

RELEASE-NOTES-1.22
docs/hooks.txt
includes/OutputPage.php
includes/api/ApiParse.php
includes/api/ApiQueryAllPages.php
includes/api/ApiQueryLangBacklinks.php
includes/api/ApiQueryLangLinks.php

index a9160e5..ce4c949 100644 (file)
@@ -52,6 +52,8 @@ production.
   still be visible on cached page renders until they are purged); extensions
   using the DoEditSectionLink or EditSectionLink hooks might need adjustments as
   well.
+* (bug 45535) introduced the new 'LanguageLinks' hook for manipulating the
+  language links associated with a page before display.
 
 === Bug fixes in 1.22 ===
 * Disable Special:PasswordReset when $wgEnableEmail. Previously one could still
@@ -84,6 +86,13 @@ production.
 * action=opensearch no longer silently ignores the format parameter.
 * action=opensearch now supports format=jsonfm.
 * list=usercontribs&ucprop=ids will now include the parent revision id.
+* BREAKING CHANGE: action=parse no longer returns all langlinks for the page
+  with prop=langlinks by default. The new effectivelanglinks parameter will
+  request that the LanguageLinks hook be called to determine the effective
+  language links.
+* BREAKING CHANGE: list=allpages, list=langbacklinks, and prop=langlinks do not
+  apply the new LanguageLinks hook, and thus only consider language links
+  stored in the database.
 
 === Languages updated in 1.22===
 
index 2d64bce..de51024 100644 (file)
@@ -1384,6 +1384,16 @@ $lang: language code (string)
 &$names: array of language code => language name
 $code language of the preferred translations
 
+'LanguageLinks': Manipulate a page's language links. This is called
+in various places to allow extensions to define the effective language
+links for a page.
+$title: The page's Title.
+&$links: Associative array mapping language codes to prefixed links of the
+  form "language:title".
+&$linkFlags: Associative array mapping prefixed links to arrays of flags.
+  Currently unused, but planned to provide support for marking individual
+  language links in the UI, e.g. for featured articles.
+
 'LinkBegin': Used when generating internal and interwiki links in
 Linker::link(), before processing starts.  Return false to skip default
 processing and return $ret. See documentation for Linker::link() for details on
index 08eb3ae..65800dd 100644 (file)
@@ -1609,6 +1609,10 @@ class OutputPage extends ContextSource {
                        }
                }
 
+               // Link flags are ignored for now, but may in the future be
+               // used to mark individual language links.
+               $linkFlags = array();
+               wfRunHooks( 'LanguageLinks', array( $this->getTitle(), &$this->mLanguageLinks, &$linkFlags ) );
                wfRunHooks( 'OutputPageParserOutput', array( &$this, $parserOutput ) );
        }
 
index 09b7a88..defdade 100644 (file)
@@ -233,11 +233,25 @@ class ApiParse extends ApiBase {
                        $result->setContent( $result_array['parsedsummary'], Linker::formatComment( $params['summary'], $titleObj ) );
                }
 
+               if ( isset( $prop['langlinks'] ) || isset( $prop['languageshtml'] ) ) {
+                       $langlinks = $p_result->getLanguageLinks();
+
+                       if ( $params['effectivelanglinks'] ) {
+                               // Link flags are ignored for now, but may in the future be
+                               // included in the result.
+                               $linkFlags = array();
+                               wfRunHooks( 'LanguageLinks', array( $titleObj, &$langlinks, &$linkFlags ) );
+                       }
+               } else {
+                       $langlinks = false;
+               }
+
                if ( isset( $prop['langlinks'] ) ) {
-                       $result_array['langlinks'] = $this->formatLangLinks( $p_result->getLanguageLinks() );
+                       $result_array['langlinks'] = $this->formatLangLinks( $langlinks );
                }
                if ( isset( $prop['languageshtml'] ) ) {
-                       $languagesHtml = $this->languagesHtml( $p_result->getLanguageLinks() );
+                       $languagesHtml = $this->languagesHtml( $langlinks );
+
                        $result_array['languageshtml'] = array();
                        $result->setContent( $result_array['languageshtml'], $languagesHtml );
                }
@@ -575,6 +589,7 @@ class ApiParse extends ApiBase {
                        ),
                        'pst' => false,
                        'onlypst' => false,
+                       'effectivelanglinks' => false,
                        'uselang' => null,
                        'section' => null,
                        'disablepp' => false,
@@ -618,6 +633,10 @@ class ApiParse extends ApiBase {
                                ' wikitext       - Gives the original wikitext that was parsed',
                                ' properties     - Gives various properties defined in the parsed wikitext',
                        ),
+                       'effectivelanglinks' => array(
+                               'Includes language links supplied by extensions',
+                               '(for use with prop=langlinks|languageshtml)',
+                       ),
                        'pst' => array(
                                'Do a pre-save transform on the input before parsing it',
                                'Ignored if page, pageid or oldid is used'
index 0d0c10f..d95980c 100644 (file)
@@ -304,7 +304,10 @@ class ApiQueryAllPages extends ApiQueryGeneratorBase {
                        'prtype' => 'Limit to protected pages only',
                        'prlevel' => "The protection level (must be used with {$p}prtype= parameter)",
                        'prfiltercascade' => "Filter protections based on cascadingness (ignored when {$p}prtype isn't set)",
-                       'filterlanglinks' => 'Filter based on whether a page has langlinks',
+                       'filterlanglinks' => array(
+                               'Filter based on whether a page has langlinks',
+                               'Note that this may not consider langlinks added by extensions.',
+                       ),
                        'limit' => 'How many total pages to return.',
                        'prexpiry' => array(
                                'Which protection expiry to filter the page on',
index 7a4880a..ce03e58 100644 (file)
@@ -223,7 +223,8 @@ class ApiQueryLangBacklinks extends ApiQueryGeneratorBase {
                return array( 'Find all pages that link to the given language link.',
                        'Can be used to find all links with a language code, or',
                        'all links to a title (with a given language).',
-                       'Using neither parameter is effectively "All Language Links"',
+                       'Using neither parameter is effectively "All Language Links".',
+                       'Note that this may not consider language links added by extensions.',
                );
        }
 
index e6b02d7..aa796e3 100644 (file)
@@ -67,6 +67,10 @@ class ApiQueryLangLinks extends ApiQueryBase {
                        );
                }
 
+               //FIXME: (follow-up) To allow extensions to add to the language links, we need
+               //       to load them all, add the extra links, then apply paging.
+               //       Should not be terrible, it's not going to be more than a few hundred links.
+
                // Note that, since (ll_from, ll_lang) is a unique key, we don't need
                // to sort by ll_title to ensure deterministic ordering.
                $sort = ( $params['dir'] == 'descending' ? ' DESC' : '' );