Adding a language
This guide explains how to add support for a new language to Cobalt.
Backend
Make sure you start from the project root.
Create a new locale by initializing it with
pybabel:
make locales-init locale=deTIP
Short alias is also available: make l:i locale=de.
- Run the following commands to extract and update the translation strings:
make locales-generate
make locales-updateTIP
Short aliases are also available: make l:g, make l:u.
Add translations to the generated file at
cobalt/backend/infrastructure/locales/de/LC_MESSAGES/messages.po.Compile the translations:
make locales-compileTIP
Short alias is also available: make l:c.
- Add the new language to the
LanguageEnumin thecobalt/backend/domain/enums.pyfile:
class LanguageEnum(StrEnum):
"""
User language enum.
"""
EN = "en"
UK = "uk"
RU = "ru"
DE = "de"- Generate a new migration:
make alembic-revision name="Add de locale"TIP
Short alias is also available: make a:r name="Add de locale".
- Since
alembicdoes not track changes to enum values, you need to manually update the new migration file in thecobalt/backend/infrastructure/databases/postgres/migrations/versionsfolder:
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.execute("ALTER TYPE languageenum ADD VALUE IF NOT EXISTS 'DE'")
# ### end Alembic commands ###- Restart the backend container:
docker restart cobalt-backendFrontend
Make sure you start from the project root.
Create a new locale file in
cobalt/frontend/src/locales, e.g.de.json, using one of the existing locale files (en.json,uk.json,ru.json) as a template.Import the new locale file in the
cobalt/frontend/src/bootstrap.tsfile:
import de from "@/locales/de.json"- Add the new locale to
setupI18n:
function setupI18n() {
return createI18n<[MessageSchema], LanguageEnum>({
legacy: false,
locale: LanguageEnum.EN,
fallbackLocale: LanguageEnum.EN,
pluralRules: {
// ...
},
messages: { en, uk, ru, de }
})
}- Configure custom plural rules for the new language in
setupI18n, if its pluralization logic differs from the default:
pluralRules: {
[LanguageEnum.UK]: (n: number): number => {
if (n === 0) return 0
if (n % 10 === 1 && n % 100 !== 11) return 1
if (n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20)) return 2
return 3
},
[LanguageEnum.DE]: (n: number): number => {
return n === 1 ? 0 : 1
}
}TIP
If the language follows standard singular/plural rules (like English or German), you can skip this step entirely - vue-i18n's default pluralization will work out of the box.
- Add the new language to the
LanguageEnumtype in thecobalt/frontend/src/types/enums/language.tsfile:
export enum LanguageEnum {
EN = "en",
RU = "ru",
UK = "uk",
DE = "de",
}WARNING
Don't forget to add the settings.general.language.options.de translation key to all locale files, including the new one.