I18N - add localization documentation in website

This commit is contained in:
Alex Sim committed 2026-09-03 23:28:48 +02:00
1 parent 6c318605e3
commit 392fd5c767
5 files changed
+313 -1

No files matched your search

+28 -1
View File
@@ -512,6 +512,33 @@ Optional Jetpack Compose support:
- Use string resources (no hardcoded strings)
- Support RTL (right-to-left) languages
- Test with different locales
- The app's own strings live in `res/values/strings_murine.xml`. The rest of
`res/values/strings.xml` is inherited from AOSP Launcher3 and translated upstream,
so only `strings_murine.xml` is ours to maintain
- **New strings start as English + Italian only.** When adding strings for a new feature,
write `res/values/strings_murine.xml` and `res/values-it/strings_murine.xml` and stop there.
The other languages are filled in later, in one pass, when the wording has settled and the
maintainer explicitly asks for it. Do not translate a feature's strings into every shipped
language unprompted
- **Read `docs/_data/languages.yml` before adding or changing any string.** It lists every
language currently shipped; each of them eventually needs the new string in its own
`res/values-<code>/strings_murine.xml`, and until then that language falls back to English
for the new text. Changing the *wording* of an existing string is different: update every
language that already has it, since a stale translation is worse than a missing one
- **Every translated file mirrors the base file's structure.** Same string order, same blank
lines between groups, same `<!-- section -->` comments in the same places. Never reorder or
alphabetize a translation: matching line positions are what makes a missing or stale string
obvious when diffing two languages side by side. New entries in `docs/_data/languages.yml`
follow the same rule, keeping the existing key order (`code`, `name`, `native`, `status`,
`strings`, `by_git`, `by`, `note`)
- **Keep `docs/_data/languages.yml` up to date.** Bump `total` when the base string count
changes, and update each language's `strings` count. It drives the public status page at
`/localization-status/`, so a stale file publishes wrong numbers
- When adding a new language, read **both** the English and the Italian strings first.
Italian is hand-written and frequently disambiguates wording that English leaves open
(grammatical gender, formal vs informal address, whether a short label is a noun or a verb),
which makes the new translation noticeably more accurate. Add the language to
`docs/_data/languages.yml` with `status: ai` unless a speaker has actually reviewed it
10. **Dependency Updates**:
- Update `gradle.properties` for version changes
@@ -547,7 +574,7 @@ Optional Jetpack Compose support:
1. Add to appropriate `res/` directory
2. Consider variant-specific resources (e.g., `quickstep/res/`)
3. Support different densities (drawable-mdpi, -hdpi, etc.)
4. Add translations for strings
4. Add translations for strings: English and Italian only for new features until otherwise requested (see **Localization** above)
### Debugging Tips
+6
View File
@@ -22,6 +22,12 @@ Alternatively, try enabling <a href="https://github.com/Magisk-Modules-Alt-Repo/
<img width="320" src="/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png"/> <img width="320" src="/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png"/>
<img width="320" src="/fastlane/metadata/android/en-US/images/phoneScreenshots/7.png"/>
## Translations
The launcher's own strings are translated separately from the locales it inherits from AOSP.
[See which languages are covered, how complete each one is, and how to help](https://www.murinelauncher.app/localization-status/)
## Download
Check [the website](https://www.murinelauncher.app/) or download it from:
+168
View File
@@ -0,0 +1,168 @@
# Translation status board (rendered by docs/localization-status.md).
#
# status: reviewed | mostly | partial | ai -> see the legend in localization-status.md
# strings: how many of the app's own strings (res/values-<code>/strings_murine.xml)
# are translated. Base count lives in `total` below.
# by_git: reviewer(s) with a GitHub account, rendered as links
# by: reviewer(s) without one, rendered as plain text
# both accept several names separated by ', ' and are shown together,
# in that order. Omit both if nobody has reviewed it
total: 143
languages:
- code: en
name: English
native: English
status: reviewed
strings: 143
by_git: alesimula
note: Source language
- code: it
name: Italian
native: Italiano
status: reviewed
strings: 143
by_git: alesimula
note: Dev's language
- code: es
name: Spanish
native: Español
status: mostly
strings: 143
by: EJDV
- code: de
name: German
native: Deutsch
status: ai
strings: 143
- code: fr
name: French
native: Français
status: ai
strings: 143
- code: pt
name: Portuguese
native: Português
status: ai
strings: 143
- code: ru
name: Russian
native: Русский
status: ai
strings: 143
- code: nl
name: Dutch
native: Nederlands
status: ai
strings: 143
- code: pl
name: Polish
native: Polski
status: ai
strings: 143
- code: tr
name: Turkish
native: Türkçe
status: ai
strings: 143
- code: uk
name: Ukrainian
native: Українська
status: ai
strings: 143
- code: ca
name: Catalan
native: Català
status: ai
strings: 143
- code: ja
name: Japanese
native: 日本語
status: ai
strings: 143
- code: ko
name: Korean
native: 한국어
status: ai
strings: 143
- code: ar
name: Arabic
native: العربية
status: ai
strings: 143
- code: fa
name: Persian
native: فارسی
status: ai
strings: 143
- code: iw
name: Hebrew
native: עברית
status: ai
strings: 143
- code: in
name: Indonesian
native: Bahasa Indonesia
status: ai
strings: 143
- code: vi
name: Vietnamese
native: Tiếng Việt
status: ai
strings: 143
- code: zh-rCN
name: Chinese (Simplified)
native: 简体中文
status: ai
strings: 143
- code: zh-rTW
name: Chinese (Traditional)
native: 繁體中文
status: ai
strings: 143
- code: hi
name: Hindi
native: हिन्दी
status: ai
strings: 143
- code: th
name: Thai
native: ไทย
status: ai
strings: 143
- code: tl
name: Filipino
native: Filipino
status: ai
strings: 143
- code: nb
name: Norwegian
native: Norsk bokmål
status: mostly
strings: 143
by_git: oddhap
+1
View File
@@ -11,6 +11,7 @@
<meta name="color-scheme" content="dark">
<meta name="supported-color-schemes" content="light dark">
<meta name="darkreader-lock">
{% if page.noindex %}<meta name="robots" content="noindex, nofollow">{% endif %}
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
+110
View File
@@ -0,0 +1,110 @@
---
layout: page
title: Localization status
subtitle: Shows the status of each translation
permalink: /localization-status/
sitemap: false # keep it out of sitemap.xml
noindex: true # and out of search engines
---
<style>
.lang-table { width: 100%; border-collapse: collapse; margin: 1.5rem 0; font-size: .95rem; }
.lang-table th, .lang-table td { padding: .7rem .8rem; text-align: left; border-bottom: 1px solid var(--md-outline-variant); }
.lang-table th { font-weight: 600; color: var(--md-on-surface-variant); font-size: .82rem;
text-transform: uppercase; letter-spacing: .04em; }
.lang-table tr:last-child td { border-bottom: none; }
.lang-table code { font-size: .85em; }
.lang-native { color: var(--md-on-surface-variant); }
.lang-link { text-decoration: none; }
.lang-link:hover strong { text-decoration: underline; }
.lang-status { white-space: nowrap; }
.lang-credits { max-width: 16ch; }
.lang-bar { display: block; height: 4px; border-radius: var(--md-shape-full);
background: var(--md-surface-container-highest); overflow: hidden; margin-top: .35rem; }
.lang-bar > span { display: block; height: 100%; background: var(--md-primary); }
.lang-legend { list-style: none; padding: 0; }
.lang-legend li { margin: .3rem 0; }
@media (max-width: 640px) { .lang-hide-sm { display: none; } }
</style>
The launcher's own strings live in `strings_murine.xml`. Everything inherited from
AOSP Launcher3 is translated upstream into 85 locales and is not tracked here.
<table class="lang-table">
<thead>
<tr>
<th>Language</th>
<th>Code</th>
<th>Strings</th>
<th>Status</th>
<th class="lang-hide-sm">Reviewed by</th>
</tr>
</thead>
<tbody>
{% for lang in site.data.languages.languages %}
{% assign pct = lang.strings | times: 100.0 | divided_by: site.data.languages.total %}
{% if lang.code == 'en' %}{% assign dir = 'values' %}{% else %}{% assign dir = 'values-' | append: lang.code %}{% endif %}
{% assign strings_url = 'https://github.com/' | append: site.github_repo | append: '/blob/main/res/' | append: dir | append: '/strings_murine.xml' %}
<tr>
<td>
<a href="{{ strings_url }}" class="lang-link">
<strong>{{ lang.name }}</strong>
{% if lang.native != lang.name %}<br><span class="lang-native">{{ lang.native }}</span>{% endif %}
</a>
</td>
<td>
<a href="{{ strings_url }}"><code>{{ lang.code }}</code></a>
</td>
<td>
{{ lang.strings }} / {{ site.data.languages.total }}
<span class="lang-bar"><span style="width: {{ pct }}%"></span></span>
</td>
<td class="lang-status">
{% case lang.status %}
{% when 'reviewed' %}✅ Fully reviewed
{% when 'mostly' %}🟢 Mostly reviewed
{% when 'partial' %}🟡 Partially reviewed
{% when 'ai' %}🤖 AI slop
{% else %}❔ Unknown
{% endcase %}
{% if lang.note %}<br><span class="lang-native">{{ lang.note }}</span>{% endif %}
</td>
<td class="lang-hide-sm">
{%- assign gits = lang.by_git | default: '' | split: ', ' -%}
{%- assign names = lang.by | default: '' | split: ', ' -%}
{%- capture credits -%}
{%- for g in gits -%}<a href="https://github.com/{{ g }}">{{ g }}</a>{%- unless forloop.last -%}, {% endunless -%}{%- endfor -%}
{%- if gits.size > 0 and names.size > 0 -%}, {% endif -%}
{%- for n in names -%}{{ n }}{%- unless forloop.last -%}, {% endunless -%}{%- endfor -%}
{%- endcapture -%}
{%- if credits == blank -%}<span class="lang-native">nobody yet</span>{%- else -%}<div class="lang-credits">{{ credits }}</div>{%- endif -%}
</td>
</tr>
{% endfor %}
</tbody>
</table>
## What the statuses mean
<ul class="lang-legend">
<li>✅ <strong>Fully reviewed</strong>: every string read by someone who speaks the language.</li>
<li>🟢 <strong>Mostly reviewed</strong>: was fully reviewed, then a few strings were added and
have not been checked yet.</li>
<li>🟡 <strong>Partially reviewed</strong>: some strings checked by a human, the rest machine-translated.</li>
<li>🤖 <strong>AI slop</strong>: machine-translated and nobody has read it yet; there may be some mistakes.</li>
</ul>
## Helping out
Click any language above to open its `strings_murine.xml`, then modify or create one and create
a pull request (or just send it to me).
That counts as a review in itself: going through the file to fix the awkward strings means
someone who speaks the language has read it, so it gets marked ✅ unless you say otherwise.
Fixing even a handful of strings is a perfectly good contribution.
Read through one and found nothing worth changing? That is still a review. Just
<a href="#contact" onclick="openContactModal(); return false;">contact me</a> saying which
language you checked and it gets marked accordingly, no pull request needed.
To add a language that is not listed, copy `res/values/strings_murine.xml` into a new
`res/values-<code>/` folder and translate it there.