-
Notifications
You must be signed in to change notification settings - Fork 1
Translation
Grafida's interface is translated into several languages, and adding another needs no code change at all. This page describes how the translations are put together, the glossaries that keep them consistent, and how to add a new language or improve an existing one.
The languages shipped today are English (United Kingdom) — the source — plus Greek, French, German, Spanish, Italian and Portuguese (Portugal).
Note
This applies to the interface: menus, buttons, labels and messages. The documentation you are reading is English only, deliberately — it is a single source shared with the project's GitHub wiki, which has a flat page namespace with nowhere to put a translated set.
Each language is a single INI file in its own directory, named after its BCP 47 tag:
language/
en-GB/en-GB.ini
de-DE/de-DE.ini
el-GR/el-GR.ini
…
The format is the Joomla INI format, so it will look familiar if you have translated a Joomla extension:
; A comment starts with a semicolon.
GRAFIDA_BTN_SAVE="Save"
GRAFIDA_MSG_DELETE_AI_TOOL_CONFIRM="Delete AI tool \"%s\"? This cannot be undone."The rules are few:
- One
KEY="Value"per line. The double quotes are not optional. - Keys are ASCII, upper case, and identical in every language. Never translate a key.
- A literal double quote inside a value is escaped as
\". - Files are UTF-8, without a byte-order mark.
-
%s,%1$s,%dand friends are placeholders and must survive translation. Where a string has more than one, the numbered form (%1$s,%2$s) lets you reorder them for your language's word order — that is exactly what it is there for.
Important
Never build a sentence by gluing fragments around a value. Grafida keeps each message as one string with placeholders in it, precisely so that a translator controls word order, punctuation and the position of the value. If you find a string that reads as half a sentence, that is a bug worth reporting.
Every language file must carry this key, holding the language's name in its own tongue:
GRAFIDA_LANGUAGE_ENDONYM="Français (France)"Grafida does not have a hard-coded list of languages. On startup it scans the language/ directory
for every <tag>/<tag>.ini and reads this key to label the entry in the Interface language
drop-down on the Settings screen. A file without it is not usable.
This is also why adding a language needs no code change and no manifest entry. There is no
.sys.ini, no XML manifest and no registration step: Grafida is a desktop application, not a
Joomla extension.
Lookups fall back in order: the chosen language → en-GB → the key itself. So a partial
translation is perfectly usable — untranslated strings simply appear in English — and a typo in a
key shows up loudly as a bare GRAFIDA_SOMETHING_OR_OTHER on screen.
The Interface language setting also has an (Auto-detect) option, which reads LC_ALL,
LC_MESSAGES or LANG from the environment. A bare language (fr) matches the first shipped tag
that starts with it (fr-FR).
Under build/glossaries/ there is one Markdown file per language, <tag>.md, holding a table of
the terms that must be translated the same way everywhere. Here's a short excerpt from the German glossary:
| Englisch (Quellbegriff) | Deutsch | Anmerkungen |
|---|---|---|
| article | Beitrag | Offizieller Joomla!-Begriff (JGLOBAL_ARTICLES = „Beiträge", nicht „Artikel") |
| tag | Schlagwörter | Offizieller Joomla!-Begriff (JTAG = „Schlagwörter"), nicht „Tag" |
These are not suggestions. They are the reason a term does not drift between two screens translated months apart, and the reason the vocabulary matches what the person at the keyboard already sees in their Joomla back end.
Important
The core terms were taken from the official Joomla translations, not invented. Where Grafida talks about something Joomla also talks about — article, category, tag, access level, featured, read more, intro image, full article image — the glossary records the term the official Joomla language pack uses, and cites the Joomla language key it came from.
The German example above is the point in miniature. Joomla's German pack renders article as Beitrag, not the literal Artikel, and tag as Schlagwort, not the loanword Tag. Someone editing a Joomla site in German reads "Beiträge" in the back end; Grafida saying anything else would be Grafida's own private dialect.
Where a term is Grafida's own — local article, slash commands, request log — the glossary records the decision and, often, why an earlier wording was dropped.
Proper nouns are never translated: Grafida, Joomla!, API, HTML, Markdown, TinyMCE.
The shipped translations were produced with the help of a large language model, checked against the glossary, and are maintained the same way. This is stated plainly rather than hidden: they are good enough to use, and they are not the work of a native-speaker translator who knows the application.
That has two consequences.
Corrections are genuinely welcome, especially from people who use Grafida in that language every day. A wording that is technically correct but nobody would actually say is a real bug; please report it.
Every correction belongs in the glossary too. If you change how a term is translated, change it
in build/glossaries/<tag>.md in the same breath, otherwise the next translation run — machine or
human — will helpfully change it back.
- Open
language/<tag>/<tag>.iniandbuild/glossaries/<tag>.mdside by side. - Make the change. If it involves a term rather than a one-off phrase, update the glossary row — or add one — including a short note saying why.
- Check that the placeholders in the value still match the English source exactly, in kind if not in order.
- Test it (below), then open a pull request.
If the string you are fixing is wrong because the English is wrong, say so: the English source is not sacred, and fixing it there fixes it for everybody.
- Copy
language/en-GB/en-GB.initolanguage/<tag>/<tag>.ini, using the BCP 47 tag for your language and region, e.g.nl-NL. - Set
GRAFIDA_LANGUAGE_ENDONYMto the language's name in its own tongue. - Create
build/glossaries/<tag>.mdand settle the core terms first, before translating the body of the file. Start from the official Joomla language pack for your language; a term that Joomla already translates should be translated the same way here. - Translate the values, leaving the keys alone.
- Test it (below).
- Open a pull request with both the INI file and the glossary.
That is the whole of it for the application itself. Two optional extras are worth knowing about:
The editor's own interface. TinyMCE ships its own language packs, and Grafida picks the one
matching your interface language. If a pack exists for your language, adding it needs two small
code changes: the pack's file name in the tinymce-i18n list in composer.json, and an entry in
TINYMCE_LANGS in assets/private/js/app.js mapping your tag to the pack's code. Without them the
editor's own menus stay English while the rest of Grafida is translated — which works, and is what
happens for any language TinyMCE has no pack for.
The spell checker is not ours to translate. It is your operating system's, and the dictionary it uses is an OS setting — see Editing Articles.
The straightforward way. Grafida reads language/ straight out of the project tree, so your file is
picked up as soon as you restart the application. Choose it under Interface language in
Settings, or leave the setting on (Auto-detect) and start Grafida with the environment
variable set:
LANG=nl-NL.UTF-8 php index.phpA compiled Grafida keeps its language files inside the binary and extracts them once, on first run,
into a resources/language/ folder under its data directory:
| Platform | Data directory |
|---|---|
| macOS | ~/Library/Application Support/Grafida/ |
| Windows | %APPDATA%\Grafida\ |
| Linux |
$XDG_DATA_HOME/grafida/ (usually ~/.local/share/grafida/) |
Dropping a new <tag>/<tag>.ini into resources/language/ there works: Grafida never deletes
files it did not put there, so your language is discovered on the next start and appears in the
drop-down. This is the quickest way to try a translation without building anything.
Warning
Editing one of the shipped files in that extracted folder is not reliable. On every start Grafida re-copies any bundled file whose extracted copy differs in size from the one inside the binary, so your edits will usually be overwritten — silently, and only sometimes, which is worse than always. Edit a source checkout instead, or test your change as a new tag.
- Every screen, not just the obvious ones: the Sites and Articles lists, the editor's properties sidebar, Settings, the confirmation dialogs, and the toast messages that appear after an action.
- Text that no longer fits. German and Greek in particular run considerably longer than English. Collapse the sidebars, and check the article rows, which change layout at a set width.
- Sentences with a value dropped into them — a deletion confirmation naming an article, the "Created:" / "Modified:" pair on an article row — read correctly with a real value in place.
- A stray
GRAFIDA_…key on screen, which means a missing or misspelt key.
Open a pull request on the project's GitHub repository, or raise it on the Discussions page if you would rather not use git. Please include the glossary change alongside the language file; see Community and help.
Grafida is free software under the GNU GPL v3 or later. Joomla!® is a registered trademark of Open Source Matters, Inc. Grafida is not affiliated with or endorsed by the Joomla! Project or Open Source Matters, Inc.
This wiki is generated from docs/ in the main repository. Edits made here are overwritten; please open a pull request against those files instead.