refactor: align files tab with content tab design (#5621)
* fix: files.vue bugs before styling changes * feat: move files tab to shared layout structure * fix: qa * fix: qa * fix: bugs * fix: lint * fix: admonition cleanup with progress + actions * fix: cleanup * fix: modals * fix: admon title * fix: i18n standard * fix: lint + i18n pass * fix: remove transition * fix: type errors * feat: files tab in app * fix: qa * fix: backup item minmax * fix: use ContentPageHeader for server panel * fix: lint * fix: lint * fix: lint * feat: page leave safety * fix: lint * fix: cargo fmt fix * fix: blank in prod * fix: content card table stuff * Revert "fix: blank in prod" This reverts commit 74758fe185cf85a4a20355857f889cb091b97ace. * fix: import * feat: browse worlds/servers flow * fix: worlds tab parity with content tab * fix: perf bug + shader filter pill copy * feat: singleplayer filter * fix: ordering * fix: breadcrumbs * fix: lint * fix: qa * feat: store server proj id when adding to a non-linked instance * fix: lint * fix: i18n + qa * fix: conflict * qa: already installed modal + placeholders not server-specific * fix: qa * fix: add + edit server modals * fix: qa * fix: security * fix: devin flags * fix: lint * chore: change file to break build cache * fix: admon * fix: import path stuff * feat: qa * fix: fmt fmt idiot --------- Signed-off-by: Calum H. <calum@modrinth.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
- [Message Definitions](#message-definitions)
|
||||
- [Rendering Messages](#rendering-messages)
|
||||
- [ICU Message Format](#icu-message-format)
|
||||
- [Writing Translation-Friendly Strings](#writing-translation-friendly-strings)
|
||||
- [Rich-Text Messages](#rich-text-messages)
|
||||
- [Vue/ICU Delimiter Collisions](#vueicu-delimiter-collisions)
|
||||
- [Imports](#imports)
|
||||
@@ -52,6 +53,36 @@ Dynamic values use ICU placeholders in `defaultMessage`:
|
||||
- **Numbers/dates/times:** `'{price, number, ::currency/USD}'`
|
||||
- **Plurals/selects:** `'{count, plural, one {# message} other {# messages}}'`
|
||||
|
||||
## Writing Translation-Friendly Strings
|
||||
|
||||
ICU gives you powerful tools (plurals, selects, nested expressions), but translators in other languages face constraints that English doesn't have:
|
||||
|
||||
- **Word order varies by language.** Don't assume `{action} {noun}` works everywhere — some languages need `{noun} {action}` or require prepositions between them.
|
||||
- **Plurals aren't just "add an s".** Many languages change internal parts of a word or phrase for pluralization, not just the ending. A simple `{count} {itemType}` breaks if `itemType` is always singular.
|
||||
- **Grammatical gender affects surrounding words.** Articles, adjectives, and verbs may change based on whether a noun is masculine or feminine. If a variable like `{contentType}` can be "shader" or "mod", translators may need to inflect surrounding text differently for each.
|
||||
|
||||
### Guidelines
|
||||
|
||||
1. **Use `select` for content types, not bare variables.** When a variable represents different content types (mod, shader, modpack, etc.), pass a key and use ICU `select` so translators can write type-specific forms:
|
||||
|
||||
```
|
||||
// Bad — translators can't inflect around a pre-rendered noun
|
||||
'Delete {count} {itemType}'
|
||||
|
||||
// Good — translators can write entirely different phrases per type
|
||||
'Delete {count} {contentType, select, mod {{count, plural, one {mod} other {mods}}} shader {{count, plural, one {shader} other {shaders}}} other {items}}'
|
||||
```
|
||||
|
||||
This lets translators write entirely different noun forms per branch, which many languages require.
|
||||
|
||||
2. **Prefer separate messages over complex ICU when branches diverge significantly.** If the singular and plural versions of a string are structurally different (not just a noun change), use two separate message IDs rather than one complex ICU expression.
|
||||
|
||||
3. **Don't concatenate translated strings.** Never build a sentence by joining multiple `formatMessage` calls — the word order may be wrong in other languages. Put the entire sentence in one message.
|
||||
|
||||
4. **Keep variables semantic.** Pass `contentType: 'mod'` (a key), not `contentType: 'Mod'` (a pre-rendered display string). Translators can then map each key to the correct form in their language.
|
||||
|
||||
5. **Test with long strings.** German and Finnish words can be 2-3x longer than English equivalents. Ensure UI layouts don't break with longer text.
|
||||
|
||||
## Rich-Text Messages
|
||||
|
||||
When a message contains links or markup, wrap the relevant ranges with named tags in `defaultMessage`:
|
||||
|
||||
Reference in New Issue
Block a user