'ResourceLoaderUserModule' => 'includes/resourceloader/ResourceLoaderUserModule.php',
'ResourceLoaderUserOptionsModule' => 'includes/resourceloader/ResourceLoaderUserOptionsModule.php',
'ResourceLoaderUserTokensModule' => 'includes/resourceloader/ResourceLoaderUserTokensModule.php',
+ 'ResourceLoaderLanguageDataModule' => 'includes/resourceloader/ResourceLoaderLanguageDataModule.php',
'ResourceLoaderWikiModule' => 'includes/resourceloader/ResourceLoaderWikiModule.php',
# includes/revisiondelete
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Santhosh Thottingal
+ * @author Timo Tijhof
+ */
+
+/**
+ * ResourceLoader module for populating language specific data.
+ */
+class ResourceLoaderLanguageDataModule extends ResourceLoaderModule {
+
+ /**
+ * Get the grammer forms for the site content language.
+ *
+ * @return array
+ */
+ protected function getSiteLangGrammarForms() {
+ global $wgContLang;
+ return $wgContLang->getGrammarForms();
+ }
+
+ /**
+ * @param $context ResourceLoaderContext
+ * @return string Javascript code
+ */
+ public function getScript( ResourceLoaderContext $context ) {
+ global $wgContLang;
+
+ return Xml::encodeJsCall( 'mw.language.setData', array(
+ $wgContLang->getCode(),
+ array( 'grammarForms' => $this->getSiteLangGrammarForms() )
+ ) );
+ }
+
+ /**
+ * @param $context ResourceLoaderContext
+ * @return array|int|Mixed
+ */
+ public function getModifiedTime( ResourceLoaderContext $context ) {
+ $cache = wfGetCache( CACHE_ANYTHING );
+ $key = wfMemcKey( 'resourceloader', 'langdatamodule', 'changeinfo' );
+
+ $forms = $this->getSiteLangGrammarForms();
+ $hash = md5( serialize( $forms ) );
+
+ $result = $cache->get( $key );
+ if ( is_array( $result ) ) {
+ if ( $result['hash'] === $hash ) {
+ return $result['timestamp'];
+ }
+ }
+ $timestamp = wfTimestamp();
+ $cache->set( $key, array( 'hash' => $hash, 'timestamp' => $timestamp ) );
+ return $timestamp;
+ }
+
+ /**
+ * @return array
+ */
+ public function getDependencies() {
+ return array( 'mediawiki.language' );
+ }
+}
}
return $word;
}
-
+ /**
+ * Get the grammar forms for the content language
+ * @return array of grammar forms
+ * @since 1.20
+ */
+ function getGrammarForms() {
+ global $wgGrammarForms;
+ if ( isset( $wgGrammarForms[$this->getCode()] ) && is_array( $wgGrammarForms[$this->getCode()] ) ) {
+ return $wgGrammarForms[$this->getCode()];
+ }
+ return array();
+ }
/**
* Provides an alternative text depending on specified gender.
* Usage {{gender:username|masculine|feminine|neutral}}.
'user.options' => array( 'class' => 'ResourceLoaderUserOptionsModule' ),
'user.tokens' => array( 'class' => 'ResourceLoaderUserTokensModule' ),
+ // Scripts for the dynamic language specific data, like grammar forms.
+ 'mediawiki.language.data' => array( 'class' => 'ResourceLoaderLanguageDataModule' ),
+
/* Skins */
'skins.chick' => array(
*/
( function( $, mw ) {
-mw.language = {
+var language = {
+ /**
+ * @var data {Object} Language related data (keyed by language,
+ * contains instances of mw.Map).
+ * @example Set data
+ * <code>
+ * // Override, extend or create the language data object of 'nl'
+ * mw.language.setData( 'nl', 'myKey', 'My value' );
+ * </code>
+ * @example Get GrammarForms data for language 'nl':
+ * <code>
+ * var grammarForms = mw.language.getData( 'nl', 'grammarForms' );
+ * </code>
+ */
+ data: {},
+
+ /**
+ * Convenience method for retreiving language data by language code and data key,
+ * covering for the potential inexistance of a data object for this langiage.
+ * @param langCode {String}
+ * @param dataKey {String}
+ * @return {mixed} Value stored in the mw.Map (or undefined if there is no map for
+ the specified langCode).
+ */
+ getData: function ( langCode, dataKey ) {
+ var langData = language.data;
+ if ( langData[langCode] instanceof mw.Map ) {
+ return langData[langCode].get( dataKey );
+ }
+ return undefined;
+ },
+
+ /**
+ * Convenience method for setting language data by language code and data key.
+ * Creates a data object if there isn't one for the specified language already.
+ * @param langCode {String}
+ * @param dataKey {String}
+ * @param value {mixed}
+ */
+ setData: function ( langCode, dataKey, value ) {
+ var langData = language.data;
+ if ( !( langData[langCode] instanceof mw.Map ) ) {
+ langData[langCode] = new mw.Map();
+ }
+ langData[langCode].set( dataKey, value );
+ },
/**
* Process the PLURAL template substitution
*
return ( forms.length === 3 ) ? forms[2] : forms[0];
},
+ /**
+ * Grammatical transformations, needed for inflected languages.
+ * Invoked by putting {{grammar:form|word}} in a message.
+ * The rules can be defined in $wgGrammarForms global or grammar
+ * forms can be computed dynamically by overriding this method per language
+ *
+ * @param word {String}
+ * @param form {String}
+ * @return {String}
+ */
+ convertGrammar: function ( word, form ) {
+ var grammarForms = language.getData( mw.config.get( 'wgContentLanguage' ), 'grammarForms' );
+ if ( grammarForms && grammarForms[form] ) {
+ return grammarForms[form][word] || word;
+ }
+ return word;
+ },
+
// Digit Transform Table, populated by language classes where applicable
'digitTransformTable': null
};
+
+mw.language = language;
+
} )( jQuery, mediaWiki );
}
var forms = nodes.slice(1);
return this.language.gender( gender, forms );
- }
+ },
+ /**
+ * Transform parsed structure into grammar conversion.
+ * Invoked by putting {{grammar:form|word}} in a message
+ * @param {Array} of nodes [{Grammar case eg: genitive}, {String word}]
+ * @return {String} selected grammatical form according to current language
+ */
+ grammar: function( nodes ) {
+ var form = nodes[0];
+ var word = nodes[1];
+ return word && form && this.language.convertGrammar( word, form );
+ }
};
// deprecated! don't rely on gM existing.
ok( mw.messages.set( 'gender-msg-wrong', '{{gender}} is awesome' ), 'mw.messages.set: Register' );
equal( parser( 'gender-msg-wrong', 'female' ) , ' is awesome', 'Wrong syntax used, but ignore the {{gender}}' );
} );
+
+
+test( 'mw.jqueryMsg Grammar', function() {
+ expect( 5 );
+ var parser = mw.jqueryMsg.getMessageFunction();
+ ok( parser, 'Parser Function initialized' );
+ // Hope the grammar form grammar_case_foo is not valid in any language
+ ok( mw.messages.set( 'grammar-msg', 'Przeszukaj {{GRAMMAR:grammar_case_foo|{{SITENAME}}}}' ), 'mw.messages.set: Register' );
+ equal( parser( 'grammar-msg' ) , 'Przeszukaj ' + mw.config.get( 'wgSiteName' ) , 'Grammar Test with sitename' );
+ ok( mw.messages.set( 'grammar-msg-wrong-syntax', 'Przeszukaj {{GRAMMAR:grammar_case_xyz}}' ), 'mw.messages.set: Register' );
+ equal( parser( 'grammar-msg-wrong-syntax' ) , 'Przeszukaj ' , 'Grammar Test with wrong grammar template syntax' );
+} );