Localisation/mk: Difference between revisions
Appearance
Content deleted Content added
Updating to match new version of source page |
Updating to match new version of source page |
||
| (22 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
<languages/> |
<languages/> |
||
{{Shortcut|I18N|I18n|L10n}} |
|||
{{i18n navigation}} |
{{i18n navigation}} |
||
{{Shortcut|I18N|I18n|L10n}} |
|||
:''<span lang="en" dir="ltr" class="mw-content-ltr">For the Wikimedia Foundation localisation team, see {{ll|Wikimedia Language engineering}}.</span>'' |
|||
:''<span lang="en" dir="ltr" class="mw-content-ltr">For translating pages on this wiki, see {{ll|Project:Language policy}}.</span>'' |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This page gives a technical description of MediaWiki's '''[[w:internationalization and localization|internationalisation and localisation]]''' ('''i18n''' and '''L10n''') system, and gives hints that coders should be aware of.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Our mantra is that ''i18n must not be an afterthought'': it's an essential component since the earliest phases of your software, as well as one of the core {{ll|principles}} of MediaWiki.</span> |
|||
{{Tocright}} |
{{Tocright}} |
||
<span lang="en" dir="ltr" class="mw-content-ltr">This landing page links to core technical documentation about MediaWiki [[w:internationalization and localization|internationalisation and localisation]] ('''i18n''' and '''L10n''').</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">A core principle of MediaWiki is that ''i18n must not be an afterthought'': i18n and l10n are an essential component even in the earliest phases of software development.</span> |
|||
{{anchor|Translation resources}} |
{{anchor|Translation resources}} |
||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
<div lang="en" dir="ltr" class="mw-content-ltr"> |
||
== For translators and users == |
|||
==Translation resources== |
|||
</div> |
</div> |
||
* {{ll|Translator hub}} |
|||
===translatewiki.net=== |
|||
<span lang="en" dir="ltr" class="mw-content-ltr"> |
* <span lang="en" dir="ltr" class="mw-content-ltr">For translating pages on this wiki, see {{ll|Project:Language policy}}.</span> |
||
* [[translatewiki:Special:MyLanguage/Translating:MediaWiki|<span lang="en" dir="ltr" class="mw-content-ltr">How to translate MediaWiki interface messages</span>]] |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If you would like to have nothing to do with all the technicalities in this page about editing files, Git, creating patches, and so forth, go directly to [[translatewiki:|translatewiki.net]].</span> |
|||
* {{ll|Manual:Language#lang-code|2=<span lang="en" dir="ltr" class="mw-content-ltr">Language names reference</span>}} |
|||
<span lang="en" dir="ltr" class="mw-content-ltr"> |
* {{ll|Help:Extension:UniversalLanguageSelector/Input_methods|2=<span lang="en" dir="ltr" class="mw-content-ltr">How to input text in different scripts</span>}} <span lang="en" dir="ltr" class="mw-content-ltr">(IMEs)</span> |
||
<span lang="en" dir="ltr" class="mw-content-ltr"> |
* {{ll|Universal Language Selector/WebFonts|2=<span lang="en" dir="ltr" class="mw-content-ltr">How to download and enable different webfonts</span>}} |
||
* {{ll|Universal Language Selector/FAQ|2=<span lang="en" dir="ltr" class="mw-content-ltr">Universal Language Selector FAQ</span>}} |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Core MediaWiki and extensions must use system messages for any text displayed in the user interface.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">For an example of how to do this, please see {{ll|Manual:Special pages#The Messages/Internationalization File|Manual:Special pages}}.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If the extension is well written, it will probably be included in {{ll|translatewiki.net|translatewiki.net}} in a few days, after its staff notices it on {{ll|gerrit|gerrit}}.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If it's not noticed, [[translatewiki:Project:About#Contact_us|contact them]].</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If it's too unstable to be translated, note so in the code or commit and contact them if necessary.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
<div lang="en" dir="ltr" class="mw-content-ltr"> |
||
== For developers == |
|||
See also [[#Overview of the localisation system|Overview of the localisation system]] and [[#what-can-be-localized|What can be localised]]. |
|||
</div> |
</div> |
||
{{ContentGrid |
|||
|content= |
|||
{{Colored box |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
|title = <span lang="en" dir="ltr" class="mw-content-ltr">Write code that can be localised</span> |
|||
===Finding messages=== |
|||
|content = |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr"> |
* {{ll|Manual:Language|2=<span lang="en" dir="ltr" class="mw-content-ltr">Overview of language in MediaWiki</span>}} |
||
<span lang="en" dir="ltr" class="mw-content-ltr"> |
* <span lang="en" dir="ltr" class="mw-content-ltr">i18n features:</span> |
||
** {{ll|Manual:Language#Namespaces|2=<span lang="en" dir="ltr" class="mw-content-ltr">Namespaces</span>}} |
|||
** {{ll|Manual:Language#Regional|2=<span lang="en" dir="ltr" class="mw-content-ltr">Time and date formats</span>}} |
|||
** {{ll|Manual:Language#Fallback_languages|2=<span lang="en" dir="ltr" class="mw-content-ltr">Fallbacks</span>}} |
|||
** {{ll|Directionality support}} |
|||
* {{ll|Help:System message|2=<span lang="en" dir="ltr" class="mw-content-ltr">How to write system messages</span>}} |
|||
* {{ll|Manual:Messages API|2=<span lang="en" dir="ltr" class="mw-content-ltr">How to write good i18n code</span>}} |
|||
* {{ll|Manual:Adding and removing languages|nsp=0}} |
|||
}} |
|||
{{Colored box |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
|title = <span lang="en" dir="ltr" class="mw-content-ltr">Get your code translated</span> |
|||
===i18n mailing list=== |
|||
|content = |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr"> |
* {{ll|Translatewiki.net|2=<span lang="en" dir="ltr" class="mw-content-ltr">Use translatewiki.net</span>}} |
||
<span lang="en" dir="ltr" class="mw-content-ltr"> |
* {{ll|Manual:Language#What can be localised|2=<span lang="en" dir="ltr" class="mw-content-ltr">What can be localised</span> }} |
||
* {{ll|Help:System message#Finding messages and documentation|2=<span lang="en" dir="ltr" class="mw-content-ltr">How to find a MediaWiki string for translation</span>}} |
|||
* [[translatewiki:Special:MyLanguage/FAQ#MediaWiki translation|<span lang="en" dir="ltr" class="mw-content-ltr">translatewiki.net FAQ for MediaWiki</span>]] |
|||
* <span lang="en" dir="ltr" class="mw-content-ltr">To localise external tools, like those in Toolforge, use the [https://github.com/wikimedia/banana-i18n Banana library].</span> |
|||
* [[Manual:Developing_extensions#Localisation|Localise an extension]] |
|||
}} |
|||
{{Colored box |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
|title = <span lang="en" dir="ltr" class="mw-content-ltr">Implement a multilingual wiki</span> |
|||
==Code structure== |
|||
|content = |
|||
</div> |
|||
* {{ll|MediaWiki Language Extension Bundle}} |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">First, you have a Language object in {{ll|Manual:Code#Language.php|Language.php}}.</span> |
|||
* {{ll|Writing systems|2=<span lang="en" dir="ltr" class="mw-content-ltr">Writing systems support</span>}} |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This object contains all the localisable {{ll|Help:System message|message strings}}, as well as other important language-specific settings and custom behaviour (uppercasing, lowercasing, printing dates, formatting numbers, {{ll|Directionality support|direction}}, {{ll|GRAMMAR|custom grammar rules}} ''etc.'').</span> |
|||
* {{ll|Content translation|2=<span lang="en" dir="ltr" class="mw-content-ltr">Content translation (CX) extension</span>}} |
|||
< |
* {{ll|Help:System message|2=<span lang="en" dir="ltr" class="mw-content-ltr">Customise messages in your local wiki</span>}} |
||
* {{ll|Multilingual Semantic MediaWiki}} |
|||
The object is constructed from two sources: sub-classed versions of itself (classes) and Message files (messages). |
|||
}} |
|||
</div> |
|||
{{Colored box |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">There's also the MessageCache class, which handles input of text via the MediaWiki namespace.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr"> |
|title = <span lang="en" dir="ltr" class="mw-content-ltr">Add a wiki in a new language</span> |
||
|content = |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Legacy code might still be using the old <code>wfMsg*()</code> functions, which are now considered deprecated in favour of the above-mentioned Message objects.</span> |
|||
* [[m:Special:MyLanguage/Language_proposal_policy|<span lang="en" dir="ltr" class="mw-content-ltr">Language proposal policy</span>]] |
|||
* [[m:Requests_for_new_languages|<span lang="en" dir="ltr" class="mw-content-ltr">Requests for new languages</span>]] |
|||
* [[incubator:Special:MyLanguage/Help:Manual|<span lang="en" dir="ltr" class="mw-content-ltr">Wikimedia Incubator Help Manual</span>]] |
|||
}} |
|||
}} |
|||
{{anchor|General use (for developers)}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
<div lang="en" dir="ltr" class="mw-content-ltr"> |
||
== Help and contact info == |
|||
==General use (for developers)== |
|||
</div> |
</div> |
||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
<div lang="en" dir="ltr" class="mw-content-ltr"> |
||
* [[mail:mediawiki-i18n|mediawiki-i18n mailing list]] |
|||
See also {{ll|Manual:Messages API}}. |
|||
* [[translatewiki:Support|translatewiki.net Support page]] |
|||
</div> |
</div> |
||
* IRC: {{irc|translatewiki}} |
|||
* Telegram channel: [https://t.me/translatewiki translatewiki.net]. |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
<div lang="en" dir="ltr" class="mw-content-ltr"> |
||
* File a bug: |
|||
===Language objects=== |
|||
** [[phab:tag/i18n|MediaWiki bug reports for internationalisation]] |
|||
** [[Special:MyLanguage/How to report a bug|Tips for filing a bug]] |
|||
* [[Special:MyLanguage/Wikimedia Language engineering|Language Engineering team]] |
|||
</div> |
</div> |
||
<span lang="en" dir="ltr" class="mw-content-ltr">There are two ways to get a language object.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">You can use the globals {{ll|Manual:$wgLang|$wgLang}} and {{ll|Manual:$wgContLang|$wgContLang}} for user interface and content language respectively.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">For an arbitrary language you can construct an object by using {{phpi|Language::factory( 'en' )}}, by replacing <code>en</code> with the code of the language.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">You can also use <code>wfGetLangObj( $code );</code> if <code>$code</code> could already be a language object.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The list of codes is in <code>languages/Names.php</code>.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Language objects are needed for doing language-specific functions, most often to do number, time and date formatting, but also to construct lists and other things.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">There are multiple layers of caching and merging with {{ll|fallback languages}}, but the details are irrelevant in normal use.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Using messages=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">MediaWiki uses a ''central'' repository of messages which are referenced by keys in the code.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This is different from, for example, <code>Gettext</code>, which just extracts the translatable strings from the source files.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The key-based system makes some things easier, like refining the original texts and tracking changes to messages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The drawback is of course that the list of used messages and the list of source texts for those keys can get out of sync.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">In practice this isn't a big problem, and the only significant problem is that sometimes extra messages that are not used anymore still stay up for translation.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">To make message keys more manageable and easy to find, also with grep, always write them completely and don't rely too much on creating them dynamically.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">You may concatenate parts of message keys if you feel that it gives your code better structure, but put a comment nearby with a list of the possible resulting keys.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">For example:</span> |
|||
'''PHP''' |
|||
<syntaxhighlight lang="php"> |
|||
// Messages that can be used here: |
|||
// * myextension-connection-success |
|||
// * myextension-connection-warning |
|||
// * myextension-connection-error |
|||
$text = wfMessage( 'myextension-connection-' . $status )->parse(); |
|||
</syntaxhighlight> |
|||
'''JS''' |
|||
<syntaxhighlight lang="js"> |
|||
// Messages that can be used here: |
|||
// * myextension-connection-success |
|||
// * myextension-connection-warning |
|||
// * myextension-connection-error |
|||
var text = mw.msg( 'myextension-connection-' + status ); |
|||
</syntaxhighlight> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
To use a message in JavaScript, you have to [[Special:MyLanguage/Manual:Messages_API#Using_a_ResourceLoader_module|list it]] in the definition of your ResourceLoader module, in the <code>"messages"</code> property. |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The detailed use of message functions in PHP and JavaScript is on {{ll|Manual:Messages API}}.</span> |
|||
'''<span lang="en" dir="ltr" class="mw-content-ltr">This is an important documentation page, and you should read it before you write code that uses messages.</span>''' |
|||
{{anchor|Adding new messages}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Adding new messages=== |
|||
</div> |
|||
Поврзано: |
|||
{{ll|Localisation file format}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
==== Choosing the message key ==== |
|||
</div> |
|||
Поврзано: |
|||
{{ll|Manual:Coding conventions#System messages}} |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The message key must be globally unique.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This includes core MediaWiki and all the extensions and skins.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Stick to lower case letters, numbers and dashes in message names; most other characters are between less practical or not working at all.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Per MediaWiki convention, first character is case-insensitive and other chars are case-sensitive.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Please follow global or local conventions for naming.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">For extensions, use a standard prefix, preferably the extension name in lower case, followed by a hyphen ("-").</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Exceptions are:</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Messages used by the API. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">These must begin with <code>apihelp-</code>, <code>apiwarn-</code>, <code>apierror-</code>.</span> <span lang="en" dir="ltr" class="mw-content-ltr">After this prefix put the extension prefix.</span> (<span lang="en" dir="ltr" class="mw-content-ltr">Note that these messages should be in a separate file, usually under [https://phabricator.wikimedia.org/source/mediawiki/browse/master/includes/api/i18n/ includes/i18/api].</span>) |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Log-related messages. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">These must begin with <code>logentry-</code>, <code>log-name-</code>, <code>log-description</code>.</span> |
|||
* Кориснички права. <span lang="en" dir="ltr" class="mw-content-ltr">The key for the name of the right as displayed on Special:ListGroupRights must begin with <code>right-</code>.</span> <span lang="en" dir="ltr" class="mw-content-ltr">The name of the action that completes the sentence "{{int|Permissionserrorstext-withaction|unused}}" must begin with <code>action-</code></span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Revisions tags must begin with <code>tag-</code>. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Special page titles must begin with <code>special-</code>. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
==== Other things to note when creating messages ==== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# Make sure that you are using suitable handling for the message (parsing, <code><nowiki>{{</nowiki></code>-replacement, escaping for HTML, etc.) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# If your message is part of core, it should usually be added to <code>languages/i18n/en.json</code>, although some components, such as Installer, EXIF tags, and ApiHelp have their own message files. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# If your message is in an extension add it to the <code>i18n/en.json</code> file or the <code>en.json</code> file in the appropriate subdirectory. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">In particular, API messages that are only seen by developers and not by most end users are usually in a separate file, such as <code>i18n/api/en.json</code>.</span> <span lang="en" dir="ltr" class="mw-content-ltr">If an extensions has a lot of messages, you may create subdirectories under <code>i18n</code>.</span> <span lang="en" dir="ltr" class="mw-content-ltr">All the message directories, including the default <code>i18n/</code>, must be listed in the <code>MessagesDirs</code> section in <code>extension.json</code> or in the {{ll|Manual:$wgMessagesDirs|$wgMessagesDirs}} variable.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# Take a pause and consider the wording of the message. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">Is it as clear as possible?</span> <span lang="en" dir="ltr" class="mw-content-ltr">Can it be misunderstood? Ask for comments from other developers or localisers if possible.</span> <span lang="en" dir="ltr" class="mw-content-ltr">Follow the [[#Internationalisation hints|#internationalisation hints]].</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# Add documentation to <code>qqq.json</code> in the same directory. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">Read more about [[#Message documentation|message documentation]].</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
=== Messages that should not be translated === |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# '''Ignored''' messages are those which should exist only in the English messages file. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">They are messages that should not need translation, because they reference only other messages or language-neutral features, ''e.g.'' a message of "<code><nowiki>{{SITENAME}}</nowiki></code>".</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# '''Optional''' messages may be translated only if changed in the target language. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
To flag such messages: |
|||
</div> |
|||
* <span lang="en" dir="ltr" class="mw-content-ltr">(optionally) use the template in the <code>qqq</code> message documentation, that is respectively</span> |
|||
*# <code>{<nowiki/>{[[translatewiki:Template:Notranslate|notranslate]]}}</code> или |
|||
*# <code>{<nowiki/>{[[translatewiki:Template:Optional|optional]]}}</code>; |
|||
* <span lang="en" dir="ltr" class="mw-content-ltr">(required) tell the {{ll|Extension:Translate|nsp=0}} extension used on {{ll|translatewiki.net|translatewiki.net}} what to do with the messages by submitting a patch listing them as appropriate (see also {{ll|Help:Extension:Translate/Group configuration/MediaWiki|full configuration docs}}):</span> |
|||
** <span lang="en" dir="ltr" class="mw-content-ltr">for core, in {{git file|project=translatewiki|file=groups/MediaWiki/MediaWiki.yaml}} add the message keys</span> |
|||
**# <span lang="en" dir="ltr" class="mw-content-ltr">under <syntaxhighlight lang="yaml"> ignored:</syntaxhighlight> or</span> |
|||
**# <span lang="en" dir="ltr" class="mw-content-ltr">under <syntaxhighlight lang="yaml"> optional:</syntaxhighlight></span>; |
|||
** <span lang="en" dir="ltr" class="mw-content-ltr">for extensions, in {{git file|project=translatewiki|file=groups/MediaWiki/mediawiki-extensions.txt}} add a line under the extension's name like</span> |
|||
**# <code>ignored = ''msg-key-1'',''msg-key-2''</code> or |
|||
**# <code>optional = ''msg-key-1'',''msg-key-2''</code>. |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Removing existing messages=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Remove it from <code>en.json</code> and <code>qqq.json</code>.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Don't bother with other languages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Updates from {{ll|translatewiki.net|translatewiki.net}} will handle those automatically.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">In addition, check whether the message appears anywhere in translatewiki configuration, for example in the list of optional or most used messages (a simple git grep should be enough).</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Remove it from these lists if needed.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Changing existing messages=== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# Consider updating the message documentation (see [[#Adding new messages|#Adding new messages]]). |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# Change the message key if old translations are not suitable for the new meaning. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">This also includes changes in message handling (parsing, escaping, parameters, etc.).</span> <span lang="en" dir="ltr" class="mw-content-ltr">Improving the phrasing of a message without technical changes is usually not a reason for changing a key.</span> <span lang="en" dir="ltr" class="mw-content-ltr">At translatewiki.net, the translations will be marked as outdated so that they can be targeted by translators.</span> <span lang="en" dir="ltr" class="mw-content-ltr">Changing a message key does not require talking to the i18n team or filing a support request.</span> <span lang="en" dir="ltr" class="mw-content-ltr">However, if you have special circumstances or questions, ask in {{irc|translatewiki}} or in the [[translatewiki:Support|support page]] at {{ll|translatewiki.net|translatewiki.net}}.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# If the extension is supported by {{ll|translatewiki.net|translatewiki.net}}, please only change the English source message and/or key, and the accompanying entry in <code>qqq.json</code>. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">If needed, the translatewiki.net team will take care of updating the translations, marking them as outdated, cleaning up the file or renaming keys where possible.</span> <span lang="en" dir="ltr" class="mw-content-ltr">This also applies when you're only changing things like HTML tags which you could change in other languages without speaking those languages.</span> <span lang="en" dir="ltr" class="mw-content-ltr">Most of these actions will take place in [[translatewiki:|translatewiki.net]] and will reach Git with about one day of delay.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Localising namespaces and special page aliases=== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
{{ll|Manual:Namespace|Namespaces}} and special page names (''i.e.'' "RecentChanges" in "[[Special:RecentChanges]]") are also translatable. |
|||
</div> |
|||
{{anchor|Namespaces}} |
|||
====Именски простори==== |
|||
:<!-- See [https://translatewiki.net/wiki/Translating:MediaWiki#Translating namespace names how they're translated] and [[#Namespace name aliases]]. --> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Currently<ref>[[gerrit:211677|https://gerrit.wikimedia.org/r/211677]]</ref> making namespace name translations is disabled on translatewiki.net, so you need to do this yourself in Gerrit, or file a [[Phabricator:]] task asking for someone else to do it. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
To allow custom namespaces introduced by your extension to be translated, create a <code>''MyExtension''.namespaces.php</code> file that looks like this: |
|||
</div> |
|||
<syntaxhighlight lang="php"> |
|||
<?php |
|||
/** |
|||
* Translations of the namespaces introduced by MyExtension. |
|||
* |
|||
* @file |
|||
*/ |
|||
$namespaceNames = []; |
|||
// For wikis where the MyExtension extension is not installed. |
|||
if( !defined( 'NS_MYEXTENSION' ) ) { |
|||
define( 'NS_MYEXTENSION', 2510 ); |
|||
} |
|||
if( !defined( 'NS_MYEXTENSION_TALK' ) ) { |
|||
define( 'NS_MYEXTENSION_TALK', 2511 ); |
|||
} |
|||
/** English */ |
|||
$namespaceNames['en'] = [ |
|||
NS_MYEXTENSION => 'MyNamespace', |
|||
NS_MYEXTENSION_TALK => 'MyNamespace_talk', |
|||
]; |
|||
/** Finnish (Suomi) */ |
|||
$namespaceNames['fi'] = [ |
|||
NS_MYEXTENSION => 'Nimiavaruuteni', |
|||
NS_MYEXTENSION_TALK => 'Keskustelu_nimiavaruudestani', |
|||
]; |
|||
</syntaxhighlight> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Then load the namespace translation file in <code>MyExtension.php</code> via {{phpi|$wgExtensionMessagesFiles['MyExtensionNamespaces'] {{=}} dirname( __FILE__ ) . '/MyExtension.namespaces.php';}} |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Now, when a user installs MyExtension on their Finnish (fi) wiki, the custom namespace will be translated into Finnish magically, and the user doesn't need to do a thing! |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Also remember to register your extension's namespace(s) on the {{ll|extension default namespaces}} page. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
====Special page aliases==== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
See {{ll|Manual:Special_pages#The_aliases_file|the manual page for Special pages}} for up-to-date information. The following does not appear to be valid. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Create a new file for the special page aliases in this format: |
|||
</div> |
|||
<syntaxhighlight lang="php"> |
|||
<?php |
|||
/** |
|||
* Aliases for the MyExtension extension. |
|||
* |
|||
* @file |
|||
* @ingroup Extensions |
|||
*/ |
|||
$aliases = []; |
|||
/** English */ |
|||
$aliases['en'] = [ |
|||
'MyExtension' => [ 'MyExtension' ] |
|||
]; |
|||
/** Finnish (Suomi) */ |
|||
$aliases['fi'] = [ |
|||
'MyExtension' => [ 'Lisäosani' ] |
|||
]; |
|||
</syntaxhighlight> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Then load it in the extension's setup file like this:</span> |
|||
{{phpi|$wgExtensionMessagesFiles['MyExtensionAlias'] {{=}} dirname( __FILE__ ) . '/MyExtension.alias.php';}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
When your special page code uses either {{phpi|SpecialPage::getTitleFor( 'MyExtension' )}} or {{phpi|$this->getTitle()}} (in the class that provides Special:MyExtension), the localised alias will be used, if it's available. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
==Message parameters== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Some messages take parameters.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">They are represented by <code>$1</code>, <code>$2</code>, <code>$3</code>, … in the (static) message texts, and replaced at run time.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Typical parameter values are numbers (the "3" in "Delete 3 versions?"), or user names (the "Bob" in "Page last edited by Bob"), page names, links and so on, or sometimes other messages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">They can be of arbitrary complexity.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The list of parameters defined for each specific message is placed in special file "qqq.json" located in "languages/" folder of MediaWiki - read more in [[#Message documentation|documentation]].</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">It's preferable to use whole words with the PLURAL, GENDER, and GRAMMAR magic words.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">For example, <code><nowiki>{{PLURAL:$1|subpage|subpages}}</nowiki></code> is better than <code><nowiki>sub{{PLURAL:$1|page|pages}}</nowiki></code>.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">It makes searching easier.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Switches in messages…=== |
|||
</div> |
|||
:''<span lang="en" dir="ltr" class="mw-content-ltr">See also {{ll|Manual:Messages API#Notes about gender, grammar, plural|Manual:Messages API#Notes about gender, grammar, plural}}.</span>'' |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Parameters values at times influence the exact wording, or grammatical variations in messages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">We don't resort to ugly constructs like "$1 (sub)page(s) of his/her userpage", because these are poor for users and we can do better.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Instead, we make switches that are parsed according to values that will be known at run time.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The static message text then supplies each of the possible choices in a list, preceded by the name of the switch, and a reference to the value that makes a difference.</span> |
|||
<!--SIC! the link is meant to go to the disambiguation page. The biggest possible overview is desired. --> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This resembles the way {{ll|parser functions}} are called in MediaWiki.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Several types of switches are available.</span> |
|||
'''<span lang="en" dir="ltr" class="mw-content-ltr">These only work if you do full parsing, or <code><nowiki>{{</nowiki></code>-transformation, for the messages.</span>''' |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
====…on numbers via PLURAL==== |
|||
</div> |
|||
:''<span lang="en" dir="ltr" class="mw-content-ltr">See also {{ll|Manual:Messages API#Notes about gender, grammar, plural|Manual:Messages API#Notes about gender, grammar, plural}}.</span>'' |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">MediaWiki supports plurals, which makes for a nicer-looking product.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">For example:</span> |
|||
<syntaxhighlight lang="php"> |
|||
'undelete_short' => 'Undelete {{PLURAL:$1|one edit|$1 edits}}', |
|||
</syntaxhighlight> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
If there is an explicit plural form to be given for a specific number, it is possible with the following syntax |
|||
</div> |
|||
<syntaxhighlight lang="php"> |
|||
'Box has {{PLURAL:$1|one egg|$1 eggs|12=a dozen eggs}}.' |
|||
</syntaxhighlight> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
=====Be aware of PLURAL use on ''all'' numbers===== |
|||
</div> |
|||
:''Поврзано: [[translatewiki:Plural|Plural]]'' |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">When a number has to be inserted into a message text, be aware that some languages will have to use PLURAL on it even if always larger than 1.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The reason is that PLURAL in languages other than English can make very different and complex distinctions, comparable to English 1<sup>st</sup>, 2<sup>nd</sup>, 3<sup>rd</sup>, 4<sup>th</sup>, … 11<sup>th</sup>, 12<sup>th</sup>, 13<sup>th</sup>, … 21<sup>st</sup>, 22<sup>nd</sup>, 23<sup>rd</sup>, … ''etc.''</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Do not try to supply three different messages for cases like "no items counted", "one item counted", "more items counted".</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Rather, let one message take them all, and leave it to translators and PLURAL to properly treat any possible differences of presentation for them in their respective languages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Always include the number as a parameter if possible.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Always add <code><nowiki>{{PLURAL:}}</nowiki></code> syntax to the source messages if possible, even if it makes no sense in English.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The syntax guides translators.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Fractional numbers are supported, but the plural rules may not be complete. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
=====Pass the number of list items as parameters to messages talking about lists===== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Don't assume that there's only singular and plural.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Many languages have more than two forms, which depend on the actual number used and they have to use [[#…on use context inside sentences via GRAMMAR|grammar]] varying with the number of list items when expressing what is listed in a list visible to readers.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Thus, whenever your code computes a list, include <code>count( $list )</code> as parameter to headlines, lead-ins, footers and other messages about the list, even if the count is not used in English.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">There is a neutral way to talk about invisible lists, so you can have links to lists on extra pages without having to count items in advance.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
====…on user names via GENDER==== |
|||
</div> |
|||
:''<span lang="en" dir="ltr" class="mw-content-ltr">See also {{ll|Manual:Messages API#Notes about gender, grammar, plural|Manual:Messages API#Notes about gender, grammar, plural}}.</span>'' |
|||
<syntaxhighlight lang="php"> |
|||
'foobar-edit-review' => 'Please review {{GENDER:$1|his|her|their}} edits.' |
|||
</syntaxhighlight> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If you refer to a user in a message, pass the user name as parameter to the message and add a mention in the message documentation that gender is supported.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If it is likely that GENDER will be used in translations for languages with gender inflections, add it explicitly in the English language source message.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
If you directly address the currently logged-in user, leave the user name as parameter empty: |
|||
</div> |
|||
<syntaxhighlight lang="php"> |
|||
'foobar-logged-in-user' => 'You said {{GENDER:|you were male|you were female|nothing about your gender}}.' |
|||
</syntaxhighlight> |
|||
{{MW version|version=1.31|comment=and after|gerrit change=398772}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
If you include the user name into the message (e.g. "{{int|Notification-compact-header-flow-thank}}"), consider passing it through <code>wfEscapeWikitext()</code> first, to ensure that characters like <code>*</code> or <code>;</code> are not interpreted. |
|||
</div> |
|||
{{anchor|Users have grammatical genders}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
=====Users have grammatical genders===== |
|||
</div> |
|||
:''<span lang="en" dir="ltr" class="mw-content-ltr">See also</span> [[translatewiki:Gender|Gender]]'' |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">When a message talks about a user, or relates to a user, or addresses a user directly, the user name should be passed to the message as a parameter.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Thus languages having to, or wanting to, use proper gender dependent grammar, can do so.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This should be done even when the user name is not intended to appear in the message, such as in "inform the user on his/her talk page", which is better made "inform the user on <nowiki>{{GENDER:$1|his|her|their}}</nowiki> talk page" in English as well.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
This does not mean that you are encouraged to "sexualise" messages' language: please use gender-neutral language whenever this can be done with clarity and precision. |
|||
</div> |
|||
{{anchor|…on use context inside sentences via GRAMMAR}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
====…on use context inside sentences via GRAMMAR==== |
|||
</div> |
|||
:''<span lang="en" dir="ltr" class="mw-content-ltr">See also {{ll|Manual:Messages API#Notes about gender, grammar, plural|Manual:Messages API#Notes about gender, grammar, plural}}.</span>'' |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Grammatical transformations for agglutinative languages is also available.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">For example for Finnish, where it was an absolute necessity to make language files site-independent, ''i.e.'' to remove the Wikipedia references.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">In Finnish, "about Wikipedia" becomes "Tietoja Wikipediasta" and "you can upload it to Wikipedia" becomes "Voit tallentaa tiedoston Wikipediaan".</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Suffixes are added depending on how the word is used, plus minor modifications to the base.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">There is a long list of exceptions, but since only a few words needed to be translated, such as the site name, we didn't need to include it.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">MediaWiki has grammatical transformation functions for over 20 languages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Some of these are just dictionaries for Wikimedia site names, but others have simple algorithms which will fail for all but the most common cases.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Even before MediaWiki had arbitrary grammatical transformation, it had a nominative/genitive distinction for month names.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This distinction is necessary for some languages if you wish to substitute month names into sentences.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Filtering special characters in parameters and messages=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The other (much simpler) issue with parameter substitution is HTML escaping.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Despite being much simpler, MediaWiki does a pretty poor job of it.</span> |
|||
<!-- TODO: mention something about the [[Manual:Messages API|new Message class]] here and how to use it properly? --> |
|||
{{anchor|Message documentation}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
==Message documentation== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">There is a pseudo-language code <code>qqq</code> for message documentation.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">It is one of the ISO 639 codes reserved for private use.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">There, we do not keep translations of each message, but collect English sentences ''about each message'': telling us where it is used, giving hints about how to translate it, and enumerating and describing its parameters, link to related messages, and so on.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">In [[translatewiki:|translatewiki.net]], these hints are shown to translators when they edit messages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Programmers must document each and every message.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Message documentation is an essential resource – not just for translators, but for all the maintainers of the module.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Whenever a message is added to the software, a corresponding <code>qqq</code> entry ''must'' be added as well; revisions which don't do so are marked "<code>V-1</code>" until the documentation is added.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Documentation in <code>qqq</code> files should be edited directly only when adding new messages or when changing an existing English message in a way that requires a documentation change, for example adding or removing parameters.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">In other cases, documentation should usually be edited in translatewiki.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Each documentation string is accessible at <nowiki>https://translatewiki.net/wiki/MediaWiki:</nowiki>''message-key''<nowiki>/qqq</nowiki>, as if it were a translation.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">These edits will be exported to the source repositories along with the translations.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Useful information that should be in the documentation includes:</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# Message handling (parsing, escaping, plain text). |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# Type of parameters with example values. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# Where the message is used (pages, locations in the user interface). |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# How the message is used where it is used (a page title, button text, ''etc.''). |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# What other messages are used together with this message, or which other messages this message refers to. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# Anything else that could be understood when the message is seen on the context, but not when the message is displayed alone (which is the case when it is being translated). |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# If applicable, notes about grammar. For example, "open" in English can be both a verb and an adjective. In many other languages the words are different and it's impossible to guess how to translate them without documentation. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# Adjectives that describe things, such as "disabled", "open" or "blocked", must ''always'' say what are they describing. In many languages adjectives must have the gender of the noun that they describe. It may also happen that different kinds of things need different adjectives. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# If the message has special properties, for example, if it is a page name, or if it should not be a direct translation, but adapted to the culture or the project. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# Whether the message appears near other message, for example in a list or a menu. The wording or the grammatical features of the words should probably be similar to the messages nearby. Also, items in a list may have to be properly related to the heading of the list. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# Parts of the message that must not be translated, such as generic namespace names, URLs or tags. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# Explanations of potentially unclear words, for example abbreviations, like "CTA", or specific jargon, like "template", "suppress" or "stub". (Note that it's best to avoid such words in the first place!) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# Screenshots are very helpful. Don't crop – an image of the full screen in which the message appears gives complete context and can be reused in several messages. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
A few other hints: |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Remember that very, very often translators translate the messages without actually using the software. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Most usually, translators do not have any context information, neither of your module, nor of other messages in it. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* A rephrased message alone is useless in most circumstances. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Don't use designers' jargon like "nav" or "comps". |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Consider writing a [[betawiki:Terminology#Terminologies|glossary]] of the technical terms that are used in your module. If you do it, link to it from the messages. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
You can link to other messages by using <code><nowiki>{{msg-mw|message key}}</nowiki></code>. Please do this if parts of the messages come from other messages (if this cannot be avoided), or if some messages are shown together or in same context. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
translatewiki.net provides some default templates for documentation: |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* <code><nowiki>{{</nowiki>[[translatewiki:Template:Doc-action|doc-action]]|[...]<nowiki>}}</nowiki></code> for <code>action-</code> messages |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* <code><nowiki>{{</nowiki>[[translatewiki:Template:Doc-right|doc-right]]|[...]<nowiki>}}</nowiki></code> for <code>right-</code> messages |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* <code><nowiki>{{</nowiki>[[translatewiki:Template:Doc-group|doc-group]]|[...]|[...]<nowiki>}}</nowiki></code> for messages around user groups (<code>group</code>, <code>member</code>, <code>page</code>, <code>js</code> and <code>css</code>) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* <code><nowiki>{{</nowiki>[[translatewiki:Template:Doc-accesskey|doc-accesskey]]|[...]<nowiki>}}</nowiki></code> for <code>accesskey-</code> messages |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Have a look at the template pages for more information. |
|||
</div> |
|||
{{anchor|Internationalisation hints}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
==Internationalisation hints== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Besides [[#Message documentation|documentation]], translators ask to consider some hints so as to make their work easier and more efficient and to allow an actual and good localisation for all languages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Even if only adding or editing messages in English, one should be aware of the needs of all languages.</span> <span lang="en" dir="ltr" class="mw-content-ltr">Each message is translated into more than 300 languages and this should be done in the best possible way.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Correct implementation of these hints will very often help you write better messages in English, too.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
These are the main places where you can find the assistance of experienced and knowledgeable people regarding i18n: |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* The [[translatewiki:Support|support page]] of [[translatewiki:|translatewiki.net]]. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* The {{irc|translatewiki}} [[Special:MyLanguage/MediaWiki on IRC|IRC]] channel. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Please do ask there! |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Use Message parameters and switches properly=== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
That's a prerequisite of a correct wording for your messages. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Avoid message re-use=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The translators discourage message re-use.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This may seem counter-intuitive, because copying and duplicating code is usually a bad practice, but in system messages it is often needed.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Although two concepts can be expressed with the same word in English, this doesn't necessarily mean they can be expressed with the same word in every language.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">"OK" is a good example: in English this is used for a generic button label, but in some languages they prefer to use a button label related to the operation which will be performed by the button.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Another example is practically any adjective: a word like "multiple" changes according to gender in many languages, so you cannot reuse it to describe several different things, and you must create several separate messages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If you are adding multiple identical messages, please add message documentation to describe the differences in their contexts.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Don't worry about the extra work for translators.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Translation memory helps a lot in these while keeping the flexibility to have different translations if needed.</span> |
|||
{{anchor|Avoid_patchwork_messages|Avoid fragmented or 'patchwork' messages}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Avoid fragmented or 'patchwork' messages=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Languages have varying word orders, and complex grammatical and syntactic rules.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">It's very hard to translate "lego" messages, that is messages formed by multiple pieces of text, possibly with some indirection (also called "string concatenation").</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">It is better to make every message a complete phrase.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Several sentences can usually be combined much more easily into a text block, if needed.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">When you want to combine several strings in one message, pass them in as parameters, as translators can order them correctly for their language when translating.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
====Messages quoting each other==== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">An exception from the rule may be messages referring to one another: 'Enter the original author's name in the field labelled "<nowiki>{{int:name}}</nowiki>" and click "<nowiki>{{int:proceed}}</nowiki>" when done'.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This makes the message consistent when a software developer or wiki operator alters the messages "name" or "proceed" later.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Without the int-hack, developers and operators would have to be aware of all related messages needing adjustment, when they alter one.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Don't use terms and templates that are specific to particular projects=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">MediaWiki is used by very diverse people, within the Wikimedia movement and outside of it.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Even though it was originally built for an encyclopedia, it is now used for various kinds of content.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Therefore, use general terms.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">For example, avoid terms like "article", and use "page" instead, unless you are absolutely sure that the feature you are developing will only be used on a site where pages are called "articles".</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Don't use "village pump", which is the name of an English Wikipedia community page, and use a generic term, such as "community discussion page", instead.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Don't assume that a certain template exists on all wikis.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Templates are local to wikis.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This applies to both the source messages and to their translations.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If messages use templates, they will only work if a template is created on ''each'' wiki where the feature is deployed.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">It's best to avoid using templates in messages completely.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If you really have to use them, you must document this clearly in the message documentation and in the extension installation instructions.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Separate times from dates in sentences=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Some languages have to insert something between a date and a time which grammatically depends on other words in a sentence.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Thus, they will not be able to use date/time combined.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Others may find the combination convenient, thus it is usually the best choice to supply three parameter values (date/time, date, time) in such cases, and in each translation leave either the first one or last two unused as needed.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Avoid <code><nowiki>{{SITENAME}}</nowiki></code> in messages=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr"><code><nowiki>{{SITENAME}}</nowiki></code> has several disadvantages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">It can be anything (acronym, word, short phrase, ''etc.'') and, depending on language, may need the use of <code>[[#…on use context inside sentences via GRAMMAR|<nowiki>{{GRAMMAR}}</nowiki>]]</code> on each occurrence.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">No matter what, each message having <code><nowiki>{{SITENAME}}</nowiki></code> will need review in most wiki languages for each new wiki on which your code is installed.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">In the majority of cases, when there is not a general <code>GRAMMAR</code> configuration for a language, wiki operators will have to add or amend PHP code so as to get <code><nowiki>{{GRAMMAR}}</nowiki></code> for <code><nowiki>{{SITENAME}}</nowiki></code> working.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This requires both more skills, and more understanding, than otherwise.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">It is more convenient to have generic references like "this wiki".</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This does not keep installations from locally altering these messages to use <code><nowiki>{{SITENAME}}</nowiki></code>, but at least they don't have to, and they can postpone message adaption until the wiki is already running and used.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Avoid references to visual layout and positions=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">What is rendered where depends on skins. Most often screen layouts of languages written from left-to-right are mirrored compared to those used for languages written from right-to-left, but not always, and for some languages and wikis, not entirely.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Handheld devices, narrow windows, and so on may show blocks underneath each other, that would appear side-by-side on larger displays.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Since site- and user-written JavaScript scripts and gadgets can, and do, hide parts, or move things around in unpredictable ways, there is no reliable way of knowing the actual layout.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">It is wrong to tie layout information to content languages, since the user interface language may not be the page's content language, and layout may be a mixture of the two depending on circumstances.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Non-visual user agents like acoustic screen readers and other auxiliary devices do not even have a concept of visual layout.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Thus, you should not refer to visual layout positions in the majority of cases, though semantic layout terms may still be used ("previous steps in the form", ''etc.'').</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
MediaWiki does not support showing different messages or message fragments based on the current directionality of the interface (see [[phab:T30997|T30997]]). |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
The upcoming browser and MediaWiki support for East and North Asian top-down writing<ref>http://dev.w3.org/csswg/css3-writing-modes/</ref> will make screen layouts even more unpredictable, with at least eight possible layouts (left/right starting position, top/bottom starting position, and which happens first). |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Avoid references to screen colours=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The colour in which something is rendered depends on many factors, including skins, site- and user-written JavaScript scripts and gadgets, and local user agent over-rides for reasons of accessibility or technological limitations. Non-visual user agents like acoustic screen readers and other auxiliary devices do not even have a concept of colour.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Thus, you should not refer to screen colours. (You should also not rely on colour alone as a mechanism for informing the user of state, for the same reason.)</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Have message elements before and after each input field=== |
|||
</div> |
|||
:''<span lang="en" dir="ltr" class="mw-content-ltr">This is a suggested guideline, has not become standard in MediaWiki development</span>'' |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">While English allows efficient use of prompting in the form item–colon–space–input-field, many other languages don't.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Even in English, you often want to use "Distance: ___ metres" rather than "Distance (in metres): ___".</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Leaving {{tag|textarea|open}} elements aside, you should think of each and every input field following the "Distance: ___ metres" pattern. So:</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*give it two messages, even if the 2<sup>nd</sup> one is empty in English and some other languages, or |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*allow the placement of inputs via <code>$i</code> parameters. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Avoid untranslated HTML markup in messages=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">HTML markup not requiring translation, such as enclosing {{tag|div|open}}s, rulers above or below, and similar, should usually not be part of messages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">They unnecessarily burden translators, increase message file size, and pose the risk to accidentally being altered or skipped in the translation process.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">In general, avoid raw HTML in messages if you can.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Messages are often longer than you think!=== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Skimming foreign language message files, you almost never find messages shorter than Chinese ones, rarely shorter than English ones, and usually much longer than English ones. |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Especially in forms, in front of input fields, English messages tend to be terse, and short.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">That is often not kept in translations.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Languages may lack the technical vocabulary present in English, and may require multiple words or even complete sentences to explain some concepts.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">For example, the brief English message "TSV file:" may have to be translated in a language as literally:</span> |
|||
<blockquote>''<span lang="en" dir="ltr" class="mw-content-ltr">Please type a name here which denotes a collection of computer data that is comprised of a sequentially organised series of typewritten lines which themselves are organised as a series of informational fields each, where said fields of information are fenced, and the fences between them are single signs of the kind that slips a typewriter carriage forward to the next predefined position each. Here we go: _____ (thank you)</span>''</blockquote> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This is, admittedly, an extreme example, but you get the trait. Imagine this sentence in a column in a form where each word occupies a line of its own, and the input field is vertically centered in the next column.</span> :-( |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Avoid using very close, similar, or identical words to denote different things, or concepts=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">For example, pages may have older ''revisions'' (of a specific date, time, and edit), comprising past ''versions'' of said page. The words ''revision'', and ''version'' can be used interchangeably.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">A problem arises, when versioned pages are revised, and the revision, ''i.e.'' the process of revising them, is being mentioned, too.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This may not pose a serious problem when the two synonyms of "revision" have different translations.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Do not rely on that, however.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">It is better to avoid the use of "revision" ''aka'' "version" altogether, then, so as to avoid it being mis-interpreted.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Basic words may have unforeseen connotations, or not exist at all=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">There are some words that are hard to translate because of their very specific use in MediaWiki.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Some may [[#Expect untranslated words|not be translated at all]].</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">For example, there is no word "user" relating to "someone who uses something" in several languages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Similarly, in [[:en:Colognian language|Kölsch]] the English words "namespace" and "apartment" translate the same word.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Sticking to Kölsch, they say "corroborator and participant" in one word since any reference to "use" would too strongly imply "abuse" as well.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The term "wiki farm" is translated as "stable full of wikis", since a single-crop farm would be a contradiction in terms in the language, and not understood, ''etc.''.</span> |
|||
{{anchor|Expect untranslated words}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Expect untranslated words=== |
|||
</div> |
|||
:''<span lang="en" dir="ltr" class="mw-content-ltr">This is a suggested guideline, has not yet become standard in MediaWiki development</span>'' |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">It is not uncommon that proper names, tag names, ''etc.'' and computerese in English are not translated, and instead taken as loan-words, or foreign words.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">In the latter case, some particularly-fastidious translators may mark such words as belonging to another language with HTML markup, such as <syntaxhighlight inline lang="html"><span lang="en"> … </span></syntaxhighlight>.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
You may want to consider ensuring that your message output handler passes such markup along unmolested, despite the obvious security risks. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Permit explanatory inline markup=== |
|||
</div> |
|||
:''<span lang="en" dir="ltr" class="mw-content-ltr">This is a suggested guideline, has not yet become standard in MediaWiki development</span>'' |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Sometimes there are abbreviations, technical terms, or generally ambiguous words in target languages that may not be immediately understood by newcomers, but are obvious to experienced computer users.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">So as to avoid screen clutter of lengthy explanations without leaving newcomers stranded, translators may choose to add explanations as {{tag|abbr|open}} annotations, shown by browsers when you move the mouse over them.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
For example, the MediaWiki core message <code>exif-orientation-8</code> about image rotation, which in English is simply "<code>Rotated 90° CW</code>", in Moroccan Arabic is translated as: |
|||
</div> |
|||
:<code lang="ary">mḍwwer 90° <abbr title="Ĝks (ṫ-ṫijah) Ĝaqarib s-Saĝa">ĜĜS</abbr></code> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
giving: |
|||
</div> |
|||
:<span lang="ary">mḍwwer 90° <abbr title="Ĝks (ṫ-ṫijah) Ĝaqarib s-Saĝa">ĜĜS</abbr></span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
explaining the abbreviation for "counter clockwise" when needed. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
You may want to consider ensuring that your message output handler passes such markup along unmolested, even if the original message does not use them. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
=== Use {{tag|code|open}}, {{tag|var|open}}, and {{tag|kbd|open}} tags where needed === |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">When talking about technical parameters, values, or keyboard inputs, mark them appropriately as such using the HTML tags {{tag|code|open}}, {{tag|var|open}}, or {{tag|kbd|open}}.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Thus they are typographically set off form the normal text.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">That clarifies their sense to readers, avoiding confusion, errors and mis-representations.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Ensure that your message handler allows such markup.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Symbols, colons, brackets, ''etc.'' are parts of messages=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Many symbols are localisable, too. Some scripts have other kinds of brackets than the Latin script has.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">A colon may not be appropriate after a label or input prompt in some languages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Having those symbols included in messages helps to make better and less Anglo-centric translations, and also reduces code clutter.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
For example, there are different quotation mark conventions used in «Norwegian», »Swedish», »Danish«, „German“, and 「Japanese」.<ref>[[w:Quotation_mark#Summary_table]]</ref> |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
If you need to wrap some text in localized parentheses, brackets, or quotation marks, you can use the <code>parentheses</code> {{int:parentheses}} or <code>brackets</code> {{int:brackets}} or <code>quotation-marks</code> {{int:quotation-marks}} messages like so: |
|||
</div> |
|||
<syntaxhighlight lang=php>wfMessage( 'parentheses' )->rawParams( /* text to go inside parentheses */ )->escaped() |
|||
wfMessage( 'brackets' )->rawParams( /* text to go inside brackets */ )->escaped() |
|||
wfMessage( 'quotation-marks' )->rawParams( /* text to go inside quotation marks */ )->escaped()</syntaxhighlight> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Do not expect symbols and punctuation to survive translation=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Languages written from right to left (as opposed to English) usually swap arrow symbols being presented with "next" and "previous" links, and their placement relative to a message text may, or may not, be inverted as well.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Ellipsis may be translated to "''etc.''", or to words.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Question marks, exclamation marks, colons will be placed other than at the end of a sentence, not at all, or twice.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">As a consequence, always include all of those in the text of your messages, and never try to insert them programmatically.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Use full stops=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">'''Do''' terminate normal sentences with full stops.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This is often the only indicator for a translator to know that they are not headlines or list items, which may need to be translated differently.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Link anchors=== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
====Wikitext of links==== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Link anchors can be put into messages in several technical ways: |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# via wikitext: … <code><nowiki>[[</nowiki>''a wiki page''|''anchor''<nowiki>]]</nowiki></code> …, |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
#via wikitext: … <code>[''some-url'' ''anchor'']</code> …, or |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
#the anchor text is a message in the MediaWiki namespace. ''Avoid it!'' |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The latter is often hard or impossible to handle for translators, [[#Avoid fragmented or 'patchwork' messages|avoid fragmented or 'patchwork' messages]] here, too.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Make sure that "<code>some-url</code>" does not contain spaces.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
====Use meaningful link anchors==== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Take care with your wording.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Link anchors play an important role in search engine assessment of pages – both the words linked, and the target anchor.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Make sure that the anchor describes the target page well.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Always avoid commonplace and generic words.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">For example, "Click here" is an absolute no-go,<ref>http://www.w3.org/QA/Tips/noClickHere</ref> since target pages are almost never about "click here".</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Do not put that in sentences around links either, because "here" was not the place to click.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Instead, Use precise action words telling what a user will get to when following the link, such as "You can [[Special:Upload|upload a file]] if you wish."</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
See also ''[http://www.nngroup.com/articles/using-link-titles-to-help-users-predict-where-they-are-going/ Help users predict where they are going]'', and [[w:en:Mystery meat navigation|mystery meat navigation]], and ''[https://tosbourn.com/click-here/ The main reasons why we shouldn't use click here as link text]''. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Avoid jargon and slang=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Avoid developer and power user jargon in messages. Try to use a simple language whenever possible.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Avoid saying "success", "successfully", "fail", "error occurred while", etc., when you want to notify the user that something happened or didn't happen.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This comes from developers' perspective of seeing everything as true or false, but users usually just want to know what actually happened or didn't, and what they should do about it (if at all). So:</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* "The file was successfully renamed" -> "The file was renamed" |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* "File renaming failed" -> "There is a file with this name already. Please choose a different name." |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===One sentence per line=== |
|||
</div> |
|||
:''<span lang="en" dir="ltr" class="mw-content-ltr">This is a suggested guideline, has not yet become standard in MediaWiki development</span>'' |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Try to have one sentence or similar block in one line. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">This helps to compare the messages in different languages, and may be used as an hint for segmentation and alignment in translation memories.</span> |
|||
<!-- Explain what this means with an actual example (it's currently meaningless) or remove this section. --> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Be aware of whitespace and line breaks=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">MediaWiki's localised messages usually get edited within the wiki, either by wiki operations on live wikis, or by the translators on [[translatewiki.net]].</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">You should be aware of how whitespace, especially at the beginning or end of your message, will affect editors:</span> |
|||
* Spaces and line breaks (new lines) at the end of the message are always automatically removed by the wikitext editor. Your message must not end with a space or line break, as it will be lost when it's edited on the wiki. |
|||
* Spaces and line breaks at the beginning are not automatically removed, but they are likely to be removed by accident during editing, and should be avoided. |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Start and end your message with active text; if you need a newline or paragraph break around it, your surrounding code should deal with adding it to the returned text. |
|||
</div> |
|||
There are some messages which require a space at the end, such as 'word-separator' (which consists of just a space character in most languages). |
|||
To support such use cases, the following HTML entities are allowed in messages and transformed to the actual characters, even if the message otherwise doesn't allow wikitext or HTML formatting:<ref>https://github.com/wikimedia/mediawiki/blob/REL1_34/includes/cache/MessageCache.php#L887</ref> |
|||
* <code>&#32;</code> – space |
|||
* <code>&nbsp;</code> or <code>&#160;</code> – [[w:non-breaking space|non-breaking space]] |
|||
* <code>&shy;</code> – [[w:soft hyphen|soft hyphen]] |
|||
On a related note, any other syntax elements affected by [[pre-save transforms]] also must not be used in messages, as they will be transformed when the message is edited on the wiki. |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Use standard capitalisation=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Capitalisation gives hints to translators as to what they are translating, such as single words, list or menu items, phrases, or full sentences.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Correct (standard) capitalisation may also play a role in search engines' assessment of your pages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">MediaWiki uses [[w:Letter case|sentence case]] (''The quick brown fox jumps over the lazy dog'') in interface messages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Always remember that many writing systems don't have capital letters at all, and some of those that do have them, use them differently from English.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Therefore, don't use ALL-CAPS for emphasis.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Use CSS, or HTML {{tag|em|open}} or {{tag|strong|open}} per below:</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
====Emphasis==== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">In normal text, [[w:Emphasis|emphasis]] like '''boldface''' or ''italics'' and similar should be part of message texts.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Local conventions on emphasis often vary, especially some Asian scripts have their own.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Translators must be able to adjust emphasis to their target languages and areas.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Try to use "{{tag|em|open}}" and "{{tag|strong|open}}" in your user interface to allow mark-up on a per language or per script basis.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">In modern screen layouts of English and European styles, emphasis becomes less used.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Do convey it in your [[#Message documentation|message documentation]] still, as it may give valuable hints as to how to translate.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Emphasis can and should be used in other cultural contexts as appropriate, provided that translators know about it.</span> |
|||
{{anchor|Overview of the localisation system}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
==Overview of the localisation system== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Update of localisation=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">As mentioned above, translation happens on translatewiki.net and other systems are discouraged.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Here's a high level overview of the localisation update workflow:</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Developers {{ll|Help:System message|add or change system messages}}. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Users translate the new or changed system messages on translatewiki.net. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Automated tools export these messages, build ''new versions'' of the message files, incorporating the added or updated messages, for both core and extensions, and commit them to [[Special:MyLanguage/Gerrit|git]]. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* The wikis then can pull in the updated system messages from the git repository. |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Wikimedia projects and any other wikis can benefit immediately and automatically from localisation work thanks to the {{ll|Extension:LocalisationUpdate|nsp=0}} extension.</span><ref> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Which works through the localisation cache and for instance on Wikimedia projects updates it daily; see also the [[wikitech:LocalisationUpdate|technical details]] about the specific implementation.</span> |
|||
</ref> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This compares the latest English messages to the English messages in production.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If they are not the same, the production translations are updated and made available to users.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Once translations are in the version control system, the Wikimedia Foundation has a daily job that updates a checkout or clone of the extension repository.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This was first established in September 2009.<ref>[http://ultimategerardm.blogspot.it/2009/08/localisationupdate-update_26.html LocalisationUpdate update]; [http://ultimategerardm.blogspot.it/2009/09/localisationupdate-is-live.html LocalisationUpdate is live].</ref></span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Because changes on translatewiki.net are pushed to the code daily as well, this means that each change to a message can potentially be applied to all existing MediaWiki installations in a couple days without any manual intervention or traumatic code update. |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">As you can see this is a multi-step process.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Over time, we have found out that many things can go wrong.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If you think the process is broken, please make sure to report it on our [[translatewiki:Support|Support]] page, or create a new bug in [https://phabricator.wikimedia.org Phabricator].</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Always be sure to describe a precise observation.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Handling support requests=== |
|||
</div> |
|||
:''<span lang="en" dir="ltr" class="mw-content-ltr">Main page: [[translatewiki:Translating:Localisation for developers]].</span>'' |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Translators may have questions about some of the messages you create.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Translatewiki.net provides a [[translatewiki:Support/Open_requests|support request]] system that allows translators the ability to ask you, the project owner, questions regarding messages so that they can be better translated.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This short tutorial guides you through the workflow of handling translatewiki.net support requests.</span> |
|||
[[File:Handling_translatewiki_support_requests.webm|centre|320x320px]] |
|||
{{anchor|Message sources}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Message sources=== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Code looks up {{ll|Help:System message|system messages}} from these sources: |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*The MediaWiki namespace. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">This allows wikis to adopt, or override, all of their messages, when standard messages do not fit or are not desired (see [[#Old local translation system|#Old local translation system]]).</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
**MediaWiki:''Message-key'' is the default message, |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
**MediaWiki:''Message-key''/''language-code'' is the message to be used when a user has selected a language other than the wiki's default language. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*From message files: |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
**Core MediaWiki itself and most currently maintained [[Special:MyLanguage/Category:All extensions|extensions]] use a file per language, named <code>''zyx''.json</code>, where ''zyx'' is the language code for the language. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
**Some older extensions use a combined message file holding all messages in all languages, usually named <code>''MyExtensionName''.i18n.php</code>. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
**Many Wikimedia Foundation wikis access some messages from the {{ll|Extension:WikimediaMessages|nsp=0}} extension, allowing them to standardise messages across WMF wikis without imposing them on every MediaWiki installation. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
**A few extensions use other techniques. |
|||
</div> |
|||
{{anchor|Caching}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Caching=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">System messages are one of the more significant components of MediaWiki, primarily because it is used in every web request.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The PHP message files are large, since they store thousands of message keys and values.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Loading this file (and possibly multiple files, if the user's language is different from the content language) has a large memory and performance cost.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">An aggressive, layered caching system is used to reduce this performance impact.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">MediaWiki has lots of caching mechanisms built in, which make the code somewhat more difficult to understand.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Since 1.16 there is a new caching system, which caches messages either in .{{ll|cdb|cdb}} files or in the database.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Customised messages are cached in the filesystem and in {{ll|memcached}} (or alternative), depending on the configuration.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The table below gives an overview of the settings involved:</span> |
|||
{|class="wikitable" |
|||
|- |
|||
!colspan="2" rowspan="2"| <span lang="en" dir="ltr" class="mw-content-ltr">Location of cache storage</span> |
|||
!colspan="4"| {{ll|Manual:$wgLocalisationCacheConf|$wgLocalisationCacheConf}} |
|||
|- |
|||
! 'store' => 'db'<br /> !! 'store' => 'detect'<br />(<span lang="en" dir="ltr" class="mw-content-ltr">default</span>) !! 'store' => 'files'<br /> !! 'store' => 'array'<br />''(<span lang="en" dir="ltr" class="mw-content-ltr">experimental since MW ≥ 1.26</span>)'' |
|||
|- |
|||
!rowspan="2"| {{ll|Manual:$wgCacheDirectory|$wgCacheDirectory}} |
|||
! = false<br />(default) |
|||
| {{ll|Manual:l10n cache table|l10n cache table}} || {{ll|Manual:l10n cache table|l10n cache table}} || ''<span lang="en" dir="ltr" class="mw-content-ltr">error</span>'' (<span lang="en" dir="ltr" class="mw-content-ltr">undefined path</span>) || ''<span lang="en" dir="ltr" class="mw-content-ltr">error</span>'' (<span lang="en" dir="ltr" class="mw-content-ltr">undefined path</span>) |
|||
|- |
|||
! = ''path'' |
|||
| {{ll|Manual:l10n cache table|l10n cache table}} || <span lang="en" dir="ltr" class="mw-content-ltr">local filesystem</span> (CDB) || <span lang="en" dir="ltr" class="mw-content-ltr">local filesystem</span> (CDB) || <span lang="en" dir="ltr" class="mw-content-ltr">local filesystem (PHP array)</span> |
|||
|} |
|||
{{MW version|version=1.27.0|version2=1.27.2|gerrit change=Id3e2d2b18ddb423647bf2e893bcf942722c0e097}} |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">In MediaWiki 1.27.0 and 1.27.1, the autodetection was changed to favor the file backend.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">In case <code>'store' => 'detect'</code> (the default), the file backend is used with the path from {{ll|Manual:$wgCacheDirectory|$wgCacheDirectory}}.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If this value is not set (which is the default), a temporary directory determined by the operating system is used.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If a temporary directory cannot be detected, the database backend is used as a fallback.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This was reverted from 1.27.2 and 1.28.0 because of conflict of files on shared hosts and security issues (see [[:phab:T127127|T127127]] and [[:phab:T161453|T161453]]).</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
====Function backtrace==== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
To better visually depict the layers of caching, here is a function backtrace of what methods are called when retrieving a message. See the below sections for an explanation of each layer. |
|||
</div> |
|||
* <code>Message::fetchMessage()</code> |
|||
* <code>MessageCache::get()</code> |
|||
* <code>Language::getMessage()</code> |
|||
* <code>LocalisationCache::getSubitem()</code> |
|||
* <code>LCStore::get()</code> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
====MessageCache==== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The <code>MessageCache</code> class is the top level of caching for messages. It is called from the Message class and returns the final raw contents of a message.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This layer handles the following logic:</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Checking for message overrides in the database |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Caching over-ridden messages in {{ll|memcached|memcached}}, or whatever {{ll|Manual:$wgMessageCacheType|$wgMessageCacheType}} is set to |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* Resolving the remainder of the {{ll|Manual:Language#Fallback languages|language fallback}} sequence |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The last bullet is important.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">{{ll|Manual:Language#Fallback languages|Language fallbacks}} allow MediaWiki to fall back on another language if the original does not have a message being asked for.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">As mentioned in the next section, most of the language fallback resolution occurs at a lower level.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">However, only the <code>MessageCache</code> layer checks the database for overridden messages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Thus integrating overridden messages from the database into the fallback chain is done here.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If not using the database, this entire layer can be disabled.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
====LocalisationCache==== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
See {{ll|Manual:LocalisationCache.php|LocalisationCache.php}} |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
====LCStore==== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The <code>LCStore</code> class is merely a back-end implementation used by the LocalisationCache class for actually caching and retrieving messages.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Like the <code>BagOStuff</code> class, which is used for general caching in MediaWiki, there are a number of different cache types (configured using {{ll|Manual:$wgLocalisationCacheConf|$wgLocalisationCacheConf}}):</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* "db" (default) - Caches messages in the database |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* "file" (default if <code>$wgCacheDirectory</code> is set) - Uses [[w:cdb (software)|CDB]] to cache messages in a local file |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
* "accel" - Uses [[Special:MyLanguage/Manual:Caching|APC]] or another opcode cache to store the data |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
The "file" option is used by the Wikimedia Foundation, and is recommended because it is faster than going to the database and more reliable than the APC cache, especially since APC is incompatible with PHP versions 5.5 or later. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Licence=== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Any edits made to the language must be licensed under the terms of the [[:en:GNU General Public License|GNU General Public License]] to be included in the MediaWiki software. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">Other extensions may be under different licences.</span> |
|||
{{anchor|History|Old local translation system}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Old local translation system=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">With MediaWiki 1.3.0, a new system was set up for localising MediaWiki.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Instead of editing the language file and asking developers to apply the change, users could edit the interface strings directly from their wikis.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This is the system in use as of August 2005.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">People can find the message they want to translate in [[Special:AllMessages]] and then edit the relevant string in the <code>MediaWiki:</code> namespace.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Once edited, these changes are live.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">There was no more need to request an update, and wait for developers to check and update the file.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
The system is great for Wikipedia projects; however a side effect is that the MediaWiki language files shipped with the software are no longer quite up-to-date, and it is harder for developers to keep the files on meta in sync with the real language files. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
As the default language files do not provide enough translated material, we face two problems: |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
#New Wikimedia projects created in a language which has not been updated for a long time, need a total re-translation of the interface. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
#Other users of MediaWiki (including Wikimedia projects in the same language) are left with untranslated interfaces. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">This is especially unfortunate for the smaller languages which don't have many translators.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">This is not such a big issue anymore, because translatewiki.net is advertised prominently and used by almost all translations.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Local translations still do happen sometimes but they're strongly discouraged.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Local messages mostly have to be deleted, moving the relevant translations to translatewiki.net and leaving on the wiki only the site-specific customisation; there's a huge backlog especially in older projects, [//toolserver.org/~robin/?tool=cleanuplocalmsgs this tool] helps with cleanup.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Keeping messages centralised and in sync=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">English messages are very rarely out of sync with the code.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Experience has shown that it's convenient to have all the English messages in the same place.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Revising the English text can be done without reference to the code, just like translation can.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Programmers sometimes make very poor choices for the default text.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
==Appendix== |
|||
</div> |
|||
{{Anchor|what-can-be-localized}}<!-- for links from external pages--> |
|||
{{anchor|What can be localized}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===What can be localised=== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">So many things are localisable on MediaWiki that not all of them are directly available on [[translatewiki.net]]: see [[translatewiki:Translating:MediaWiki]].</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If something requires a [[developer]] intervention on the code, you can [[Special:MyLanguage/How to report a bug|request it on Phabricator]], or ask at [[translatewiki:Support]] if you don't know what to do exactly.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*[[#Namespaces|Namespaces]] (both core and extensions', plus [[#Users have grammatical genders|gender]]-dependent user namespaces) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Weekdays (and abbreviations) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Months (and abbreviations) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Bookstores for [[Special:BookSources]] |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Skin names |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Math names |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*{{ll|Manual:Date formatting|Date preferences}} (<code>$datePreferences</code>) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*{{ll|Manual:Date formatting|Date formats}} (<code>$dateFormats</code>) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*{{ll|Manual:Date formatting|Default date format}} (<code>$defaultDateFormat</code>) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*{{ll|Manual:Date formatting|Date preference migration map}} (for compatibility with old MediaWiki databases) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Default user option overrides |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Language names |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Country names (via {{ll|Extension:CLDR}}) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Currency names (via {{ll|Extension:CLDR}}) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Timezones |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Character encoding conversion via <code>iconv</code> |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*UpperLowerCase first (needs casemaps for some){{clarify}} |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*UpperLowerCase{{clarify}} |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Uppercase words |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Uppercase word breaks{{clarify}} |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Case folding{{clarify}} |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Strip punctuation for MySQL search (search optimisation) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Get first character |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Alternate encoding |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Recoding for edit (and then recode input){{clarify}} |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
[[Image:MediaWiki fallback chains.svg|thumb|Graph of language fallback]] |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*[[Fallback languages]] (that is, other more closely related language(s) to use when a translation is not available, instead of the default fallback, which is English) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Directionality (left to right or right to left, RTL) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Direction mark character depending on RTL |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Arrow depending on RTL |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Languages where italics cannot be used |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Number formatting (comma-ify, ''i.e.'' adding or not digits separators; transform digits; transform separators)<ref>These are configured by language in the respective <code>language/classes/LanguageXx.php</code> or <code>language/messages/MessagesXx.php</code> files.</ref> |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Truncate (multibyte) |
|||
</div> |
|||
*[[#…on use context inside sentences via GRAMMAR|<span lang="en" dir="ltr" class="mw-content-ltr">Grammar conversions for inflected languages</span>]] |
|||
*[[#Be aware of PLURAL use on all numbers|<span lang="en" dir="ltr" class="mw-content-ltr">Plural transformations</span>]] |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Formatting expiry times{{clarify}} |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Segmenting for diffs (Chinese) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Convert to variants of language (between different orthographies, or scripts) |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Language specific user preference options |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*{{ll|Help:Links#linktrail|Link trails}} and link prefix, ''e.g.'': <code><nowiki>[[foo]]</nowiki>bar</code> These are letters that can be glued after/before the closing/opening brackets of a wiki link, but appear rendered on the screen as if part of the link (that is, clickable and in the same colour). |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">By default the link trail is "a-z"; you may want to add the accentuated or non-Latin letters used by your language to the list.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Language code (preferably used according to the latest RFC in standard BCP 47, currently {{IETF RFC|5646}}, with its associated IANA database. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">Avoid deprecated, grandfathered and private-use codes: look at what they mean in standard ISO 639, and avoid codes assigned to collections/families of languages in ISO 639-5, and ISO 639 codes which were not imported in the IANA database for BCP 47)</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Type of emphasising |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*The {{ll|Extension:Cite|nsp=0}} extension has a special page file per language, <code>cite_text-''zyx''</code> for language code <code>zyx</code>. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Neat functionality: |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*I18N <code>sprintfDate</code> |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
*Roman numeral formatting |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
====Namespace name aliases==== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Namespace name aliases are additional names which can be used to address existing namespaces.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">They are rarely needed, but not having them when they are, usually creates havoc in existing wikis.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
You need namespace name aliases: |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# When a language has variants, and these variants spell some namespaces differently, and you want editors to be able to use the variant spellings. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">Variants are selectable in the user preferences.</span> <span lang="en" dir="ltr" class="mw-content-ltr">Users always see their selected variant, except in wikitext, but when editing or searching, an arbitrary variant can be used.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
# When an existing wiki's language, fall back language(s), or localisation is changed, with it are changed some namespace names. |
|||
</div> <span lang="en" dir="ltr" class="mw-content-ltr">So as not to break the links already present in the wiki, that are using the old namespace names, you need to add each of the altered previous namespace names to its namespace name aliases, when, or before, the change is made.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
The generic English namespace names are always present as namespace name aliases in all localisations, so you need not, and should not, add those. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Aliases can't be translated on [[translatewiki.net]], but can be requested there or on [[bugzilla]]: see [[translatewiki:Translating:MediaWiki#Namespace name aliases]]. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
====Regional settings==== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
Some linguistic settings vary across geographies; MediaWiki doesn't have a concept of region, it only has languages and language variants. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
These settings need to be set once as a language's default, then individual wikis can change them as they wish in their configuration. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===== Time and date formats ===== |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Time and dates are shown on special pages and alike.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The default time and date format is used for signatures, so it should be the most used and most widely understood format for users of that language.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Also anonymous users see the default format.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Registered users can choose other formats in their preferences.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If you are familiar with PHP's time() format, you can try to construct formats yourself.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">MediaWiki uses a similar format string, with some extra features.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">If you don't understand the previous sentence, that's OK.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">You can provide a list of examples for {{ll|Developers|developers}}.</span> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
==== Old edit window toolbar buttons ==== |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
:''Not to be confused with the much more common {{ll|Extension:WikiEditor|nsp=0}}'s "advanced toolbar", which has similar features.'' |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">When a wiki page is being edited, and a user has allowed it in their [[Special:Preferences]], a set of icons is displayed above the text area where one can edit.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">The toolbar buttons can be set [http://nike.fixme.fi/blag/2008/07/05/localisation-of-images/] but there are no messages for it.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">What we need is a set of properly sized <code>.png</code> files.</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">Plenty of samples can be found in [[commons:Category:ButtonToolbar]], and there is an [[:Image:Button_base.png|empty button image]] to start off from.</span> |
|||
{{note|1=<span lang="en" dir="ltr" class="mw-content-ltr">This can only be done when your language is already enabled in MediaWiki, which usually means a good portion of its messages have been translated; otherwise you must just wait, and have it done later.</span>}} |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
===Missing=== |
|||
</div> |
|||
'''<span lang="en" dir="ltr" class="mw-content-ltr">This section is missing about the changes in the i18n system related to extensions.</span> <span lang="en" dir="ltr" class="mw-content-ltr">The format was standardised and messages are automatically loaded.</span>''' |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
See [[#Message sources|#Message sources]]. |
|||
</div> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
== External tools internationalization == |
|||
</div> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">To facilitate the internalization and localization of external tools, such as those located in {{ll|Toolforge}}, you can use the [https://github.com/wikimedia/banana-i18n Banana library].</span> |
|||
<span lang="en" dir="ltr" class="mw-content-ltr">It allows you to use some magic words:</span> |
|||
* <code><nowiki>{{PLURAL:$1|pluralform1|pluralform2|...}}</nowiki></code> |
|||
* <code><nowiki>{{GENDER:$2|his|her}}</nowiki></code> |
|||
* <code><nowiki>{{grammar:genitive|$1}}</nowiki></code> |
|||
* <code><nowiki>{{bidi:$1}}</nowiki></code>. |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
|||
==References== |
|||
</div> |
|||
<references /> |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
<div lang="en" dir="ltr" class="mw-content-ltr"> |
||
| Line 1,434: | Line 95: | ||
</div> |
</div> |
||
** {{ll|API:Localisation}} |
** {{ll|API:Localisation}} |
||
** |
** {{ll|Language tools}} - <span lang="en" dir="ltr" class="mw-content-ltr">The work of the Wikimedia Foundation's i18n/l10n team</span> |
||
** <span lang="en" dir="ltr" class="mw-content-ltr">[[:File:How to i18n your code - presentation for DevCamp.pdf|How to internationalise your code]] presentation - PDF slides about i18n, l10n and m17n in general and about doing it in MediaWiki in particular. (2012)</span> |
|||
** {{ll|Internationalization and localization tools|The work of the Wikimedia Foundation's i18n/l10n team}} |
|||
** [[:File:How to i18n your code - presentation for DevCamp.pdf|How to i18n your code]] - a presentation about i18n, l10n and m17n in general and about doing it in MediaWiki in particular. |
|||
* {{ll|Help:System message}} (overview) and {{ll|Manual:Messages API}} (how to use messages, for developers) |
|||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
<div lang="en" dir="ltr" class="mw-content-ltr"> |
||
* Statistics and issues |
* Statistics and issues |
||
</div> |
</div> |
||
** [https://translatewiki.net/w/i.php?title=Special:MessageGroupStats&group=mediawiki <span lang="en" dir="ltr" class="mw-content-ltr">Localisation statistics</span>] |
|||
** {{ll|Localisation statistics}} |
|||
** {{ll|Localisation checks}} |
** {{ll|Localisation checks}} |
||
** [[phab:tag/i18n|MediaWiki bug reports for Internationalisation]] |
** [[phab:tag/i18n|<span lang="en" dir="ltr" class="mw-content-ltr">MediaWiki bug reports for Internationalisation</span>]] |
||
<div lang="en" dir="ltr" class="mw-content-ltr"> |
<div lang="en" dir="ltr" class="mw-content-ltr"> |
||
* Other |
* Other |
||
</div> |
</div> |
||
** <span lang="en" dir="ltr" class="mw-content-ltr">{{ll|Manual:Wiki family}} - installation and configuration of a small wiki-family (for administrators)</span> |
|||
** [[m:Help:How to start a new Wikipedia#Translate the interface, etc.|How to start a new Wikipedia? Translate the interface]] |
|||
** {{ll|Manual:Wiki family}} - installation and configuration of a small wiki-family (for administrators) |
|||
** {{ll|Template:Languages}} |
** {{ll|Template:Languages}} |
||
** <span lang="en" dir="ltr" class="mw-content-ltr">Debian's [https://www.debian.org/doc/manuals/intro-i18n/ Introduction to i18n]</span> |
|||
** [http://www.globalvis.com/internationalization-i18n-dos-and-donts-in-software-development-before-product-localization/ Do’s and Don’ts in software development before product localization] – 12 brief points |
|||
** <span lang="en" dir="ltr" class="mw-content-ltr">[http://www.unicode.org/reports/ Unicode Technical Reports] (also [http://www.unicode.org/faq/specifications.html specifications by topic])</span> |
|||
** Debian's [https://www.debian.org/doc/manuals/intro-i18n/ Introduction to i18n] |
|||
** [http://www.unicode.org/reports/ Unicode Technical Reports] (also [http://www.unicode.org/faq/specifications.html specifications by topic]) |
|||
{{Development guidelines navigation}} |
{{Development guidelines navigation}} |
||
Latest revision as of 10:59, 11 December 2024
This landing page links to core technical documentation about MediaWiki internationalisation and localisation (i18n and L10n). A core principle of MediaWiki is that i18n must not be an afterthought: i18n and l10n are an essential component even in the earliest phases of software development.
For translators and users
- Translator hub
- For translating pages on this wiki, see Project:Language policy.
- How to translate MediaWiki interface messages
- Language names reference
- How to input text in different scripts (IMEs)
- How to download and enable different webfonts
- Universal Language Selector FAQ
For developers
Write code that can be localised
Get your code translated
- Use translatewiki.net
- What can be localised
- How to find a MediaWiki string for translation
- translatewiki.net FAQ for MediaWiki
- To localise external tools, like those in Toolforge, use the Banana library.
- Localise an extension
Implement a multilingual wiki
Add a wiki in a new language
Help and contact info
- IRC: #translatewiki connect
- Telegram channel: translatewiki.net.
See also
- Resources
- API:Localisation
- Language tools - The work of the Wikimedia Foundation's i18n/l10n team
- How to internationalise your code presentation - PDF slides about i18n, l10n and m17n in general and about doing it in MediaWiki in particular. (2012)
- Statistics and issues
- Other
- Manual:Wiki family - installation and configuration of a small wiki-family (for administrators)
- Template:Languages
- Debian's Introduction to i18n
- Unicode Technical Reports (also specifications by topic)