r101361 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r101360‎ | r101361 | r101362 >
Date:15:02, 31 October 2011
Author:nikerabbit
Status:ok
Tags:
Comment:
Much improved Special:FirstSteps. Before you had to go back and worth for everything, now you can stay on the page and use simple forms.
Modified paths:
  • /trunk/extensions/Translate/FirstSteps.i18n.php (modified) (history)
  • /trunk/extensions/Translate/specials/SpecialFirstSteps.php (modified) (history)

Diff [purge]

Index: trunk/extensions/Translate/specials/SpecialFirstSteps.php
@@ -52,6 +52,11 @@
5353 $step = $this->showTarget( $step );
5454 $step = $this->showEmail( $step );
5555
 56+ if ( $step === 'translate-fs-target-title' ) {
 57+ global $wgLang;
 58+ $this->out->redirect( SpecialPage::getTitleFor( 'LanguageStats', $wgLang->getCode() )->getLocalUrl() );
 59+ }
 60+
5661 $this->out->setPageTitle( htmlspecialchars( wfMsg( 'translate-fs-pagetitle', wfMsg( $step ) ) ) );
5762 }
5863
@@ -65,34 +70,20 @@
6671 return $step;
6772 }
6873
69 - if ( $this->user->isLoggedIn() ) {
 74+ if ( $this->user->isLoggedIn() ) {
7075 $header->content( $header->content . wfMsg( 'translate-fs-pagetitle-done' ) );
7176 $this->out->addHtml( $header );
7277 return $step;
 78+ } else {
 79+ // Go straight to create account (or login) page
 80+ $create = SpecialPage::getTitleFor( 'Userlogin' );
 81+ $returnto = $this->getTitle()->getPrefixedText();
 82+ $this->out->redirect( $create->getLocalUrl( array( 'returnto' => $returnto , 'type' => 'signup' ) ) );
7383 }
74 -
75 - $this->out->addHtml( $header->style( 'opacity', false ) );
76 -
77 - $login_page = SpecialPage::getTitleFor( 'Userlogin' );
78 - $query = array( 'returnto' => $this->getTitle() );
79 -
80 - $li_href = $login_page->getFullUrl( $query );
81 - $tag = new HtmlTag( 'span', "[$li_href |||]" );
82 - $tag->param( 'class', 'plainlinks' );
83 - list( $li_before, $li_after ) = explode( '|||', $tag, 2 );
84 -
85 - $su_href = $login_page->getFullUrl( $query + array( 'type' => 'signup' ) );
86 - $tag->content( "[$su_href |||]" );
87 - $tag->id( 'translate-fs-signup' );
88 - list( $su_before, $su_after ) = explode( '|||', $tag, 2 );
89 -
90 - $this->out->addWikiMsg( 'translate-fs-signup-text', $li_before, $li_after, $su_before, $su_after );
91 -
92 - return $step_message;
9384 }
9485
9586 protected function showSettings( $step ) {
96 - global $wgRequest;
 87+ global $wgRequest, $wgLang;
9788
9889 $header = new HtmlTag( 'h2' );
9990 $step_message = 'translate-fs-settings-title';
@@ -103,26 +94,112 @@
10495 return $step;
10596 }
10697
107 - if ( $this->user->getOption( 'language' ) !== 'en' || $wgRequest->getText( 'step' ) === 'settings' ) {
 98+ if ( $wgRequest->wasPosted() &&
 99+ $this->user->matchEditToken( $wgRequest->getVal( 'token' ) ) &&
 100+ $wgRequest->getText( 'step' ) === 'settings' )
 101+ {
 102+ $this->user->setOption( 'language', $wgRequest->getVal( 'primary-language' ) );
 103+ $this->user->setOption( 'translate-firststeps', '1' );
 104+
 105+ $assistant = array();
 106+ for ( $i = 0; $i < 10; $i++ ) {
 107+ $language = $wgRequest->getText( "assistant-language-$i", '-' );
 108+ if ( $language === '-' ) continue;
 109+ $assistant[] = $language;
 110+ }
 111+
 112+ if ( count( $assistant ) ) {
 113+ $this->user->setOption( 'translate-editlangs', implode( ',', $assistant ) );
 114+ }
 115+ $this->user->saveSettings();
 116+ // Reload the page if language changed, just in case and this is the easieast way
 117+ $this->out->redirect( $this->getTitle()->getLocalUrl() );
 118+ }
 119+
 120+ if ( $this->user->getOption( 'translate-firststeps' ) === '1' ) {
108121 $header->content( $header->content . wfMsg( 'translate-fs-pagetitle-done' ) );
109122 $this->out->addHtml( $header );
110123 return $step;
111124 }
112125
113126 $this->out->addHtml( $header->style( 'opacity', false ) );
114 - $this->out->addWikiMsg( 'translate-fs-settings-text' );
115127
116 - $form = new HtmlTag( 'form' );
117 - $items = new TagContainer();
118 - $form->param( 'method', 'post' )->content( $items );
119 - $items[] = new RawHtml( Html::hidden( 'step', 'settings' ) );
120 - $items[] = new RawHtml( Xml::submitButton( wfMsg( 'translate-fs-settings-skip' ) ) );
 128+ $code = $wgLang->getCode();
121129
122 - $this->out->addHtml( $form );
 130+ $languages = $this->languages( $code );
 131+ $selector = new XmlSelect();
 132+ $selector->addOptions( $languages );
 133+ $selector->setDefault( $code );
123134
 135+ $output = Html::openElement( 'form', array( 'method' => 'post' ) );
 136+ $output .= Html::hidden( 'step', 'settings' );
 137+ $output .= Html::hidden( 'token', $this->user->editToken() );
 138+ $output .= Html::hidden( 'title', $this->getTitle() );
 139+ $output .= Html::openElement( 'table' );
 140+
 141+ $name = $id = 'primary-language';
 142+ $selector->setAttribute( 'id', $id );
 143+ $selector->setAttribute( 'name', $name );
 144+ $text = wfMessage( 'translate-fs-settings-planguage' )->text();
 145+ $row = self::wrap( 'td', Xml::label( $text, $id ) );
 146+ $row .= self::wrap( 'td', $selector->getHtml() );
 147+ $output .= self::wrap( 'tr', $row );
 148+
 149+ $row = Html::rawElement( 'td', array( 'colspan' => 2 ), wfMessage( 'translate-fs-settings-planguage-desc' )->parse() );
 150+ $output .= self::wrap( 'tr', $row );
 151+
 152+ $helpers = $this->getHelpers( $this->user, $code );
 153+
 154+ $selector = new XmlSelect();
 155+ $selector->addOption( wfMessage( 'translate-fs-selectlanguage' )->text(), '-' );
 156+ $selector->addOptions( $languages );
 157+
 158+ $num = max( 2, count( $helpers ) );
 159+ for( $i = 0; $i < $num; $i++ ) {
 160+ $id = $name = "assistant-language-$i";
 161+ $text = wfMessage( 'translate-fs-settings-slanguage' )->numParams( $i + 1 )->text();
 162+ $selector->setDefault( isset( $helpers[$i] ) ? $helpers[$i] : false );
 163+ $selector->setAttribute( 'id', $id );
 164+ $selector->setAttribute( 'name', $name );
 165+
 166+ $row = self::wrap( 'td', Xml::label( $text, $id ) );
 167+ $row .= self::wrap( 'td', $selector->getHtml() );
 168+ $output .= self::wrap( 'tr', $row );
 169+ }
 170+
 171+ $output .= Html::openElement( 'tr' );
 172+ $output .= Html::rawElement( 'td', array( 'colspan' => 2 ), wfMessage( 'translate-fs-settings-slanguage-desc' )->parse() );
 173+ $output .= Html::closeElement( 'tr' );
 174+ $output .= Html::openElement( 'tr' );
 175+ $output .= Html::rawElement( 'td', array( 'colspan' => 2 ), Xml::submitButton( wfMsg( 'translate-fs-settings-submit' ) ) );
 176+ $output .= Html::closeElement( 'tr' );
 177+ $output .= Html::closeElement( 'table' );
 178+ $output .= Html::closeElement( 'form' );
 179+
 180+ $this->out->addHtml( $output );
 181+
124182 return $step_message;
125183 }
126184
 185+ protected static function wrap( /*string*/ $tag, /*string*/ $content ) {
 186+ return Html::rawElement( $tag, array(), $content );
 187+ }
 188+
 189+ protected function getHelpers( User $user, /*string*/ $code ) {
 190+ global $wgTranslateLanguageFallbacks;
 191+ $helpers = $user->getOption( 'translate-editlangs' );
 192+ if ( $helpers === 'default' ) {
 193+ if ( isset( $wgTranslateLanguageFallbacks[$code] ) ) {
 194+ $helpers = $wgTranslateLanguageFallbacks[$code];
 195+ } else {
 196+ $helpers = array();
 197+ }
 198+ } else {
 199+ $helpers = array_map( 'trim', explode( ',', $helpers ) );
 200+ }
 201+ return $helpers;
 202+ }
 203+
127204 protected function showUserpage( $step ) {
128205 global $wgRequest;
129206
@@ -138,15 +215,33 @@
139216 }
140217
141218 $userpage = $this->user->getUserPage();
142 - $preload = "{{#babel:en-2}}\nI am My Name and....";
 219+ $preload = "I am My Name and....";
143220
144221 if ( $wgRequest->wasPosted() &&
145222 $this->user->matchEditToken( $wgRequest->getVal( 'token' ) ) &&
146223 $wgRequest->getText( 'step' ) === 'userpage' )
147224 {
148 - $article = new Article( $userpage );
149 - $status = $article->doEdit( $wgRequest->getText( $textareaId ), $this->getTitle() );
 225+ $babel = array();
 226+ for ( $i = 0; $i < 5; $i++ ) {
 227+ $language = $wgRequest->getText( "babel-$i-language", '-' );
 228+ if ( $language === '-' ) continue;
 229+ $level = $wgRequest->getText( "babel-$i-level", '-' );
 230+ $babel[$language] = $level;
 231+ }
150232
 233+ arsort( $babel );
 234+ $babeltext = '{{#babel:';
 235+ foreach ( $babel as $language => $level ) {
 236+ if ( $level === 'N' ) $level = '';
 237+ else $level = "-$level";
 238+ $babeltext .= "$language$level|";
 239+ }
 240+ $babeltext = trim( $babeltext, '|' );
 241+ $babeltext .= "}}\n";
 242+
 243+ $article = new Article( $userpage, 0 );
 244+ $status = $article->doEdit( $babeltext . $wgRequest->getText( $textareaId ), $this->getTitle() );
 245+
151246 if ( $status->isOK() ) {
152247 $header->content( $header->content . wfMsg( 'translate-fs-pagetitle-done' ) );
153248 $this->out->addHtml( $header );
@@ -174,11 +269,8 @@
175270
176271 $this->out->addHtml( $header->style( 'opacity', false ) );
177272
178 - $this->out->addWikiMsg( 'translate-fs-userpage-text' );
 273+ $this->out->addWikiMsg( 'translate-fs-userpage-help' );
179274 global $wgLang;
180 - $this->out->addHtml(
181 - TranslateUtils::languageSelector( $wgLang->getCode(), $wgLang->getCode() )
182 - );
183275
184276 $form = new HtmlTag( 'form' );
185277 $items = new TagContainer();
@@ -187,6 +279,37 @@
188280 $items[] = new RawHtml( Html::hidden( 'step', 'userpage' ) );
189281 $items[] = new RawHtml( Html::hidden( 'token', $this->user->editToken() ) );
190282 $items[] = new RawHtml( Html::hidden( 'title', $this->getTitle() ) );
 283+
 284+ $languages = $this->languages( $wgLang->getCode() );
 285+ $selector = new XmlSelect();
 286+ $selector->addOption( wfMessage( 'translate-fs-selectlanguage' )->text(), '-' );
 287+ $selector->addOptions( $languages );
 288+
 289+ // Building a skill selector
 290+ $skill = new XmlSelect();
 291+ $levels = 'N,5,4,3,2,1';
 292+ foreach ( explode( ',', $levels ) as $level ) {
 293+ $skill->addOption( wfMessage( "translate-fs-userpage-level-$level" )->text(), $level );
 294+ }
 295+ for ( $i = 0; $i < 5; $i++ ) {
 296+ // Prefill en-2 and [wgLang]-N if [wgLang] != en
 297+ if ( $i === 0 ) {
 298+ $skill->setDefault( '2' );
 299+ $selector->setDefault( 'en' );
 300+ } elseif( $i === 1 && $wgLang->getCode() !== 'en' ) {
 301+ $skill->setDefault( 'N' );
 302+ $selector->setDefault( $wgLang->getCode() );
 303+ } else {
 304+ $skill->setDefault( false );
 305+ $selector->setDefault( false );
 306+ }
 307+
 308+ // [skill level selector][language selector]
 309+ $skill->setAttribute( 'name', "babel-$i-level" );
 310+ $selector->setAttribute( 'name', "babel-$i-language" );
 311+ $items[] = New RawHtml( $skill->getHtml() . $selector->getHtml() . '<br />' );
 312+ }
 313+
191314 $textarea = new HtmlTag( 'textarea', $preload );
192315 $items[] = $textarea->param( 'rows' , 5 )->id( $textareaId )->param( 'name', $textareaId );
193316 $items[] = new RawHtml( Xml::submitButton( wfMsg( 'translate-fs-userpage-submit' ) ) );
@@ -197,6 +320,7 @@
198321 }
199322
200323 protected function showPermissions( $step ) {
 324+ global $wgLang, $wgRequest;
201325 $header = new HtmlTag( 'h2' );
202326 $step_message = 'translate-fs-permissions-title';
203327 $header->content( wfMsg( $step_message ) )->style( 'opacity', 0.4 );
@@ -206,15 +330,68 @@
207331 return $step;
208332 }
209333
 334+ if ( $wgRequest->wasPosted() &&
 335+ $this->user->matchEditToken( $wgRequest->getVal( 'token' ) ) &&
 336+ $wgRequest->getText( 'step' ) === 'permissions' )
 337+ {
 338+ // This is ridiculous
 339+ global $wgCaptchaTriggers;
 340+ $captcha = $wgCaptchaTriggers;
 341+ $wgCaptchaTriggers = null;
 342+
 343+ $language = $wgRequest->getVal( 'primary-language' );
 344+ $message = $wgRequest->getText( 'message' );
 345+ $params = array(
 346+ 'action' => 'threadaction',
 347+ 'threadaction' => 'newthread',
 348+ 'token' => $this->user->editToken(),
 349+ 'talkpage' => 'Project:Translator',
 350+ 'subject' => "{{LanguageHeader|$language}}",
 351+ 'reason' => 'Using Special:FirstSteps',
 352+ 'text' => $message,
 353+ );
 354+ $request = new FauxRequest( $params, true, $_SESSION );
 355+ $api = new ApiMain( $request, true );
 356+ $api->execute();
 357+ $result = $api->getResultData();
 358+ $wgCaptchaTriggers = $captcha;
 359+ $page = $result['threadaction']['thread']['thread-title'];
 360+ $this->user->setOption( 'translate-firststeps-request', $page );
 361+ $this->user->saveSettings();
 362+ }
 363+
 364+ $page = $this->user->getOption( 'translate-firststeps-request' );
210365 if ( $this->user->isAllowed( 'translate' ) ) {
211366 $header->content( $header->content . wfMsg( 'translate-fs-pagetitle-done' ) );
212367 $this->out->addHtml( $header );
213368 return $step;
 369+ } elseif( $page ) {
 370+ $header->content( $header->content . wfMsg( 'translate-fs-pagetitle-pending' ) );
 371+ $this->out->addHtml( $header->style( 'opacity', false ) );
 372+ $this->out->addWikiMsg( 'translate-fs-permissions-pending', $page );
 373+ return $step_message;
214374 }
215375
216376 $this->out->addHtml( $header->style( 'opacity', false ) );
217 - $this->out->addWikiMsg( 'translate-fs-permissions-text' );
 377+ $this->out->addWikiMsg( 'translate-fs-permissions-help' );
218378
 379+ $output = Html::openElement( 'form', array( 'method' => 'post' ) );
 380+ $output .= Html::hidden( 'step', 'permissions' );
 381+ $output .= Html::hidden( 'token', $this->user->editToken() );
 382+ $output .= Html::hidden( 'title', $this->getTitle() );
 383+ $name = $id = 'primary-language';
 384+ $selector = new XmlSelect();
 385+ $selector->addOptions( $this->languages( $wgLang->getCode() ) );
 386+ $selector->setAttribute( 'id', $id );
 387+ $selector->setAttribute( 'name', $name );
 388+ $selector->setDefault( $wgLang->getCode() );
 389+ $text = wfMessage( 'translate-fs-permissions-planguage' )->text();
 390+ $output .= Xml::label( $text, $id ) . "&#160;" . $selector->getHtml() . '<br />';
 391+ $output .= Html::element( 'textarea', array( 'rows' => 5, 'name' => 'message' ), '' );
 392+ $output .= Xml::submitButton( wfMsg( 'translate-fs-permissions-submit' ) );
 393+ $output .= Html::closeElement( 'form' );
 394+
 395+ $this->out->addHtml( $output );
219396 return $step_message;
220397 }
221398
@@ -242,7 +419,7 @@
243420 $step_message = 'translate-fs-email-title';
244421 $header->style( 'opacity', 0.4 )->content( wfMsg( $step_message ) );
245422
246 - if ( $step && $step !== 'translate-fs-target-title' ) {
 423+ if ( $step && ( $step !== 'translate-fs-target-title' && $step !== 'translate-fs-permissions-title' ) ) {
247424 $this->out->addHtml( $header );
248425 return $step;
249426 }
@@ -250,7 +427,6 @@
251428 if ( $this->user->isEmailConfirmed() ) {
252429 $header->content( $header->content . wfMsg( 'translate-fs-pagetitle-done' ) );
253430 $this->out->addHtml( $header );
254 -
255431 return $step; // Start translating step
256432 }
257433
@@ -259,4 +435,23 @@
260436
261437 return $step_message;
262438 }
 439+
 440+ protected function languages( $language ) {
 441+ if ( is_callable( array( 'LanguageNames', 'getNames' ) ) ) {
 442+ $languages = LanguageNames::getNames( $language,
 443+ LanguageNames::FALLBACK_NORMAL,
 444+ LanguageNames::LIST_MW
 445+ );
 446+ } else {
 447+ $languages = Language::getLanguageNames( false );
 448+ }
 449+
 450+ ksort( $languages );
 451+
 452+ $options = array();
 453+ foreach ( $languages as $code => $name ) {
 454+ $options["$code - $name"] = $code;
 455+ }
 456+ return $options;
 457+ }
263458 }
Index: trunk/extensions/Translate/FirstSteps.i18n.php
@@ -19,6 +19,7 @@
2020 'firststeps' => 'First steps',
2121 'firststeps-desc' => '[[Special:FirstSteps|Special page]] for getting users started on a wiki using the Translate extension',
2222 'translate-fs-pagetitle-done' => ' - done!',
 23+ 'translate-fs-pagetitle-pending' => ' - pending',
2324 'translate-fs-pagetitle' => 'Getting started wizard - $1',
2425 'translate-fs-signup-title' => 'Sign up',
2526 'translate-fs-settings-title' => 'Configure your preferences',
@@ -31,64 +32,31 @@
3233 You will be guided through the process of becoming a translator step by step.
3334 In the end you will be able to translate ''interface messages'' of all supported projects at {{SITENAME}}.",
3435
35 - 'translate-fs-signup-text' => '[[Image:HowToStart1CreateAccount.png|frame]]
36 -
37 -In the first step you must sign up.
38 -
39 -Credit for your translations is attributed to your user name.
40 -The image on the right shows how to fill the fields.
41 -
42 -If you have already signed up, $1log in$2 instead.
43 -Once you are signed up, please return to this page.
44 -
45 -$3Sign up$4',
46 - 'translate-fs-settings-text' => 'You should now go to your preferences and
47 -at least change your interface language to the language you are going to translate to.
48 -
49 -Your interface language is used as the default target language.
50 -It is easy to forget to change the language to the correct one, so setting it now is highly recommended.
51 -
52 -While you are there, you can also request the software to display translations in other languages you know.
53 -This setting can be found under tab "{{int:prefs-editing}}".
54 -Feel free to explore other settings, too.
55 -
56 -Go to your [[Special:Preferences|preferences page]] now and then return to this page.',
57 - 'translate-fs-settings-skip' => "I'm done.
58 -Let me proceed.",
59 - 'translate-fs-userpage-text' => 'Now you need to create an user page.
60 -
61 -Please write something about yourself; who you are and what you do.
62 -This will help the {{SITENAME}} community to work together.
63 -At {{SITENAME}} there are people from all around the world working on different languages and projects.
64 -
65 -In the prefilled box above in the very first line you see <nowiki>{{#babel:en-2}}</nowiki>.
66 -Please complete it with your language knowledge.
67 -The number after the language code describes how well you know the language.
68 -The alternatives are:
69 -* 1 - a little
70 -* 2 - basic knowledge
71 -* 3 - good knowledge
72 -* 4 - native speaker level
73 -* 5 - you use the language professionally, for example you are a professional translator.
74 -
75 -If you are a native speaker of a language, leave the skill level out, and only use the language code.
76 -Example: if you speak Tamil natively, English well, and little Swahili, you would write:
77 -<code><nowiki>{{#babel:ta|en-3|sw-1}}</nowiki></code>
78 -
79 -If you do not know the language code of a language, now is a good time to look it up.
80 -You can use the list below.',
 36+ 'translate-fs-selectlanguage' => "Pick a language",
 37+ 'translate-fs-settings-planguage' => "Primary language:",
 38+ 'translate-fs-settings-planguage-desc' => "The primary language doubles as your interface language on this wiki
 39+and as default target langauge for translations.",
 40+ 'translate-fs-settings-slanguage' => "Assistant language $1:",
 41+ 'translate-fs-settings-slanguage-desc' => "It is possible to show translations of messages in other languages in the translation editor.
 42+Here you can choose which languages, if any, you would like to see.",
 43+ 'translate-fs-settings-submit' => "Save preferences",
 44+ 'translate-fs-userpage-level-N' => 'I am a native speaker of',
 45+ 'translate-fs-userpage-level-5' => 'I am a professional translator of',
 46+ 'translate-fs-userpage-level-4' => 'I know it like a native speaker',
 47+ 'translate-fs-userpage-level-3' => 'I have a good command of',
 48+ 'translate-fs-userpage-level-2' => 'I have a moderate command of',
 49+ 'translate-fs-userpage-level-1' => 'I know a little',
 50+ 'translate-fs-userpage-help' => 'Please indicate your language skills and tell us something about yourself. If you know more than five languages you can add more later. ',
8151 'translate-fs-userpage-submit' => 'Create my userpage',
8252 'translate-fs-userpage-done' => 'Well done! You now have an user page.',
83 - 'translate-fs-permissions-text' => 'Now you need to place a request to be added to the translator group.
 53+ 'translate-fs-permissions-planguage' => "Primary language:",
 54+ 'translate-fs-permissions-help' => 'Now you need to place a request to be added to the translator group.
 55+Select the primary langauge you are going to translate to.
8456
85 -Until we fix the code, please go to [[Project:Translator]] and follow the instructions.
86 -Then come back to this page.
87 -
88 -After you have submitted your request, one of the volunteer staff members will check your request and approve it as soon as possible.
89 -Please be patient.
90 -
91 -<del>Check that the following request is correctly filled and then press the request button.</del>',
92 -
 57+You can mention other languages and other remarks in textbox below.',
 58+ 'translate-fs-permissions-pending' => 'Your request has been submitted to [[$1]] and someone from the site staff will check it as soon as possible.
 59+If you confirm your e-mail address, you will get an e-mail notification as soon as it happens.',
 60+ 'translate-fs-permissions-submit' => 'Send request',
9361 'translate-fs-target-text' => 'Congratulations!
9462 You can now start translating.
9563
@@ -121,6 +89,18 @@
12290 'translate-fs-signup-text' => 'The parameters represent the start and end of an HTML link.',
12391 'translate-fs-userpage-text' => 'You may replace "Tamil" (ta) and "Swahili" (sw) with languages that people from your language are more likely to speak.',
12492 'translate-fs-permissions-text' => 'Synonym for "filed" is "submitted".',
 93+ 'translate-fs-selectlanguage' => "Default value in language selector, acts as 'nothing chosen'",
 94+ 'translate-fs-settings-planguage' => "Label for choosing interface language, followed by language selector",
 95+ 'translate-fs-settings-planguage-desc' => "Help message for choosing interface language",
 96+ 'translate-fs-settings-slanguage' => "Other languages shown while translating, followed by language selector, $1 is running number",
 97+ 'translate-fs-settings-slanguage-desc' => "Help message for choosing assistant languages",
 98+ 'translate-fs-settings-submit' => "Submit button",
 99+ 'translate-fs-userpage-level-N' => 'Language skill level option, followed by language selector',
 100+ 'translate-fs-userpage-level-5' => 'Language skill level option, followed by language selector',
 101+ 'translate-fs-userpage-level-4' => 'Language skill level option, followed by language selector',
 102+ 'translate-fs-userpage-level-3' => 'Language skill level option, followed by language selector',
 103+ 'translate-fs-userpage-level-2' => 'Language skill level option, followed by language selector',
 104+ 'translate-fs-userpage-level-1' => 'Language skill level option, followed by language selector',
125105 );
126106
127107 /** Arabic (العربية)

Follow-up revisions

RevisionCommit summaryAuthorDate
r101400fix typos of r101361robin20:12, 31 October 2011

Status & tagging log