一键导入
mediawiki-translate-extension
Work with the Translate extension for multilingual wiki content — marking pages for translation, writing translatable templates, using
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Work with the Translate extension for multilingual wiki content — marking pages for translation, writing translatable templates, using
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Deploy Python web services on Wikimedia Toolforge — Flask (WSGI) and FastAPI (ASGI), gunicorn/uvicorn, Build Service and traditional Kubernetes backends, virtual environments, pip caching, PORT configuration, static files, logging, and common pitfalls
Understand and work with English Wikipedia's WikiProject system — finding relevant projects, interpreting assessment tables, using Popular pages and work lists, and navigating project directories
Understand and query Wikidata — the free, collaborative, multilingual knowledge graph that underpins Wikipedia's inter-language links, Commons structured data, and semantic facts across all Wikimedia projects. Covers SPARQL, the Wikibase REST/Action APIs, RDF data dumps, and semantic web concepts
Query Wikidata by meaning, concept, or natural-language description — not just by exact label match. Uses semantic embeddings to find items (QIDs) and properties (PIDs) via vector similarity, keyword search, and Reciprocal Rank Fusion. Covers fuzzy semantic search, concept matching, similarity lookups, cross-lingual queries, and "find like this" when you do not know the exact QID or label
Design multilingual Toolforge tools — message files and ICU plurals, language detection and fallback chains, RTL/bidi layout, Unicode normalization and pitfalls, cross-wiki domain mapping, batch Wikidata label fetching, and avoiding English Wikipedia assumptions
Deploy and manage Node.js web services on Wikimedia Toolforge Kubernetes — zero-dependency server patterns, webservice commands, PORT configuration, static file serving with caching headers, npm on NFS, environment variables, logging, and common pitfalls
| name | mediawiki-translate-extension |
| description | Work with the Translate extension for multilingual wiki content — marking pages for translation, writing translatable templates, using |
| license | MIT |
| compatibility | opencode |
| depends_on | ["wikimedia-api-access","wikipedia-templates"] |
| skill_discovery_hints | [{"keywords":["Translate extension","page translation","translatable","<translate>","translation unit","language subpage"]},{"keywords":["Special:MyLanguage","#timef","translation memory","message group","fuzzy translation"]}] |
| last_verified | "2026-06-10T00:00:00.000Z" |
⚠️ User-Agent required: The API examples below hit Wikimedia endpoints. All requests must include a descriptive
User-Agentheader. See the wikimedia-api-access skill for the correct format.📖 Prerequisites: For general template syntax and parser functions, see wikipedia-templates. For navigation patterns that use
Special:MyLanguage/, see mediawiki-page-navigation. For styling translatable templates, see wikimedia-page-styling.
<translate> Tags<languages/> Bar/en, /fi, /ko, etc.)<tvar>)Special:MyLanguage/ — Language-Aware Links#timef — Locale-Aware Date Formatting{{TRANSLATABLEPAGE}} Magic WordThe Translate extension is MediaWiki's built-in system for creating multilingual content. It is installed on Meta, mediawiki.org, Commons, and many other Wikimedia wikis, but not on Wikipedia (which uses interlanguage links instead).
Without the Translate extension, multilingual wikis faced these problems:
| Problem | Without Translate | With Translate |
|---|---|---|
| How to display multiple languages | Manual copy-paste, hard to maintain | Automatic language subpages + <languages/> bar |
| How to track completion | No visibility | Colored progress indicators per language |
| What happens when source changes | Translations go out of sync silently | Marked as "outdated" (fuzzy) until reviewed |
| How to format dates per locale | Hard-coded formats | #timef — auto-formats to user's language |
| How to link to translated pages | Manual per-language links | Special:MyLanguage/ — follows user's preference |
| Wiki | Translate Extension | Purpose |
|---|---|---|
| meta.wikimedia.org | ✅ Yes | Cross-project coordination docs, multilingual community pages |
| commons.wikimedia.org | ✅ Yes | Multilingual file descriptions |
| mediawiki.org | ✅ Yes | Software documentation in dozens of languages |
| en.wikipedia.org | ❌ No | Uses interlanguage links instead |
| translatewiki.net | ✅ Yes (primary) | Software interface translation (MediaWiki, extensions) |
| Toolforge | ✅ Yes | Tool documentation |
The Translate extension has two distinct modes:
Content is written in one language (usually English) and marked for translation with <translate> tags. Translation administrators approve the page, and translators can translate each unit through the Special:Translate interface. This is what AvoinGLAM pages use.
Best for: Long-form content, documentation, community pages that need human-quality translation.
Individual messages are defined as wiki pages in the MediaWiki namespace and translated via the same interface. Used for site UI and template messages.
Best for: Template labels, UI strings, small snippets.
This skill focuses on Page Translation, which is what the AvoinGLAM pages use.
To make a page translatable, wrap translatable content in <translate> tags:
<languages />
<translate>
== Introduction == <!--T:1-->
Welcome to the AvoinGLAM project.
== Mission == <!--T:2-->
Our goal is to promote Open Access to cultural heritage.
</translate>
Write the page in the base language (usually English), wrapping translatable content in <translate>... </translate>
Add <languages /> at the top (this shows the language selector bar)
Add translation unit markers — <!--T:1-->, <!--T:2-->, etc. — after each heading or paragraph. These can be auto-generated when the page is marked for translation.
Request translation marking — a translation administrator uses Special:PageTranslation to mark the page
Translators translate via Special:Translate — each unit gets translated independently
The system creates language subpages — /en, /fi, /fr, etc.
<translate>Only the translatable content goes inside <translate> tags. Things that should NOT be translated:
Content outside <translate> tags is page-global — it appears on all language variants unchanged:
<languages />
{{Project/Navigation}}
<translate><!--T:1-->
Welcome to our project.
</translate>
[[:Category:Project]] ← Categories are page-global, outside translate
<translate> TagsA translation unit is the smallest piece of content that can be translated independently. Each unit gets a unique identifier (<!--T:1-->).
<translate>
== Heading == <!--T:1-->
This is a paragraph. It is one translation unit. <!--T:2-->
This is another paragraph. It is a separate unit. <!--T:3-->
</translate>
Rules for translation units:
<!--T:N--> marker after itHeadings inside <translate> become their own translation units:
<translate>
== Contact us == <!--T:10-->
Reach us at example@example.org. <!--T:11-->
</translate>
The heading is unit 10, the paragraph is unit 11.
List items can be individual units:
<translate>
Our activities include: <!--T:20-->
* Workshops <!--T:21-->
* Hackathons <!--T:22-->
* Online events <!--T:23-->
</translate>
Content can be mixed inside and outside <translate> tags, but each section must be a complete block:
<translate><!--T:30-->
This paragraph is translatable.
</translate>
{{Some template that should not be translated}}
<translate><!--T:31-->
This paragraph is also translatable.
</translate>
<languages/> BarPlace <languages /> at the very top of the page, before any content:
<languages />
{{Project/Navigation}}
<translate>
...
</translate>
The bar shows all available translations with colored progress indicators:
Languages: English ✅ Finnish ✅ French 🔵 Arabic 🟡 German 🔴
| Color | Meaning |
|---|---|
| ✅ Green | 100% translated and up-to-date |
| 🔵 Blue | 100% translated but some units are outdated (fuzzy) |
| 🟡 Yellow/Orange | Partially translated |
| 🔴 Red | Not translated at all |
<languages/> at the BottomYou only need one <languages /> tag at the top — do not add it to the bottom.
For templates that are translated (like navigation templates), place <languages /> inside <noinclude> so it only appears on the template page itself, not when transcluded:
<noinclude><languages /></noinclude>
<templatestyles src="Project/style.css" />
<translate>... translatable template content ...</translate>
/en, /fi, /ko, etc.)When a page is marked for translation, the system automatically creates language subpages:
AvoinGLAM ← Base page (contains the translatable source)
AvoinGLAM/en ← English translation
AvoinGLAM/fi ← Finnish translation
AvoinGLAM/ko ← Korean translation
<translate> tags/fi, you see the Finnish translation<languages /> bar on the base page links to all variantsLanguage subpages work for templates too. The AvoinGLAM navigation template has:
Template:AvoinGLAM/Main navigation ← Source (with <translate> tags)
Template:AvoinGLAM/Main navigation/en ← English
Template:AvoinGLAM/Main navigation/fi ← Finnish
Template:AvoinGLAM/Main navigation/ko ← Korean
Template:AvoinGLAM/Main navigation/ar ← Arabic
Template:AvoinGLAM/Main navigation/zh ← Chinese
fi → en)This is why Special:MyLanguage/ is important — it triggers this fallback chain.
Do NOT manually create language subpages. They are created and managed by the Translate extension's page translation system. Editing them directly is possible but will be overwritten the next time a translator updates through the interface.
<tvar>)<tvar> variables let you embed non-translatable content inside a translation unit while keeping the surrounding text translatable.
<translate><!--T:40-->
Welcome to <tvar name="project">{{SITENAME}}</tvar>.
Our website is at <tvar name="url">https://example.org</tvar>.
</translate>
In the translation interface, translators see:
Welcome to $project. Our website is at $url.
They translate the sentence but the $project and $url placeholders stay intact.
<tvar>| Use | Example |
|---|---|
| Magic words | <tvar name="year">{{CURRENTYEAR}}</tvar> |
| Template calls | <tvar name="count">{{PAGESINCATEGORY:Events}}</tvar> |
| URLs | <tvar name="link">https://example.com</tvar> |
| Numbers/statistics | <tvar name="members">42</tvar> |
| Special characters | <tvar name="arrow">→</tvar> |
| Formulas | <tvar name="formula">E=mc²</tvar> |
For template labels that include parameters:
<translate><!--T:50-->
Join the <tvar name="group">{{{groupname|}}}</tvar> community.
</translate>
<tvar>name="project" not name="1" — so translators understand what they represent<tvar> inside links — use the link text approach instead (see below)Special:MyLanguage/ — Language-Aware LinksSpecial:MyLanguage/ is a redirect page that follows the user's language preference.
[[Special:MyLanguage/AvoinGLAM/Past activities|Past activities]]
fi)AvoinGLAM/Past activities/fi if that translation existsWithout Special:MyLanguage/, a Finnish reader clicking "Past activities" would always go to the English page. With it, they land on the Finnish translation if available.
* [[Special:MyLanguage/AvoinGLAM|<translate><!--T:1--> AvoinGLAM</translate>]]
* [[Special:MyLanguage/AvoinGLAM/{{CURRENTYEAR}}|<translate><!--T:2--> This year</translate>]]
[[w:en:Page|Page]]Special:MyLanguage/ doesn't work with category syntax#timef — Locale-Aware Date Formatting#timef is a parser function provided by the Translate extension that formats dates according to the user's interface language.
{{#timef:2024-05-06|date}}
| User Language | Output |
|---|---|
| en (English) | 6 May 2024 |
| fi (Finnish) | 6. toukokuuta 2024 |
| fr (French) | 6 mai 2024 |
| de (German) | 6. Mai 2024 |
| ar (Arabic) | ٦ مايو ٢٠٢٤ |
| ko (Korean) | 2024년 5월 6일 |
| Format | Example (English) | Example (Finnish) |
|---|---|---|
date | 6 May 2024 | 6. toukokuuta 2024 |
time | 14:30 | 14:30 |
both | 6 May 2024 14:30 | 6. toukokuuta 2024 14:30 |
dmy | 6 May 2024 | 6. toukokuuta 2024 |
mdy | May 6, 2024 | toukokuuta 6, 2024 |
ymd | 2024 May 6 | 2024 toukokuuta 6 |
iso | 2024-05-06 | 2024-05-06 (iso is always the same) |
#timef with Date RangesIn the AvoinGLAM navigation template, #timef is used to display date ranges:
{{#timef:{{{startdate|}}}|date}}
{{#if: {{{enddate|}}}|–{{#timef:{{{enddate|}}}|date}}}}
This produces:
6 May 2024 – 7 May 20246. toukokuuta 2024 – 7. toukokuuta 2024{{{location|}}} {{#timef:{{{startdate|}}}|date}}
{{#if: {{{starttime|}}}|• {{{starttime|}}}
}}{{#if: {{{enddate|}}}|–
}}{{#if: {{{enddate|}}}|
{{#timef:{{{enddate|}}}|date}}
}}{{#if: {{{endtime|}}}|{{{endtime|}}}
}} {{{timezone|}}}
#timef Only Works on Translatable Pages#timef formats dates based on the language of the (translatable) page that contains it. On non-translatable pages, it falls back to #time behavior. This means:
#timef calls on non-translatable pages#dateformat#dateformat is another parser function from the Translate extension that formats dates according to the wiki's content language:
{{#dateformat:2024-05-06|dmy}}
This is less commonly used than #timef because it doesn't adapt to the user's language.
{{#language:...}}The #language parser function returns the language name in a given language:
{{#language:fi}} → "suomi" (in Finnish context)
{{#language:fi|en}} → "Finnish" (in English context)
{{#language:fr|en}} → "French"
Templates can be made translatable so that their labels, navigation text, and UI strings appear in the user's language.
<translate><noinclude><languages /></noinclude>
<templatestyles src="Project/style.css" />
<div class="menu">
* [[Special:MyLanguage/AvoinGLAM|<translate><!--T:1--> AvoinGLAM</translate>]]
* [[Special:MyLanguage/AvoinGLAM/{{CURRENTYEAR}}|<translate><!--T:2--> This year</translate>]]
* [[Special:MyLanguage/AvoinGLAM/Past activities|<translate><!--T:4--> Past activities</translate>]]
</div>
When a template parameter expects a label, you can provide it inline:
{{Project/Box
| title = <translate><!--T:5--> Join our community</translate>
| intro = <translate><!--T:6--> We invite you to participate.</translate>
}}
Or use parameters with defaults:
{{Project/Box
| title = <translate><!--T:5--> Join our community</translate>
| intro = {{{intro|<translate><!--T:6--> We invite you to participate.</translate>}}}
}}
For complex projects, create a dedicated string template:
<!-- Template:Project/Labels -->
<translate>
<!--T:1--> AvoinGLAM
<!--T:2--> This year
<!--T:4--> Past activities
</translate>
And reference it in your navigation template:
{{#if: {{{show_join|}}}
| [[Special:MyLanguage/Project/Join|{{Project/Labels|join}}]]
}}
<translate><!-- ❌ WRONG: Wrapping the entire template call -->
<translate>{{Project/Navigation}}</translate>
<!-- ✅ RIGHT: Only wrap the labels inside the template -->
{{Project/Navigation|title=<translate><!--T:1--> Welcome</translate>}}
{{TRANSLATABLEPAGE}} Magic Word{{TRANSLATABLEPAGE}} returns the title of the translatable page that contains it. It is useful in templates that are transcluded on translatable pages.
{{fullurl:{{TRANSLATABLEPAGE}}|veaction=edit}}
This generates an edit link for the translatable page, regardless of whether the current view is /en, /fi, or the base page.
<span class="editbutton">
[[File:OOjs UI icon edit-ltr.svg|12px|link=
{{fullurl:{{TRANSLATABLEPAGE}}|veaction=edit}}
]]
</span>
This is used in the AvoinGLAM log entry template to ensure the edit button always targets the source page, not the translation variant.
If {{TRANSLATABLEPAGE}} is used on a non-translatable page, it returns nothing. Always wrap in a conditional:
{{#if: {{TRANSLATABLEPAGE}}
| [[File:edit.svg|link={{fullurl:{{TRANSLATABLEPAGE}}|action=edit}}]]
}}
<translate> tags<languages /> at the top<!--T:1-->) or skip them (the system auto-generates when the page is marked)Special:PageTranslation<translate> tags and shows each unitMain page: Help:Extension:Translate/Page translation administration
Special:TranslateSpecial:TranslateA message group is a collection of translation units. For page translation, one page = one message group. They can be organized into aggregate groups for larger projects:
AvoinGLAM (aggregate group)
├── AvoinGLAM (page group)
├── AvoinGLAM/Past activities (page group)
├── AvoinGLAM/Main navigation (page group)
└── AvoinGLAM/style.css (page group — CSS is NOT translatable)
The Translate extension uses translation memory (TM) to suggest translations:
| Feature | Description |
|---|---|
| Translation review | Translations can be marked as "reviewed" |
| Validation | Checks for missing variables, unbalanced tags |
| Pre-translation | Auto-fill from TM for high-match units |
| Consistency checks | Flags inconsistent translations of the same source text |
| Do | Don't |
|---|---|
| ✅ Write short, complete sentences | ❌ Write long paragraphs with multiple ideas |
✅ Use <!--T:N--> markers after each unit | ❌ Put everything in one giant <translate> block |
| ✅ Keep sentences self-contained | ❌ Use "As mentioned above" (direction is language-dependent) |
✅ Use <tvar> for numbers, URLs, magic words | ❌ Embed formatting in translated text |
✅ Use Special:MyLanguage/ for internal links | ❌ Hard-code language-specific links |
| Pattern | Best Practice |
|---|---|
| Navigation | Wrap menu labels in <translate>, use Special:MyLanguage/ for links |
| Infoboxes | Make label parameters translatable with defaults |
| Buttons | Keep button text short, wrap in <translate> |
| Dates | Use {{#timef:...}} not {{#time:...}} |
| Banners | Use <tvar> for dynamic content like attendee counts |
#timef for all dates — it costs nothing and improves UX for all languages| Problem | Likely Cause | Solution |
|---|---|---|
<languages /> bar not showing | Page hasn't been marked for translation | Request marking at Special:PageTranslation |
#timef not formatting dates | Page is not translatable or not in a translatable context | Ensure the page has <translate> tags and is marked |
Special:MyLanguage/ not working | No translation subpage exists for the target page | Create the translation or check the fallback |
| Template labels not translating | Labels not wrapped in <translate> | Add <translate> tags around labels |
| Translation units not updating | Source page was edited without updating the translation | Re-mark the page or ask an admin |
{{TRANSLATABLEPAGE}} returns nothing | Page is not translatable | Check that the page has been marked for translation |
Broken <tvar> in translation | Variable name doesn't match the source | Check for typos in name="..." |
| Language subpage shows source text | No translation exists yet | The system falls back to source when no translation is available |
# Check if a page is translatable and get its message group
curl -s "https://meta.wikimedia.org/w/api.php?action=query&prop=translationinfo&titles=AvoinGLAM/Past%20activities&format=json" \
-H "User-Agent: MyTool/1.0"
# List available translations for a page
curl -s "https://meta.wikimedia.org/w/api.php?action=query&prop=langlinks&titles=AvoinGLAM/Past%20activities&format=json" \
-H "User-Agent: MyTool/1.0"
| Resource | URL |
|---|---|
| Translate extension page | mediawiki.org/wiki/Extension:Translate |
| Help:Extension:Translate | mediawiki.org/wiki/Help:Extension:Translate |
| Page translation administration | mediawiki.org/wiki/Help:Extension:Translate/Page_translation_administration |
| Translation best practices | mediawiki.org/wiki/Help:Extension:Translate/Translation_best_practices |
| Unstructured element translation | mediawiki.org/wiki/Help:Extension:Translate/Unstructured_element_translation |
Special:MyLanguage | mediawiki.org/wiki/Help:Special_MyLanguage |
#timef parser function | mediawiki.org/wiki/Help:Extension:Translate/Page_translation_example |
| Translation API | mediawiki.org/wiki/Help:Extension:Translate/API |
| Special:Translate on Meta | meta.wikimedia.org/wiki/Special:Translate |
| Skill: Templates | wikipedia-templates |
| Skill: Navigation | mediawiki-page-navigation |
| Skill: Page styling | wikimedia-page-styling |
| Skill: API access | wikimedia-api-access |
This skill includes helper scripts, reference docs, and template code for working with translated pages.
scripts/translation-status.sh)Check the translation status of a translatable page — available languages, completion percentages, and fuzzy (outdated) units:
# Show translation status for a page
./scripts/translation-status.sh "AvoinGLAM/Past activities" --wiki meta
# Show all languages with completion percentages
./scripts/translation-status.sh "AvoinGLAM" --languages
# Show only incomplete translations
./scripts/translation-status.sh "Project/Page" --incomplete
scripts/extract-translatable-strings.sh)Extract all <translate> sections and their translation unit IDs from a page or template:
# Show all translatable strings with their T: markers
./scripts/extract-translatable-strings.sh "AvoinGLAM/Main navigation" --wiki meta
# Show just the string IDs and their source text (no markup)
./scripts/extract-translatable-strings.sh "Template:Project/Navigation" --ids
# Show tvar variables used
./scripts/extract-translatable-strings.sh "Template:Project/Banner" --tvars
references/translate-parser-functions.md)Complete reference for Translate extension parser functions:
#timef — locale-aware date formatting (all format options, examples across 10+ languages)#dateformat — alternative date formatting#language — language name in any language#direction — text direction (ltr/rtl){{TRANSLATABLEPAGE}} — magic word for translatable page context{{TRANSLATIONLANGUAGE}} — the language of the current translationreferences/page-translation-workflow.md)Step-by-step guide for the complete translation workflow:
assets/translation_checker.py)Comprehensive translation analysis for a page — lists available languages, completion stats, fuzzy units, and identifies common issues:
# Full translation report
python3 assets/translation_checker.py "AvoinGLAM/Past activities" --wiki meta
# Show only outdated/fuzzy translations
python3 assets/translation_checker.py "Project/Page" --fuzzy
# Export translation status as JSON
python3 assets/translation_checker.py "Project/Page" --json
assets/template_translation_scanner.py)Scan templates for translation compliance — checks that labels use <translate>, links use Special:MyLanguage/, and dates use #timef:
# Check a template for translation best practices
python3 assets/template_translation_scanner.py "Template:AvoinGLAM/Main navigation" --wiki meta
# Check all templates in a project
python3 assets/template_translation_scanner.py --project "AvoinGLAM" --wiki meta
# Show compliance report
python3 assets/template_translation_scanner.py "Template:Project/Box" --report
tests/)Test scripts for verifying translation-related tooling:
# Run all translation tests
python3 -m pytest tests/
# Test #timef format detection
python3 -m pytest tests/test_timef.py
# Test Special:MyLanguage URL resolution
python3 -m pytest tests/test_mylanguage.py
# Test translatable string extraction
python3 -m pytest tests/test_extraction.py