I have managed to make changes to code which enable users to choose their user interface language, feature sought at Wikisource, Wiktionary etc. To whom should I send the code?
On Apr 23, 2004, at 03:57, Nikola Smolenski wrote:
I have managed to make changes to code which enable users to choose their user interface language, feature sought at Wikisource, Wiktionary etc. To whom should I send the code?
Same place you're posting this question. :)
-- brion vibber (brion @ pobox.com)
On Friday 23 April 2004 13:46, Brion Vibber wrote:
On Apr 23, 2004, at 03:57, Nikola Smolenski wrote:
I have managed to make changes to code which enable users to choose their user interface language, feature sought at Wikisource, Wiktionary etc. To whom should I send the code?
Same place you're posting this question. :)
Since that message, I've noticed some bugs and had no time to fix them, but now I think I can present a beta version. Note I worked against 1.2.0rc3 and not against the CVS; this because if I did something in the wrong way, and a rewrite is needed, I didn't want to adapt to CVS changes at the same time. I hope this will be no problem. I have to say that I have a SF account and know how to work with the CVS, so I can submit the code changes directly to it, if needed. Differences follow:
I think that this is quite selfexplanatory. If $wgLanguageCode is a string, then there is old-fashioned monolingual interface. If it is an array, then a multilingual interface.
LocalSettings.php: $wgLanguageCode = array("en","de","sr");
Changes in SpecialPreferences.php were the most straightforward. If $wpLanguage is satisfying name, they may go to the CVS, they do no harm even if nothing else is imlepmented. I have put language chooser at the very top, since users who do not know the main language will need it the most.
*** ../../Documents/Download/mediawiki-1.2.0rc3/includes/SpecialPreferences.phpWed Feb 18 03:14:56 2004 --- ./SpecialPreferences.php Sat May 8 11:30:09 2004 *************** *** 87,92 **** --- 87,93 ---- global $wpSkin, $wpMath, $wpDate, $wpUserEmail, $wpEmailFlag, $wpNick, $wpSearch, $wpRecent; global $wpSearchLines, $wpSearchChars, $wpStubs; global $wpRows, $wpCols, $wpHourDiff, $HTTP_POST_VARS; + global $wpLanguage;
if ( "" != $wpNewpass ) { if ( $wpNewpass != $wpRetypePass ) { *************** *** 116,121 **** --- 117,123 ---- $wgUser->setOption( "cols", validateInt( $wpCols, 4, 1000 ) ); $wgUser->setOption( "stubthreshold", validateIntOrNull( $wpStubs ) ); $wgUser->setOption( "timecorrection", validateTimeZone( $wpHourDiff, -12, 14 ) ); + $wgUser->setOption( "language", $wpLanguage );
$namespaces = $wgLang->getNamespaces(); # Set search namespace options *************** *** 151,156 **** --- 153,159 ---- global $wpRows, $wpCols, $wpSkin, $wpMath, $wpDate, $wpUserEmail, $wpEmailFlag, $wpNick; global $wpSearch, $wpRecent, $HTTP_POST_VARS; global $wpHourDiff, $wpSearchLines, $wpSearchChars; + global $wpLanguage;
$wpOldpass = $wpNewpass = $wpRetypePass = ""; $wpUserEmail = $wgUser->getEmail(); *************** *** 170,175 **** --- 173,179 ---- $wpSearchLines = $wgUser->getOption( "contextlines" ); $wpSearchChars = $wgUser->getOption( "contextchars" ); $wpRecent = $wgUser->getOption( "rclimit" ); + $wpLanguage = $wgUser->getOption( "language" );
$togs = $wgLang->getUserToggles(); foreach ( $togs as $tname => $ttext ) { *************** *** 213,223 ****
/* private */ function mainPrefsForm( $err ) { ! global $wgUser, $wgOut, $wgLang, $wgUseDynamicDates; global $wpQuickbar, $wpOldpass, $wpNewpass, $wpRetypePass; global $wpSkin, $wpMath, $wpDate, $wpUserEmail, $wpEmailFlag, $wpNick, $wpSearch, $wpRecent; global $wpRows, $wpCols, $wpSaveprefs, $wpReset, $wpHourDiff; global $wpSearchLines, $wpSearchChars, $wpStubs, $wgValidSkinNames;
$wgOut->setPageTitle( wfMsg( "preferences" ) ); $wgOut->setArticleRelated( false ); --- 217,228 ----
/* private */ function mainPrefsForm( $err ) { ! global $wgUser, $wgOut, $wgLang, $wgUseDynamicDates,$wgLanguageArray,$wgLanguageCode,$wgLanguageNames; global $wpQuickbar, $wpOldpass, $wpNewpass, $wpRetypePass; global $wpSkin, $wpMath, $wpDate, $wpUserEmail, $wpEmailFlag, $wpNick, $wpSearch, $wpRecent; global $wpRows, $wpCols, $wpSaveprefs, $wpReset, $wpHourDiff; global $wpSearchLines, $wpSearchChars, $wpStubs, $wgValidSkinNames; + global $wpLanguage;
$wgOut->setPageTitle( wfMsg( "preferences" ) ); $wgOut->setArticleRelated( false ); *************** *** 269,275 **** $dsn = wfMsg( "defaultns" );
$wgOut->addHTML( "<form id="preferences" name="preferences" action="$action" ! method="post"><table border="1"><tr><td valign=top nowrap><b>$qb:</b><br>\n" );
# Quickbar setting # --- 274,290 ---- $dsn = wfMsg( "defaultns" );
$wgOut->addHTML( "<form id="preferences" name="preferences" action="$action" ! method="post"><table border="1">"); ! ! if(is_array($wgLanguageArray)) { ! $wgOut->addHTML("<tr><td colspan=2><b>Language:</b>"); ! $wgOut->addHTML("<select name="wpLanguage">"); ! foreach($wgLanguageArray as $v) ! $wgOut->addHTML("<option value="$v" ".(($v==$wpLanguage)?"selected":"").">{$wgLanguageNames[$v]}</option>"); ! $wgOut->addHTML("</select></td></tr>"); ! } ! ! $wgOut->addHTML("<tr><td valign=top nowrap><b>$qb:</b><br>\n" );
# Quickbar setting #
Most changes were needed to the Setup.php. Creation of an user and loading of the language had to be executed earlier, but that is not a problem. But here there was a big problem with circular dependency. User.php requires Language.php because some default user settings are language-dependent. But, apparently, an user must be created in order to know which language settings to choose! I have not solved this in a satisfactory enough way, and all users have, let's call them, international default settings:
*** ../../Documents/Download/mediawiki-1.2.0rc3/includes/Setup.php Thu Feb 26 14:37:26 2004 --- ./Setup.php Sat May 8 11:46:25 2004 *************** *** 123,129 **** --- 123,146 ---- wfProfileOut( "$fname-memcached" ); wfProfileIn( "$fname-misc" );
+ if( !$wgCommandLineMode && isset( $_COOKIE[ini_get("session.name")] ) ) { + User::SetupSession(); + } + include_once( "Language.php" ); + $wgUser = User::loadFromSession(); + if(is_array($wgLanguageCode)) { + $wgLanguageArray=$wgLanguageCode; + if($_GET['language']&&in_array($_GET['language'],$wgLanguageArray)) { + $wgLanguageCode=$_GET['language']; + } else if($_POST['wpLanguage']&&in_array($_POST['wpLanguage'],$wgLanguageArray)) { + $wgLanguageCode=$_POST['wpLanguage']; + } else { + $wgLanguageCode = $wgUser->getOption("language"); + } + } + @include_once( "Language" . ucfirst( $wgLanguageCode ) . ".php" ); + if(is_array($wgLanguageArray)) eval("$wgNamespaceNames".ucfirst( $wgLanguageCode )."=$wgNamespaceNamesEn;");
$wgMessageCache = new MessageCache;
*************** *** 148,159 **** $wgDateFormatter = new DateFormatter; }
- if( !$wgCommandLineMode && isset( $_COOKIE[ini_get("session.name")] ) ) { - User::SetupSession(); - } - $wgBlockCache = new BlockCache( true ); - $wgUser = User::loadFromSession(); $wgDeferredUpdateList = array(); $wgLinkCache = new LinkCache(); $wgMagicWords = array(); --- 165,171 ----
I have copied these international settings from English settings:
*** ../../Documents/Download/mediawiki-1.2.0rc3/includes/User.php Sun Mar 7 11:07:17 2004 --- ./User.php Sat May 8 11:18:45 2004 *************** *** 11,16 **** --- 11,26 ---- /* private */ var $mBlockedby, $mBlockreason; /* private */ var $mTouched; /* private */ var $mCookiePassword; + /* private */ var $wgDefaultUserOptions = array( + "quickbar" => 1, "underline" => 1, "hover" => 1, + "cols" => 80, "rows" => 25, "searchlimit" => 20, + "contextlines" => 5, "contextchars" => 50, + "skin" => 0, "math" => 1, "rcdays" => 7, "rclimit" => 50, + "highlightbroken" => 1, "stubthreshold" => 0, + "previewontop" => 1, "editsection"=>1,"editsectiononrightclick"=>0, "showtoc"=>1, + "showtoolbar" =>1, + "date" => 0, "language" => "en" + );
function User() { *************** *** 70,76 ****
function loadDefaults() { ! global $wgLang, $wgIP; global $wgNamespacesToBeSearchedDefault;
$this->mId = $this->mNewtalk = 0; --- 80,86 ----
function loadDefaults() { ! global $wgLang, $wgIP, $wgLanguageCode; global $wgNamespacesToBeSearchedDefault;
$this->mId = $this->mNewtalk = 0; *************** *** 78,84 **** $this->mEmail = ""; $this->mPassword = $this->mNewpassword = ""; $this->mRights = array(); ! $defOpt = $wgLang->getDefaultUserOptions() ; foreach ( $defOpt as $oname => $val ) { $this->mOptions[$oname] = $val; } --- 88,94 ---- $this->mEmail = ""; $this->mPassword = $this->mNewpassword = ""; $this->mRights = array(); ! $defOpt = $this->wgDefaultUserOptions; foreach ( $defOpt as $oname => $val ) { $this->mOptions[$oname] = $val; }
Unrelated to multilingual interface, this is needed because some PHP versions stupidly throw an error when the file is not present:
*** ../../Documents/Download/mediawiki-1.2.0rc3/includes/GlobalFunctions.php Thu Feb 26 21:08:45 2004 --- ./GlobalFunctions.php Fri Mar 12 12:27:18 2004 *************** *** 231,237 **** global $wgReadOnlyFile;
if ( "" == $wgReadOnlyFile ) { return false; } ! return is_file( $wgReadOnlyFile ); }
$wgReplacementKeys = array( "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9" ); --- 231,237 ---- global $wgReadOnlyFile;
if ( "" == $wgReadOnlyFile ) { return false; } ! return @is_file( $wgReadOnlyFile ); }
$wgReplacementKeys = array( "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9" );
So, what do you think?
Nikola Smolenski wrote:
Since that message, I've noticed some bugs and had no time to fix them, but now I think I can present a beta version. Note I worked against 1.2.0rc3 and not against the CVS; this because if I did something in the wrong way, and a rewrite is needed, I didn't want to adapt to CVS changes at the same time. I hope this will be no problem. I have to say that I have a SF account and know how to work with the CVS, so I can submit the code changes directly to it, if needed. Differences follow:
In general I would highly recommend *against* doing significant development on the stable branch. Forward porting things is sometimes more work than expected -- particularly when there are major changes -- or just doesn't get done and your neat new thing gets lost; if you put it in the development version, you just have to wait and it'll become the stable version. ;)
I think that this is quite selfexplanatory. If $wgLanguageCode is a string, then there is old-fashioned monolingual interface. If it is an array, then a multilingual interface.
LocalSettings.php: $wgLanguageCode = array("en","de","sr");
Neat! But there are some problems that need to be overcome.
First, it won't interact at all well with $wgUseDatabaseMessages, since we have no way to distinguish which language a defined message is intended to reach. Now, it's possible to just make the two modes mutually exclusive, so you get the hardcoded messages if in non-default language. That's probably ok.
Second, a number of language-specific options will affect how things are parsed and stored. Namespace interpretation will be different; I notice this is partially taken care of in your patch by run-time patching to hardcode the English names, but some languages define additional aliased names which would break under another class, and it would be preferable to always use the content language's names rather than English.
Some languages are still using Latin-1 charset, and you really can't mix Latin-1 with UTF-8. Besides the encoding of the messages themselves, the fulltext search index is treated very differently between latin-1 and UTF-8, and some languages such as Chinese and Japanese do some different work to insert simulated word spaces. At some point (hopefully for 1.4) we'll want to add language-specific sorting for displays of titles/usernames etc, which will require generating and storing indexes which depend on the content language.
As for the Latin1/UTF-8 thing, I'd like to just transition everything to UTF-8. Hopefully we'll do that soon, as we've been moving tentatively in that direction, and it'll end up a non-problem.
Most of the other stuff could be dealt with by defining a 'master language' which controls the content encoding, namespace definitions, logpage names, logpage content, material used for {{transposed}} and substituted messages in content, etc, and a 'display language' which can be selected by the user which will determine the language used for user interface messages. This probably requires more work on the language classes and messages to separate out links.
Also I'm not keen on changing the value and type of $wgLanguageCode. It would be best I think to keep things predictable and separate the array of selectable languages from the master/content language.
-- brion vibber (brion @ pobox.com)
On Saturday 08 May 2004 12:42, Brion Vibber wrote:
Nikola Smolenski wrote:
Since that message, I've noticed some bugs and had no time to fix them, but now I think I can present a beta version. Note I worked against 1.2.0rc3 and not against the CVS; this because if I did something in the wrong way, and a rewrite is needed, I didn't want to adapt to CVS changes at the same time. I hope this will be no problem. I have to say that I have a SF account and know how to work with the CVS, so I can submit the code changes directly to it, if needed. Differences follow:
In general I would highly recommend *against* doing significant development on the stable branch. Forward porting things is sometimes more work than expected -- particularly when there are major changes -- or just doesn't get done and your neat new thing gets lost; if you put it in the development version, you just have to wait and it'll become the stable version. ;)
OK, I'll make future patches against the unstable branch.
I think that this is quite selfexplanatory. If $wgLanguageCode is a string, then there is old-fashioned monolingual interface. If it is an array, then a multilingual interface.
LocalSettings.php: $wgLanguageCode = array("en","de","sr");
Neat! But there are some problems that need to be overcome.
First, it won't interact at all well with $wgUseDatabaseMessages, since we have no way to distinguish which language a defined message is intended to reach. Now, it's possible to just make the two modes mutually exclusive, so you get the hardcoded messages if in non-default language. That's probably ok.
No it won't. I have disabled it, and it's easy to make sure that if one is set, the other one is forcefully disabled:
if(is_array($wgLanguageCode)) { $wgLanguageArray=$wgLanguageCode; $wgUseDatabaseMessages=FALSE;
$wgUseDatabaseMessages is not used prior to this point.
Second, a number of language-specific options will affect how things are parsed and stored. Namespace interpretation will be different; I notice this is partially taken care of in your patch by run-time patching to hardcode the English names, but some languages define additional aliased names which would break under another class, and it would be preferable to always use the content language's names rather than English.
A final solution for this would require that, eventually, a MediaWiki installation in ''any'' language recognises codes of ''every'' language. Eventually, this could be done, but until it is done I think that multilingual installations could use English messages only. As I understand, this is needed for Wikisource, Wikibooks and Wiktionary and staying with English is at least as good as what is already there :)
if(is_array($wgLanguageArray)) eval("$wgNamespaceNames".ucfirst( $wgLanguageCode )."=$wgNamespaceNamesEn;");
should be changed to:
if(is_array($wgLanguageArray)) { eval("$wgNamespaceNames".ucfirst( $wgLanguageCode )."=$wgNamespaceNamesEn;"); eval("$wgMagicWords".ucfirst( $wgLanguageCode )."=$wgMagicWordsEn;"); eval("$wgAllMessages".ucfirst( $wgLanguageCode )."['linktrail']=$wgAllMessagesEn['linktrail'];"); eval("$wgAllMessages".ucfirst( $wgLanguageCode )."['uploadlog']=$wgAllMessagesEn['uploadlog'];"); eval("$wgAllMessages".ucfirst( $wgLanguageCode )."['uploadlogpage']=$wgAllMessagesEn['uploadlogpage'];"); eval("$wgAllMessages".ucfirst( $wgLanguageCode )."['deletionlog']=$wgAllMessagesEn['deletionlog'];"); }
That linktrail bit might be a bit of a problem. But even this way, again, it is at least as good as what is there already. Eventually, linktrail should be specific to a code page, not a language. Whether it would be reasonable to do so for UTF-8 I am not sure.
I think that these are all options which affect affect how things are parsed and stored. If I have missed something, tell. I was thinking about also forcing following and other similar options to English:
"mainpage" => "Main Page", "aboutpage" => "$wgMetaNamespace:About", "helppage" => "$wgMetaNamespace:Help",
But as a multilingual site would need to have them in all its languages, I proclaim this a feature, not a bug! :)
Some languages are still using Latin-1 charset, and you really can't mix Latin-1 with UTF-8. Besides the encoding of the messages themselves, the fulltext search index is treated very differently between latin-1 and UTF-8, and some languages such as Chinese and Japanese do some different work to insert simulated word spaces. At some point (hopefully for 1.4) we'll want to add language-specific sorting for displays of titles/usernames etc, which will require generating and storing indexes which depend on the content language.
Yes. One can use all languages in same encoding (all Latin-1, all Latin-2, all UTF-8...) but can not mix encodings. It is trivial to convert any language to UTF-8, except for the linktrail which is not used anyway. Wikisource, Wikibooks and Wiktionary are in UTF-8 already, so I don't think it will be a problem for them. I don't think that language-specific sorting will be a problem when introduced; an user will simply see text sorted in his language. But good luck to one who is going to implement it in UTF-8 for all languages! As for Chinese and Japanese, you were referring to stripForSearch? I don't think that it is a problem, Chinese and Japanese users will be able to search properly, other users will not, but they are not now anyway. But take a look at this:
# Italic is not appropriate for Japanese script # Unfortunately most browsers do not recognise this, and render <em> as italic function emphasize( $text ) { return $text; }
It could make some problems. Eventually, things like this should be specific to the language of a page or even a section of a page. Currently, if Japanese Wikipedia has some emphasized text in English, or if English Wikipedia has some emphasized text in Japanese, things don't work properly. Perhaps emphasize function in Language.php should be remade to not emphasize Japanese and Chinese characters. I don't want to even imagine how that could be done.
Most of the other stuff could be dealt with by defining a 'master language' which controls the content encoding, namespace definitions, logpage names, logpage content, material used for {{transposed}} and substituted messages in content, etc, and a 'display language' which can be selected by the user which will determine the language used for user interface messages. This probably requires more work on the language classes and messages to separate out links.
Yes. Well, currently, English acts as the master language. In future, it should be possible to have some other language as a master language.
Also I'm not keen on changing the value and type of $wgLanguageCode. It would be best I think to keep things predictable and separate the array of selectable languages from the master/content language.
Not a problem. I agree, in light of being able to use another master language in future (that language would then be defined in $wgLanguageCode). While $wgLanguageCodes might be the most intuitive name, it could be easily overlooked, so how about $wgLanguageArray?
If all of this is fine, I'm downloading the code from the CVS, and sending the patches.
Nikola Smolenski wrote:
Yes. One can use all languages in same encoding (all Latin-1, all Latin-2, all UTF-8...) but can not mix encodings. It is trivial to convert any language to UTF-8, except for the linktrail which is not used anyway. Wikisource, Wikibooks and Wiktionary are in UTF-8 already, so I don't think it will be a problem for them.
All the remaining latin-1 language files will have to be upgraded to do that, or appropriate run-time upconversion added.
I don't think that language-specific sorting will be a problem when introduced; an user will simply see text sorted in his language.
The sorting will have to be hard-coded into the index fields in the tables, so it must be uniform for all saved data. Everything displayed will use the same uniform sorting method, as it's impractical to add dozens of sort indexes for every conceivable language to a table with hundreds of thousands of pages.
But good luck to one who is going to implement it in UTF-8 for all languages! As for Chinese and Japanese, you were referring to stripForSearch? I don't think that it is a problem, Chinese and Japanese users will be able to search properly, other users will not, but they are not now anyway.
Yes, that's one of the problem functions. It's about saving the index data consistently, and reading it back properly. The data must always be stored and interpreted in a consistent way.
-- brion vibber (brion @ pobox.com)
On Tuesday 11 May 2004 07:48, Brion Vibber wrote:
Nikola Smolenski wrote:
Yes. One can use all languages in same encoding (all Latin-1, all Latin-2, all UTF-8...) but can not mix encodings. It is trivial to convert any language to UTF-8, except for the linktrail which is not used anyway. Wikisource, Wikibooks and Wiktionary are in UTF-8 already, so I don't think it will be a problem for them.
All the remaining latin-1 language files will have to be upgraded to do that, or appropriate run-time upconversion added.
I don't think that runtime conversion is a good idea.
1) Create Language*Utf.php files which would be used aside current ones. 2) Write a small guide on how to convert existing language files to UTF-8.
I don't think that language-specific sorting will be a problem when introduced; an user will simply see text sorted in his language.
The sorting will have to be hard-coded into the index fields in the tables, so it must be uniform for all saved data. Everything displayed will use the same uniform sorting method, as it's impractical to add dozens of sort indexes for every conceivable language to a table with hundreds of thousands of pages.
Oh, if there will be indexes, then yes, it probably could not be done. As other things, it will have to fall back to English/default language.
But good luck to one who is going to implement it in UTF-8 for all languages! As for Chinese and Japanese, you were referring to stripForSearch? I don't think that it is a problem, Chinese and Japanese users will be able to search properly, other users will not, but they are not now anyway.
Yes, that's one of the problem functions. It's about saving the index data consistently, and reading it back properly. The data must always be stored and interpreted in a consistent way.
I thought only when searching, but now I see that it is used when generating data. Fallback to English for now, though perhaps later something could be done.
I have got the CVS and made the first set of changes. They are unnoticeable if the feature is not enabled and don't do anything even if it is, so they could be safely introduced to the source. I will probably be able to submit rest of the changes soon.
About GlobalFunctions.php: strcasecmp is probably an error, and get_class accepts only one argument. It works this way for me (PHP 4.1.0).
Do you think that documentation for this is needed (if yes, can I use parts of your e-mails to write it)?
Index: LocalSettings.sample =================================================================== RCS file: /cvsroot/wikipedia/phase3/LocalSettings.sample,v retrieving revision 1.34 diff -u -3 -p -r1.34 LocalSettings.sample --- LocalSettings.sample 8 May 2004 02:15:49 -0000 1.34 +++ LocalSettings.sample 16 May 2004 06:25:42 -0000 @@ -141,6 +141,8 @@ $wgLocalInterwiki = $wgSitename;
## If you want a non-English wiki, add a line like this # $wgLanguageCode = "de"; +## If you want your wiki to have several languages, add their codes into an array like this +# $wgLanguageArray = array("en","de","sr");
## Character encoding: normally auto-selected by the language. ## English, German, Danish, Dutch, French, Spanish, and Swedish Index: includes/DefaultSettings.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/DefaultSettings.php,v retrieving revision 1.109 diff -u -3 -p -r1.109 DefaultSettings.php --- includes/DefaultSettings.php 15 May 2004 10:36:58 -0000 1.109 +++ includes/DefaultSettings.php 16 May 2004 06:25:45 -0000 @@ -94,6 +94,7 @@ $wgLinkCacheMemcached = false; # Not ful # $wgLanguageCode = "en"; $wgLanguageFile = false; # Filename of a language file generated by dumpMessages.php +$wgLanguageArray = false; # Monolingual by default $wgInterwikiMagic = true; # Treat language links as magic connectors, not inline links $wgInputEncoding = "ISO-8859-1"; $wgOutputEncoding = "ISO-8859-1"; Index: includes/GlobalFunctions.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/GlobalFunctions.php,v retrieving revision 1.85 diff -u -3 -p -r1.85 GlobalFunctions.php --- includes/GlobalFunctions.php 15 May 2004 14:03:00 -0000 1.85 +++ includes/GlobalFunctions.php 16 May 2004 06:25:48 -0000 @@ -40,8 +40,8 @@ if( !function_exists('is_a') ) { # Exists in PHP 4.2.0+ function is_a( $object, $class_name ) { return - (strcasecmp( get_class( $object, $class_name ) == 0) || - is_subclass_of( $object, $class_name ) ); + ( get_class( $object ) == 0) || + is_subclass_of( $object, $class_name ) ; } }
@@ -261,7 +261,7 @@ function wfReadOnly() global $wgReadOnlyFile;
if ( "" == $wgReadOnlyFile ) { return false; } - return is_file( $wgReadOnlyFile ); + return @is_file( $wgReadOnlyFile ); }
$wgReplacementKeys = array( "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9" ); Index: includes/SpecialPreferences.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/SpecialPreferences.php,v retrieving revision 1.42 diff -u -3 -p -r1.42 SpecialPreferences.php --- includes/SpecialPreferences.php 13 May 2004 14:17:44 -0000 1.42 +++ includes/SpecialPreferences.php 16 May 2004 06:25:50 -0000 @@ -12,7 +12,7 @@ class PreferencesForm { var $mQuickbar, $mOldpass, $mNewpass, $mRetypePass, $mStubs; var $mRows, $mCols, $mSkin, $mMath, $mDate, $mUserEmail, $mEmailFlag, $mNick; var $mSearch, $mRecent, $mHourDiff, $mSearchLines, $mSearchChars, $mAction; - var $mReset, $mPosted, $mToggles, $mSearchNs, $mRealName; + var $mReset, $mPosted, $mToggles, $mSearchNs, $mRealName, $mLanguage;
function PreferencesForm( &$request ) { global $wgLang; @@ -40,6 +40,7 @@ class PreferencesForm { $this->mReset = $request->getCheck( 'wpReset' ); $this->mPosted = $request->wasPosted(); $this->mSaveprefs = $request->getCheck( 'wpSaveprefs' ) && $this->mPosted; + $this->mLanguage = $request->getVal( 'wpLanguage' );
# User toggles (the big ugly unsorted list of checkboxes) $this->mToggles = array(); @@ -159,6 +160,7 @@ class PreferencesForm { $wgUser->setOption( "cols", $this->validateInt( $this->mCols, 4, 1000 ) ); $wgUser->setOption( "stubthreshold", $this->validateIntOrNull( $this->mStubs ) ); $wgUser->setOption( "timecorrection", $this->validateTimeZone( $this->mHourDiff, -12, 14 ) ); + $wgUser->setOption( "language", $this->mLanguage );
# Set search namespace options foreach( $this->mSearchNs as $i => $value ) { @@ -202,6 +204,7 @@ class PreferencesForm { $this->mSearchLines = $wgUser->getOption( "contextlines" ); $this->mSearchChars = $wgUser->getOption( "contextchars" ); $this->mRecent = $wgUser->getOption( "rclimit" ); + $this->mLanguage = $wgUser->getOption( "language" );
$togs = $wgLang->getUserToggles(); foreach ( $togs as $tname => $ttext ) { @@ -265,7 +268,7 @@ class PreferencesForm {
/* private */ function mainPrefsForm( $err ) { - global $wgUser, $wgOut, $wgLang, $wgUseDynamicDates, $wgValidSkinNames; + global $wgUser, $wgOut, $wgLang, $wgUseDynamicDates, $wgValidSkinNames,$wgLanguageArray;
$wgOut->setPageTitle( wfMsg( "preferences" ) ); $wgOut->setArticleRelated( false ); @@ -321,6 +324,20 @@ class PreferencesForm { $wgOut->addHTML( "<form id="preferences" name="preferences" action="$action" method="post">" );
+ # Zeroth section: language + # + if($wgLanguageArray) { + $wgOut->addHTML( "<fieldset> + <legend>Language</legend> + <div><select name="wpLanguage">" ); + foreach( $wgLanguageArray as $v) + $wgOut->addHTML( "<option value="$v" ". + (($v==$this->mLanguage)?"selected":""). + ">".$wgLang->getLanguageName( $v ). + "</option>" ); + $wgOut->addHTML( "</select></div></fieldset>" ); + } + # First section: identity # Email, etc. #
Nikola Smolenski wrote:
About GlobalFunctions.php: strcasecmp is probably an error, and get_class accepts only one argument. It works this way for me (PHP 4.1.0).
No, strcasecmp is correct: get_class always returns a lowercase value, so the comparison needs to be case insensitive. There is however a misnested parenthesis.
-- brion vibber (brion @ pobox.com)
On Sunday 16 May 2004 09:16, Brion Vibber wrote:
Nikola Smolenski wrote:
About GlobalFunctions.php: strcasecmp is probably an error, and get_class accepts only one argument. It works this way for me (PHP 4.1.0).
No, strcasecmp is correct: get_class always returns a lowercase value, so the comparison needs to be case insensitive. There is however a misnested parenthesis.
I see now. OK, here it is, all changes required for the multilingual interface. Now different languages all have different default settings, and everything which needs to fallbacks on English except for Chinese and Japanese. I hope that this could make it to the new release...
Index: LocalSettings.sample =================================================================== RCS file: /cvsroot/wikipedia/phase3/LocalSettings.sample,v retrieving revision 1.34 diff -u -3 -p -r1.34 LocalSettings.sample --- LocalSettings.sample 8 May 2004 02:15:49 -0000 1.34 +++ LocalSettings.sample 22 May 2004 12:25:03 -0000 @@ -141,6 +141,8 @@ $wgLocalInterwiki = $wgSitename;
## If you want a non-English wiki, add a line like this # $wgLanguageCode = "de"; +## If you want your wiki to have several languages, add their codes into an array like this +# $wgLanguageArray = array("en","de","sr");
## Character encoding: normally auto-selected by the language. ## English, German, Danish, Dutch, French, Spanish, and Swedish Index: includes/DefaultSettings.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/DefaultSettings.php,v retrieving revision 1.110 diff -u -3 -p -r1.110 DefaultSettings.php --- includes/DefaultSettings.php 21 May 2004 19:04:52 -0000 1.110 +++ includes/DefaultSettings.php 22 May 2004 12:25:06 -0000 @@ -94,6 +94,7 @@ $wgLinkCacheMemcached = false; # Not ful # $wgLanguageCode = "en"; $wgLanguageFile = false; # Filename of a language file generated by dumpMessages.php +$wgLanguageArray = false; # Monolingual by default $wgInterwikiMagic = true; # Treat language links as magic connectors, not inline links $wgInputEncoding = "ISO-8859-1"; $wgOutputEncoding = "ISO-8859-1"; Index: includes/GlobalFunctions.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/GlobalFunctions.php,v retrieving revision 1.86 diff -u -3 -p -r1.86 GlobalFunctions.php --- includes/GlobalFunctions.php 17 May 2004 20:04:50 -0000 1.86 +++ includes/GlobalFunctions.php 22 May 2004 12:25:09 -0000 @@ -40,8 +40,8 @@ if( !function_exists('is_a') ) { # Exists in PHP 4.2.0+ function is_a( $object, $class_name ) { return - (strcasecmp( get_class( $object, $class_name ) == 0) || - is_subclass_of( $object, $class_name ) ); + (strcasecmp( get_class( $object ), $class_name ) == 0) || + is_subclass_of( $object, $class_name ) ; } }
@@ -261,7 +261,7 @@ function wfReadOnly() global $wgReadOnlyFile;
if ( "" == $wgReadOnlyFile ) { return false; } - return is_file( $wgReadOnlyFile ); + return @is_file( $wgReadOnlyFile ); }
$wgReplacementKeys = array( "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9" ); Index: includes/Setup.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/Setup.php,v retrieving revision 1.47 diff -u -3 -p -r1.47 Setup.php --- includes/Setup.php 15 May 2004 03:36:38 -0000 1.47 +++ includes/Setup.php 22 May 2004 12:25:10 -0000 @@ -144,7 +144,47 @@ if( $wgUseMemCached ) { wfProfileOut( "$fname-memcached" ); wfProfileIn( "$fname-misc" );
-require_once( "languages/Language.php" ); +if( !$wgLanguageArray ) { + require_once( "languages/Language.php" ); +} + +if( !$wgCommandLineMode && ( isset( $_COOKIE[ini_get("session.name")] ) || isset +( $_COOKIE["{$wgDBname}Password"] ) ) ) { + User::SetupSession(); +} + +$wgBlockCache = new BlockCache( true ); +if( $wgCommandLineMode ) { + # Used for some maintenance scripts; user session cookies can screw things up + # when the database is in an in-between state. + $wgUser = new User(); +} else { + $wgUser = User::loadFromSession(); +} + +if( $wgLanguageArray ) { + if($_GET['language']&&in_array($_GET['language'],$wgLanguageArray)) { + $wgLanguageCode=$_GET['language']; + } else if($_POST['wpLanguage']&&in_array($_POST['wpLanguage'],$wgLanguageArray)) { + $wgLanguageCode=$_POST['wpLanguage']; + } else { + $wgLanguageCode = $wgUser->getOption("language"); + } +} + + require_once( "languages/Language.php" ); + +if( $wgLanguageArray ) { + $UCFLC=ucfirst( $wgLanguageCode ); + eval(" + $wgNamespaceNames$UCFLC=$wgNamespaceNamesEn; + $wgMagicWords$UCFLC=$wgMagicWordsEn; + $wgAllMessages$UCFLC ['linktrail']=$wgAllMessagesEn ['linktrail']; + $wgAllMessages$UCFLC ['uploadlog']=$wgAllMessagesEn ['uploadlog']; + $wgAllMessages$UCFLC ['uploadlogpage']=$wgAllMessagesEn ['uploadlogpage']; + $wgAllMessages$UCFLC ['deletionlog']=$wgAllMessagesEn ['deletionlog']; + "); +}
$wgMessageCache = new MessageCache;
@@ -158,6 +198,11 @@ $wgLang = new $wgLangClass(); if ( !is_object($wgLang) ) { print "No language class ($wgLang)\N"; } + +if(!$this->mId) { + $wgUser->setDefaultOptions($wgLang->getDefaultUserOptions()); +} + $wgMessageCache->initialise( $messageMemc, $wgUseDatabaseMessages, $wgMsgCacheExpiry, $wgDBname );
$wgOut = new OutputPage(); @@ -169,7 +214,7 @@ if ( $wgUseDynamicDates ) { $wgDateFormatter = new DateFormatter; }
-if( !$wgCommandLineMode && ( isset( $_COOKIE[ini_get("session.name")] ) || isset( $_COOKIE["{$wgDBname}Password"] ) ) ) { +/*if( !$wgCommandLineMode && ( isset( $_COOKIE[ini_get("session.name")] ) || isset( $_COOKIE["{$wgDBname}Password"] ) ) ) { User::SetupSession(); }
@@ -180,7 +225,7 @@ if( $wgCommandLineMode ) { $wgUser = new User(); } else { $wgUser = User::loadFromSession(); -} +}*/ $wgDeferredUpdateList = array(); $wgLinkCache = new LinkCache(); $wgMagicWords = array(); Index: includes/SpecialPreferences.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/SpecialPreferences.php,v retrieving revision 1.46 diff -u -3 -p -r1.46 SpecialPreferences.php --- includes/SpecialPreferences.php 20 May 2004 11:26:32 -0000 1.46 +++ includes/SpecialPreferences.php 22 May 2004 12:25:11 -0000 @@ -11,7 +11,7 @@ class PreferencesForm { var $mQuickbar, $mOldpass, $mNewpass, $mRetypePass, $mStubs; var $mRows, $mCols, $mSkin, $mMath, $mDate, $mUserEmail, $mEmailFlag, $mNick; var $mSearch, $mRecent, $mHourDiff, $mSearchLines, $mSearchChars, $mAction; - var $mReset, $mPosted, $mToggles, $mSearchNs, $mRealName; + var $mReset, $mPosted, $mToggles, $mSearchNs, $mRealName, $mLanguage;
function PreferencesForm( &$request ) { global $wgLang; @@ -39,6 +39,7 @@ class PreferencesForm { $this->mReset = $request->getCheck( 'wpReset' ); $this->mPosted = $request->wasPosted(); $this->mSaveprefs = $request->getCheck( 'wpSaveprefs' ) && $this->mPosted; + $this->mLanguage = $request->getVal( 'wpLanguage' );
# User toggles (the big ugly unsorted list of checkboxes) $this->mToggles = array(); @@ -158,6 +159,7 @@ class PreferencesForm { $wgUser->setOption( "cols", $this->validateInt( $this->mCols, 4, 1000 ) ); $wgUser->setOption( "stubthreshold", $this->validateIntOrNull( $this->mStubs ) ); $wgUser->setOption( "timecorrection", $this->validateTimeZone( $this->mHourDiff, -12, 14 ) ); + $wgUser->setOption( "language", $this->mLanguage );
# Set search namespace options foreach( $this->mSearchNs as $i => $value ) { @@ -201,6 +203,7 @@ class PreferencesForm { $this->mSearchLines = $wgUser->getOption( "contextlines" ); $this->mSearchChars = $wgUser->getOption( "contextchars" ); $this->mRecent = $wgUser->getOption( "rclimit" ); + $this->mLanguage = $wgUser->getOption( "language" );
$togs = $wgLang->getUserToggles(); foreach ( $togs as $tname => $ttext ) { @@ -264,7 +267,7 @@ class PreferencesForm {
/* private */ function mainPrefsForm( $err ) { - global $wgUser, $wgOut, $wgLang, $wgUseDynamicDates, $wgValidSkinNames; + global $wgUser, $wgOut, $wgLang, $wgUseDynamicDates, $wgValidSkinNames,$wgLanguageArray;
$wgOut->setPageTitle( wfMsg( "preferences" ) ); $wgOut->setArticleRelated( false ); @@ -320,6 +323,20 @@ class PreferencesForm { $wgOut->addHTML( "<form id="preferences" name="preferences" action="$action" method="post">" );
+ # Zeroth section: language + # + if($wgLanguageArray) { + $wgOut->addHTML( "<fieldset> + <legend>Language</legend> + <div><select name="wpLanguage">" ); + foreach( $wgLanguageArray as $v) + $wgOut->addHTML( "<option value="$v" ". + (($v==$this->mLanguage)?"selected":""). + ">".$wgLang->getLanguageName( $v ). + "</option>" ); + $wgOut->addHTML( "</select></div></fieldset>" ); + } + # First section: identity # Email, etc. # Index: includes/User.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/User.php,v retrieving revision 1.52 diff -u -3 -p -r1.52 User.php --- includes/User.php 22 May 2004 04:53:02 -0000 1.52 +++ includes/User.php 22 May 2004 12:25:13 -0000 @@ -82,7 +82,7 @@ class User {
function loadDefaults() { - global $wgLang, $wgIP; + global $wgLang, $wgIP, $wgLanguageArray; global $wgNamespacesToBeSearchedDefault;
$this->mId = $this->mNewtalk = 0; @@ -90,10 +90,17 @@ class User { $this->mEmail = ""; $this->mPassword = $this->mNewpassword = ""; $this->mRights = array(); - $defOpt = $wgLang->getDefaultUserOptions() ; - foreach ( $defOpt as $oname => $val ) { - $this->mOptions[$oname] = $val; - } + $this->setDefaultOptions(array( + "quickbar" => 1, "underline" => 1, "hover" => 1, + "cols" => 80, "rows" => 25, "searchlimit" => 20, + "contextlines" => 5, "contextchars" => 50, + "skin" => 0, "math" => 1, "rcdays" => 7, "rclimit" => 50, + "highlightbroken" => 1, "stubthreshold" => 0, + "previewontop" => 1, + "editsection"=>1,"editsectiononrightclick"=>0, "showtoc"=>1, + "showtoolbar" =>1, + "date" => 0, "language" => "en" + )); foreach ($wgNamespacesToBeSearchedDefault as $nsnum => $val) { $this->mOptions["searchNs".$nsnum] = $val; } @@ -279,6 +286,13 @@ class User { $this->mDataLoaded = true; }
+ function setDefaultOptions($defOpt) + { + foreach ( $defOpt as $oname => $val ) { + $this->mOptions[$oname] = $val; + } + } + function getID() { return $this->mId; } function setID( $v ) { $this->mId = $v;
wikitech-l@lists.wikimedia.org