(bug 33658) support for {{GRAMMAR:}} in jqueryMsg
This add GRAMMAR support to the mediawiki.jqueryMsg module: 1. make jqueryMsg understand GRAMMAR(case insensitive) 2. mw.language get convertGrammar, can be overridden per language as in php 3. Introduce resourceloader module ResourceLoaderLanguageDataModule 4. Language.php get a method to filter wgGrammerForms for the current contentLanguage. 5. Qunit tests 6. This code was originally written in jsgrammar branch of svn and had reviewed during the last slush time. Change-Id: I90dd0b2f0cb30fd30539896c292829adc4fc7364
This commit is contained in:
parent
477d34c31b
commit
931c31c7bd
7 changed files with 186 additions and 3 deletions
|
|
@ -739,6 +739,7 @@ $wgAutoloadLocalClasses = array(
|
|||
'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
|
||||
|
|
|
|||
79
includes/resourceloader/ResourceLoaderLanguageDataModule.php
Normal file
79
includes/resourceloader/ResourceLoaderLanguageDataModule.php
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?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' );
|
||||
}
|
||||
}
|
||||
|
|
@ -3233,7 +3233,18 @@ class 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}}.
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ return array(
|
|||
'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(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,52 @@
|
|||
*/
|
||||
( 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
|
||||
*
|
||||
|
|
@ -122,7 +167,28 @@ mw.language = {
|
|||
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 );
|
||||
|
|
|
|||
|
|
@ -664,8 +664,19 @@
|
|||
}
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -41,3 +41,15 @@ test( 'mw.jqueryMsg Gender', function() {
|
|||
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' );
|
||||
} );
|
||||
|
|
|
|||
Loading…
Reference in a new issue