From: Brian Wolff Date: Sat, 16 Nov 2013 01:47:51 +0000 (-0400) Subject: Add UI to discover translated SVG files. X-Git-Tag: 1.31.0-rc.0~17732^2 X-Git-Url: http://git.cyclocoop.org/%22.%24h.%22?a=commitdiff_plain;h=d0c0bad56d8ff3fe4c02d23b3fa336988ebcfcf8;p=lhc%2Fweb%2Fwiklou.git Add UI to discover translated SVG files. Currently we support rendering SVGs in multiple languages, but there is no mechanism for users to discover what languages a file is available in. Show this information on the image page. At the moment, if unspecified we always default the language to english (I believe to avoid mass cache splitting, especially if most languages wouldn't have a translation of the file in their language). This code was written in such a way so that this assumption should be changable in the future if we so desire. Long term, Jarry has a super cool svg translation extension which would take over some of this. However I still believe we should have an interface for this in core, since we do support the different language renderings in core. Change-Id: I84506436514e09d71200aa2db3932aa001b55c71 --- diff --git a/includes/ImagePage.php b/includes/ImagePage.php index b2a53cdb1b..2c303c9f8a 100644 --- a/includes/ImagePage.php +++ b/includes/ImagePage.php @@ -525,6 +525,16 @@ EOT ); } + $renderLangOptions = $this->displayImg->getAvailableLanguages(); + if ( count( $renderLangOptions ) >= 1 ) { + $currentLanguage = $renderLang; + $defaultLang = $this->displayImg->getDefaultRenderLanguage(); + if ( is_null( $currentLanguage ) ) { + $currentLanguage = $defaultLang; + } + $out->addHtml( $this->doRenderLangOpt( $renderLangOptions, $currentLanguage, $defaultLang ) ); + } + // Add cannot animate thumbnail warning if ( !$this->displayImg->canAnimateThumbIfAppropriate() ) { // Include the extension so wiki admins can @@ -947,6 +957,72 @@ EOT ? $wgImageLimits[$option] : array( 800, 600 ); // if nothing is set, fallback to a hardcoded default } + + /** + * Output a drop-down box for language options for the file + * + * @param Array $langChoices Array of string language codes + * @param String $curLang Language code file is being viewed in. + * @param String $defaultLang Language code that image is rendered in by default + * @return String HTML to insert underneath image. + */ + protected function doRenderLangOpt( array $langChoices, $curLang, $defaultLang ) { + global $wgScript; + sort( $langChoices ); + $curLang = wfBCP47( $curLang ); + $defaultLang = wfBCP47( $defaultLang ); + $opts = ''; + $haveCurrentLang = false; + $haveDefaultLang = false; + + // We make a list of all the language choices in the file. + // Additionally if the default language to render this file + // is not included as being in this file (for example, in svgs + // usually the fallback content is the english content) also + // include a choice for that. Last of all, if we're viewing + // the file in a language not on the list, add it as a choice. + foreach ( $langChoices as $lang ) { + $code = wfBCP47( $lang ); + $name = Language::fetchLanguageName( $code, $this->getContext()->getLanguage()->getCode() ); + if ( $name !== '' ) { + $display = wfMessage( 'img-lang-opt', $code, $name )->text(); + } else { + $display = $code; + } + $opts .= "\n" . XML::Option( $display, $code, $curLang === $code ); + if ( $curLang === $code ) { + $haveCurrentLang = true; + } + if ( $defaultLang === $code ) { + $haveDefaultLang = true; + } + } + if ( !$haveDefaultLang ) { + // Its hard to know if the content is really in the default language, or + // if its just unmarked content that could be in any language. + $opts = XML::Option( wfMessage( 'img-lang-default' )->text(), '', $defaultLang === $curLang ) . $opts; + } + if ( !$haveCurrentLang && $defaultLang !== $curLang ) { + $name = Language::fetchLanguageName( $curLang, $this->getContext()->getLanguage()->getCode() ); + if ( $name !== '' ) { + $display = wfMessage( 'img-lang-opt', $curLang, $name )->text(); + } else { + $display = $curLang; + } + $opts = XML::Option( $display, $curLang, true ) . $opts; + } + + $select = Html::rawElement( 'select', array( 'id' => 'mw-imglangselector', 'name' => 'lang' ), $opts ); + $submit = Xml::submitButton( wfMessage( 'img-lang-go' )->text() ); + + $formContents = wfMessage( 'img-lang-info' )->rawParams( $select, $submit )->parse() + . Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() ); + + $langSelectLine = Html::rawElement( 'div', array( 'id' => 'mw-imglangselector-line' ), + Html::rawElement( 'form', array( 'action' => $wgScript ), $formContents ) + ); + return $langSelectLine; + } } /** diff --git a/includes/filerepo/file/File.php b/includes/filerepo/file/File.php index 7d9e79deac..1c9d8aacf5 100644 --- a/includes/filerepo/file/File.php +++ b/includes/filerepo/file/File.php @@ -495,6 +495,42 @@ abstract class File { } } + /** + * Gives a (possibly empty) list of languages to render + * the file in. + * + * If the file doesn't have translations, or if the file + * format does not support that sort of thing, returns + * an empty array. + * + * @return Array + * @since 1.23 + */ + public function getAvailableLanguages() { + $handler = $this->getHandler(); + if ( $handler ) { + return $handler->getAvailableLanguages( $this ); + } else { + return array(); + } + } + + /** + * In files that support multiple language, what is the default language + * to use if none specified. + * + * @return String lang code, or null if filetype doesn't support multiple languages. + * @since 1.23 + */ + public function getDefaultRenderLanguage() { + $handler = $this->getHandler(); + if ( $handler ) { + return $handler->getDefaultRenderLanguage( $this ); + } else { + return null; + } + } + /** * Will the thumbnail be animated if one would expect it to be. * diff --git a/includes/media/MediaHandler.php b/includes/media/MediaHandler.php index b3be21eef7..1dc74ce9fe 100644 --- a/includes/media/MediaHandler.php +++ b/includes/media/MediaHandler.php @@ -747,4 +747,30 @@ abstract class MediaHandler { wfHostname(), $retval, $errMessage, $cmd ) ); } + /** + * Get list of languages file can be viewed in. + * + * @param File $file + * @return Array Array of language codes, or empty array if unsupported. + * @since 1.23 + */ + public function getAvailableLanguages( File $file ) { + return array(); + } + + /** + * On file types that support renderings in multiple languages, + * which language is used by default if unspecified. + * + * If getAvailableLanguages returns a non-empty array, this must return + * a valid language code. Otherwise can return null if files of this + * type do not support alternative language renderings. + * + * @param File $file + * @return String language code or null if multi-language not supported for filetype. + * @since 1.23 + */ + public function getDefaultRenderLanguage( File $file ) { + return null; + } } diff --git a/includes/media/SVG.php b/includes/media/SVG.php index 6864de4675..5a61bcc336 100644 --- a/includes/media/SVG.php +++ b/includes/media/SVG.php @@ -76,6 +76,43 @@ class SvgHandler extends ImageHandler { return false; } + /** + * Which languages (systemLanguage attribute) is supported. + * + * @note This list is not guaranteed to be exhaustive. + * To avoid OOM errors, we only look at first bit of a file. + * Thus all languages on this list are present in the file, + * but its possible for the file to have a language not on + * this list. + * + * @param File $file + * @return Array of language codes, or empty if no language switching supported. + */ + public function getAvailableLanguages( File $file ) { + $metadata = $file->getMetadata(); + $langList = array(); + if ( $metadata ) { + $metadata = $this->unpackMetadata( $metadata ); + if ( isset( $metadata['translations'] ) ) { + foreach( $metadata['translations'] as $lang => $langType ) { + if ( $langType === SvgReader::LANG_FULL_MATCH ) { + $langList[] = $lang; + } + } + } + } + return $langList; + } + + /** + * What language to render file in if none selected. + * + * @return String language code. + */ + public function getDefaultRenderLanguage( File $file ) { + return 'en'; + } + /** * We do not support making animated svg thumbnails */ @@ -129,7 +166,7 @@ class SvgHandler extends ImageHandler { $clientHeight = $params['height']; $physicalWidth = $params['physicalWidth']; $physicalHeight = $params['physicalHeight']; - $lang = isset( $params['lang'] ) ? $params['lang'] : 'en'; + $lang = isset( $params['lang'] ) ? $params['lang'] : $this->getDefaultRenderLanguage( $image ); if ( $flags & self::TRANSFORM_LATER ) { return new ThumbnailImage( $image, $dstUrl, $dstPath, $params ); diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index f5ecbe1b36..f03b60f882 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -4628,6 +4628,11 @@ Please confirm that you really want to recreate this page.", 'imgmultigo' => 'Go!', 'imgmultigoto' => 'Go to page $1', +'img-lang-opt' => '$2 ($1)', +'img-lang-default' => '(default language)', +'img-lang-info' => 'Render this image in $1 $2.', +'img-lang-go' => 'Go', + # Table pager 'ascending_abbrev' => 'asc', 'descending_abbrev' => 'desc', diff --git a/languages/messages/MessagesQqq.php b/languages/messages/MessagesQqq.php index f74f78b1a0..1c7d11f4d4 100644 --- a/languages/messages/MessagesQqq.php +++ b/languages/messages/MessagesQqq.php @@ -9573,6 +9573,17 @@ See also: See also: * {{msg-mw|Imgmultigo|Submit button text}}', +'img-lang-opt' => '{{optional}} Items in the language drop down on the image page for a translated SVG file. For an example see [[:File:Gerrit patchset 25838 test.svg]]. See also {{msg-mw|img-lang-info}} + +* $1 Language code +* $2 Language name (Either in the language in question, or the name of that language translated to the current users interface language)', +'img-lang-default' => 'An option in the drop down of a translatable file. For example see [[:File:Gerrit patchset 25838 test.svg]]. Used when it cannot be determined what the default fallback language is. However it should be noted that most of the time, the content displayed for this option would be in English.', +'img-lang-info' => 'Label for drop down box. Appears underneath the image on the image description page. See [[:File:Gerrit patchset 25838 test.svg]] for an example. + +* $1 is a drop down box with language options (See also {{msg-mw|img-lang-opt}}) +* $2 is a submit button, which uses the text from {{msg-mw|img-lang-go}}', +'img-lang-go' => 'Go button for the language select for translatable files. See [[:File:Gerrit patchset 25838 test.svg]] for an example. See {{msg-mw|img-lang-info}}.', + # Table pager 'ascending_abbrev' => 'Abbreviation of ascending order. See also: diff --git a/maintenance/language/messageTypes.inc b/maintenance/language/messageTypes.inc index 6d4a46d013..80a31bc707 100644 --- a/maintenance/language/messageTypes.inc +++ b/maintenance/language/messageTypes.inc @@ -488,6 +488,7 @@ $wgOptionalMessages = array( 'limitreport-expansiondepth-value', 'limitreport-expensivefunctioncount-value', 'interlanguage-link-title', + 'img-lang-opt', ); /** Exif messages, which may be set as optional in several checks, but are generally mandatory */ diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc index 450da62d25..6aeb3aee55 100644 --- a/maintenance/language/messages.inc +++ b/maintenance/language/messages.inc @@ -3498,6 +3498,12 @@ $wgMessageStructure = array( 'imgmultigo', 'imgmultigoto', ), + 'img-lang' => array( + 'img-lang-opt', + 'img-lang-default', + 'img-lang-info', + 'img-lang-go', + ), 'tablepager' => array( 'ascending_abbrev', 'descending_abbrev', @@ -4169,6 +4175,7 @@ Variants for Chinese language", 'watch-unwatch' => 'action=watch/unwatch', 'separators' => 'Separators for various lists, etc.', 'imgmulti' => 'Multipage image navigation', + 'img-lang' => 'Language selector for translatable SVGs', 'tablepager' => 'Table pager', 'autosumm' => 'Auto-summaries', 'autoblock_whitelist' => 'Autoblock whitelist',