Skip to content

Add an Italian locale, and spell two error headings one way - #188

Merged
Jaggob merged 2 commits into
mainfrom
chore/l10n-italian
Aug 9, 2026
Merged

Add an Italian locale, and spell two error headings one way#188
Jaggob merged 2 commits into
mainfrom
chore/l10n-italian

Conversation

@Jaggob

@Jaggob Jaggob commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Two catalog changes, one commit each.

Spell the two error headings one way. Could not open pad and Could not create pad each existed twice, once with a trailing full stop and once without – the embed page uses them as headings, the controllers as messages. Two keys for one sentence, and every translator had to write both. Settled on the form without the stop, which reads as either. 180 → 178 keys in de, es and fr.

The messages that name what failed stay as they are. Which step could not find a file is not something a user can act on, but which action failed is – that distinction is the reason for the separate wordings.

Add an Italian locale. it joins de, es and fr with the same 178 keys, written and reviewed by a native speaker with a working knowledge of the app.

Verified: it.json and it.js character-for-character identical, key set identical to de, placeholder parity ({domain}, {url}, {{date}}, …) checked against the source string in all 178 entries, no empty values, plural form nplurals=2; plural=(n != 1);. npm run build green, npm test 148/148.

No behaviour change – catalogs and one doc file only.

Jaggob added 2 commits August 9, 2026 11:12
"Could not open pad" and "Could not create pad" each existed twice, once
with a trailing full stop and once without, because the embed page uses them
as headings and the controllers as messages. Two keys, one sentence, and a
translator had to write both. Settled on the form without the stop, which
reads as either.

The messages that name what failed stay as they are. Which step could not
find a file is not information a user can act on, but which action failed
is — that distinction is the reason for the wording, so it keeps its own
strings.

180 → 178 keys in de, es and fr.
Italian joins de, es and fr as a maintained locale, with the same 178
keys as the other catalogs, written and reviewed by a native speaker
with a working knowledge of the app.

Three terms were settled across the whole catalog: "nome dell'host"
for hostname, "parent domain" left untranslated, and the app's own
picker tiles called "modelli propri dell'app" – Nextcloud's own Italian
Files strings call everything in that picker a "modello" and have no
word for a tile.
@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Add Italian locale and consolidate pad open/create error translation keys

✨ Enhancement 📝 Documentation 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Consolidate duplicated “Could not open/create pad” strings by removing trailing full stops.
• Add maintained Italian (it) translation catalogs with full key/placeholder parity.
• Update docs and tests to reflect the new locale and canonicalized messages.
Diagram

graph TD
  C["PHP controllers"] --> L["L10N service"] --> Cat[("Locale catalogs")]
  E["Embed JS"] --> L
  T["Unit tests"] --> C
  T --> E
  D["i18n docs"] -."maintenance rules".-> Cat
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Keep period-suffixed keys and strip punctuation in headings
  • ➕ Avoids any visible message text change in sentence contexts
  • ➕ Keeps translations closer to full-sentence punctuation conventions
  • ➖ Couples UI rendering to string content/punctuation rules
  • ➖ Still leaves duplicated keys (or requires special-casing) and extra translator work
2. Introduce stable identifier keys (vs source-string keys)
  • ➕ Prevents future key churn from punctuation/copy edits
  • ➕ Allows separate heading/message variants without duplicate English strings
  • ➖ Often not supported by the surrounding Nextcloud l10n conventions/tooling
  • ➖ Requires broad refactor across codebase and translation workflow

Recommendation: Proceed with the PR’s approach: pick a single canonical key form (“Could not open/create pad” without a trailing full stop) and update both catalogs and call sites. It minimizes translator burden, avoids UI punctuation hacks, and keeps behavior effectively unchanged aside from trivial punctuation removal.

Files changed (18) +383 / -26

Enhancement (2) +367 / -0
it.jsAdd Italian JS translation catalog (178 keys) +184/-0

Add Italian JS translation catalog (178 keys)

• Introduces a complete Italian 'OC.L10N.register(...)' catalog with the full maintained key set, including the canonical periodless “Could not open/create pad” entries. Defines plural rules for Italian ('nplurals=2; plural=(n != 1);').

l10n/it.js

it.jsonAdd Italian JSON translation catalog matching it.js +183/-0

Add Italian JSON translation catalog matching it.js

• Adds the Italian JSON catalog with the same translations and plural form as 'it.js' to satisfy the repository’s dual-format rule. Key set and placeholders are aligned to other maintained locales.

l10n/it.json

Refactor (11) +7 / -19
de.jsDrop period-suffixed duplicates for pad open/create headings +0/-2

Drop period-suffixed duplicates for pad open/create headings

• Removes the duplicate translation entries for “Could not open pad.” and “Could not create pad.”, keeping the periodless forms as the canonical keys. Keeps the rest of the German catalog unchanged.

l10n/de.js

de.jsonMirror de.js key consolidation in JSON catalog +0/-2

Mirror de.js key consolidation in JSON catalog

• Removes the same two period-suffixed duplicate keys from the German JSON catalog to maintain '.json'/'.js' parity. Ensures the remaining canonical keys are unchanged.

l10n/de.json

es.jsDrop period-suffixed duplicates for pad open/create headings +0/-2

Drop period-suffixed duplicates for pad open/create headings

• Removes the Spanish translations for the period-suffixed duplicate keys, keeping the periodless forms. Aligns the Spanish catalog with the canonical key set.

l10n/es.js

es.jsonMirror es.js key consolidation in JSON catalog +0/-2

Mirror es.js key consolidation in JSON catalog

• Removes “Could not open pad.” and “Could not create pad.” from the Spanish JSON catalog to match the JS catalog. Preserves all remaining translations.

l10n/es.json

fr.jsDrop period-suffixed duplicates for pad open/create headings +0/-2

Drop period-suffixed duplicates for pad open/create headings

• Removes the French translations for the two period-suffixed duplicate keys. Leaves the periodless forms as the single source for both heading and message use cases.

l10n/fr.js

fr.jsonMirror fr.js key consolidation in JSON catalog +0/-2

Mirror fr.js key consolidation in JSON catalog

• Removes the same two duplicate keys from the French JSON catalog to keep catalogs consistent. No other key/value changes are introduced.

l10n/fr.json

EmbedControllerErrorMapper.phpUse canonical “Could not open pad” translation key +1/-1

Use canonical “Could not open pad” translation key

• Switches the embed error template mapping from the period-suffixed key to the periodless canonical key. This ensures a single translation entry is used for headings/messages.

lib/Controller/EmbedControllerErrorMapper.php

PadCreateController.phpUse canonical “Could not create pad” translation key +2/-2

Use canonical “Could not create pad” translation key

• Updates both create endpoints’ generic failure messages to use “Could not create pad” (no trailing full stop). Keeps all other error mapping behavior unchanged.

lib/Controller/PadCreateController.php

PadSessionController.phpUse canonical “Could not open pad” translation key +2/-2

Use canonical “Could not open pad” translation key

• Updates generic open failures (by path and by file ID) to use the periodless canonical key. Aligns controller output with the consolidated catalogs.

lib/Controller/PadSessionController.php

PublicViewerControllerErrorMapper.phpMask unexpected viewer failures with canonical message +1/-1

Mask unexpected viewer failures with canonical message

• Changes the fallback masked message for unexpected public viewer errors to “Could not open pad” (no trailing full stop). Matches the canonical key and updated tests.

lib/Controller/PublicViewerControllerErrorMapper.php

ViewerControllerErrorMapper.phpUse canonical “Could not open pad” translation key +1/-1

Use canonical “Could not open pad” translation key

• Updates the generic viewer template error message to use the periodless canonical translation key. Keeps logging and error handling flow intact.

lib/Controller/ViewerControllerErrorMapper.php

Tests (4) +5 / -5
embed-create-main.test.jsUpdate embed create failure assertion to periodless message +1/-1

Update embed create failure assertion to periodless message

• Adjusts the mocked server error response payload to use “Could not create pad” without a full stop. Keeps the test intent (posting create-failed with server reason) the same.

tests/js/embed-create-main.test.js

EmbedControllerErrorMapperTest.phpAssert periodless generic embed open error message +1/-1

Assert periodless generic embed open error message

• Updates the expected template parameter 'error' string to match the new canonical “Could not open pad” message. Ensures the mapper test reflects the key consolidation.

tests/phpunit/unit/EmbedControllerErrorMapperTest.php

PublicViewerControllerErrorMapperTest.phpAssert periodless masked public viewer error messages +2/-2

Assert periodless masked public viewer error messages

• Updates both data and template paths to expect “Could not open pad” (no trailing full stop) when masking unexpected failures. Preserves HTTP status and other assertions.

tests/phpunit/unit/PublicViewerControllerErrorMapperTest.php

ViewerControllerErrorMapperTest.phpAssert periodless generic viewer template error message +1/-1

Assert periodless generic viewer template error message

• Updates the expected template parameter 'error' string to the canonical periodless form. Keeps the rest of the mapper behavior assertions unchanged.

tests/phpunit/unit/ViewerControllerErrorMapperTest.php

Documentation (1) +4 / -2
i18n.mdDocument 'it' as a maintained locale and review status +4/-2

Document 'it' as a maintained locale and review status

• Adds Italian ('it') to the maintained locale list and updates the maintenance rule to require key parity across 'de', 'es', 'fr', and 'it'. Notes which locales have native-speaker end-to-end review vs first-pass quality.

docs/i18n.md

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

@Jaggob
Jaggob merged commit f3025bc into main Aug 9, 2026
13 checks passed
@Jaggob
Jaggob deleted the chore/l10n-italian branch August 9, 2026 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant