Skip to content

Commit

Permalink
Update Nuxt i18n
Browse files Browse the repository at this point in the history
  • Loading branch information
obulat committed Nov 25, 2024
1 parent 380eb31 commit d2c3fea
Show file tree
Hide file tree
Showing 51 changed files with 762 additions and 477 deletions.
6 changes: 1 addition & 5 deletions .codespell/ignore_lines.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
;; The release-drafter/release-drafter configuration variable name cannot be changed
commitish: main

;; frontend/src/locales/scripts/en.json5
;; frontend/i18n/data/en.json5
;; Prettier insists we escape a single quote rather than the double quotes and codespell
;; does not understand the escaped `\'t` as "couldn't". It instead just sees "couldn".
heading: 'We couldn\'t find anything for "{query}".',
Expand All @@ -16,7 +16,3 @@
;; block of Dutch text.
"Identificatie Titel(s): Allegorie op kunstenaar Francesco Mazzoli, "
"bekend als Parmigianino"

;; packages/js/eslint-plugin/configs/vue.ts
;; `te` gets matched with `the` and others
const i18nDestructureRules = ["t", "tc", "te", "td", "d", "n"].map(
2 changes: 1 addition & 1 deletion .github/workflows/generate_pot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
# The workflow will only run when both filters are satisfied.
paths:
- frontend/src/locales/scripts/en.json5
- frontend/i18n/data/en.json5
branches:
- main

Expand Down
10 changes: 10 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ coverage
*.pot

# Downloaded translation files
i18n/locales/openverse.zip
i18n/locales/*.json
i18n/locales/scripts/valid-locales.json
i18n/locales/scripts/untranslated-locales.json
i18n/locales/scripts/invalid-locales.json
i18n/locales/scripts/wp-locales.json
i18n/data/valid-locales.json
i18n/data/untranslated-locales.json
i18n/locales/scripts/*.json
# The old downloaded translation files. Can be deleted after the i18n folder changes are merged
src/locales/openverse.zip
src/locales/*.json
src/locales/scripts/valid-locales.json
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,13 @@
"es-ec": ["es"],
"es-mx": ["es"],
"es-ve": ["es"],
"en-au": ["en"],
"en-ca": ["en"],
"en-gb": ["en"],
"en-za": ["en"],
"fa": ["fa-af"],
"fr-be": ["fr"],
"fr-ca": ["fr"],
"pt": ["pt-br"],
"default": ["en"]
}
5 changes: 5 additions & 0 deletions frontend/i18n/locales/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Locales

The primary internationalisation file is [`data/en.json5`](../data/en.json5).
All `.json` files present in this directory are re-generated when updating
translations, so they should not be modified.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const axios = require("axios")

const { userAgent } = require("../../constants/user-agent")
const { userAgent } = require("../../../src/constants/user-agent")

module.exports = module.exports = axios.create({
headers: { "User-Agent": userAgent },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const fetchBulkJed1x = async () => {
params: { "export-format": "jed1x" },
responseType: "stream",
})
const destPath = process.cwd() + "/src/locales/openverse.zip"
const destPath = process.cwd() + "/i18n/locales/openverse.zip"
await pipeline(res.data, createWriteStream(destPath))
return destPath
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ async function getWpLocaleData() {
getWpLocaleData()
.then((data) => {
try {
const fileName = process.cwd() + "/src/locales/scripts/wp-locales.json"
const fileName = process.cwd() + "/i18n/locales/scripts/wp-locales.json"
fs.writeFileSync(fileName, JSON.stringify(data, null, 2) + "\n")
console.log(`Successfully wrote locales list file to ${fileName}`)
} catch (err) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const { parseJson } = require("./read-i18n")
const writeEnglish = () => {
const rootEntry = parseJson("en.json5")
writeFileSync(
process.cwd() + "/src/locales/en.json",
process.cwd() + "/i18n/locales/en.json",
JSON.stringify(rootEntry, null, 2) + os.EOL
)
console.log("Successfully saved English translation to en.json.")
Expand All @@ -26,7 +26,7 @@ writeEnglish()
if (process.argv.includes("--watch")) {
console.log("Watching en.json5 for changes...")
chokidar
.watch(process.cwd() + "/src/locales/scripts/en.json5")
.watch(process.cwd() + "/i18n/data/en.json5")
.on("all", (event, path) => {
console.log(`Event '${event}' for file ${path}`)
writeEnglish()
Expand All @@ -46,7 +46,7 @@ if (!process.argv.includes("--en-only")) {
} else {
// Create valid-locales.json if it doesn't exist. It is required for Nuxt to build the app.
const validLocalesFilePath =
process.cwd() + "/src/locales/scripts/valid-locales.json"
process.cwd() + "/i18n/locales/scripts/valid-locales.json"
if (!existsSync(validLocalesFilePath)) {
writeFileSync(validLocalesFilePath, "[]")
console.log("Created empty valid-locales.json.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const getValidatedLocales = async () => {
translated: locale.translated,
}))
for (const locale of allLocales) {
const fileLocation = `${process.cwd()}/src/locales/${locale.file}`
const fileLocation = `${process.cwd()}/i18n/locales/${locale.file}`
if (fs.existsSync(fileLocation)) {
if (Object.keys(JSON.parse(fs.readFileSync(fileLocation))).length) {
result.translated.push(locale)
Expand All @@ -59,7 +59,7 @@ try {
const fileName = "valid-locales.json"
const valid = locales.translated
fs.writeFileSync(
process.cwd() + `/src/locales/scripts/` + fileName,
process.cwd() + `/i18n/locales/scripts/` + fileName,
JSON.stringify(valid, null, 2) + "\n"
)

Expand All @@ -68,14 +68,14 @@ try {
)
const untranslatedFileName = "untranslated-locales.json"
fs.writeFileSync(
process.cwd() + `/src/locales/scripts/` + untranslatedFileName,
process.cwd() + `/i18n/locales/scripts/` + untranslatedFileName,
JSON.stringify(locales.untranslated, null, 2) + "\n"
)

console.log(`Found ${locales.invalid.length} invalid locales.`)
const invalidFileName = "invalid-locales.json"
fs.writeFileSync(
process.cwd() + `/src/locales/scripts/` + invalidFileName,
process.cwd() + `/i18n/locales/scripts/` + invalidFileName,
JSON.stringify(locales.invalid, null, 2) + "\n"
)

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ const path = require("path")

const glob = require("glob")

const BASE_PATH = path.dirname(path.dirname(__dirname))
const BASE_PATH = path.join(
path.dirname(path.dirname(path.dirname(__dirname))),
"src"
)

function readVueFiles(src) {
const targetFiles = glob.sync(src)

if (targetFiles.length === 0) {
throw new Error("vueFiles glob has no files.")
}
// Now that the script are inside `src/locales/scripts`,
// to get relative URL, the script needs to go up 3 levels
// Now that the script are inside `i18n/locales/scripts`,
// to get relative URL, the script needs to go up 4 levels
return targetFiles.map((f) => {
const fileName = path.relative(process.cwd(), f.replace(BASE_PATH, "src"))
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,10 @@ const parseObjProperty = (node) => {
const parseJson = (filename) =>
parseObjProperty({
value: babel.parseExpression(
fs.readFileSync(path.join(__dirname, filename), "utf-8")
fs.readFileSync(
path.join(__dirname, "..", "..", "data", filename),
"utf-8"
)
),
})

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ exports.writeLocaleFile = (locale, rawTranslations, deprecatedKeys) => {
)

return writeFile(
process.cwd() + `/src/locales/${locale}.json`,
process.cwd() + `/i18n/locales/${locale}.json`,
JSON.stringify(translations, null, 2) + os.EOL
)
}
173 changes: 173 additions & 0 deletions frontend/i18n/vue-i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import { defineI18nConfig } from "#imports"

import localeFallback from "./locale-fallback.json"

import type { Locale } from "@intlify/core-base"

const custom5Rule = (n: number): number =>
n == 0
? 0
: n == 1
? 1
: n == 2
? 2
: n % 100 >= 3 && n % 100 <= 10
? 3
: n % 100 >= 11 && n % 100 <= 99
? 4
: 5

export default defineI18nConfig(() => ({
legacy: false,
globalInjection: true,
fallbackLocale: localeFallback as { [x: string]: Locale[] },
silentFallbackWarn: true,
pluralizationRules: {
ar: custom5Rule,
arq: custom5Rule,
ary: custom5Rule,
bel: (n: number): number =>
n % 10 == 1 && n % 100 != 11
? 0
: n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)
? 1
: 2,
bs: (n: number): number =>
n % 10 == 1 && n % 100 != 11
? 0
: n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)
? 1
: 2,
cor: (n: number): number =>
n == 0
? 0
: n == 1
? 1
: n % 100 == 2 ||
n % 100 == 22 ||
n % 100 == 42 ||
n % 100 == 62 ||
n % 100 == 82 ||
(n % 1000 == 0 &&
((n % 100000 >= 1000 && n % 100000 <= 20000) ||
n % 100000 == 40000 ||
n % 100000 == 60000 ||
n % 100000 == 80000)) ||
(n != 0 && n % 1000000 == 100000)
? 2
: n % 100 == 3 ||
n % 100 == 23 ||
n % 100 == 43 ||
n % 100 == 63 ||
n % 100 == 83
? 3
: n != 1 &&
(n % 100 == 1 ||
n % 100 == 21 ||
n % 100 == 41 ||
n % 100 == 61 ||
n % 100 == 81)
? 4
: 5,
cs: (n: number): number => (n == 1 ? 0 : n >= 2 && n <= 4 ? 1 : 2),
cy: (n: number): number =>
n == 1 ? 0 : n == 2 ? 1 : n != 8 && n != 11 ? 2 : 3,
dsb: (n: number): number =>
n % 100 == 1
? 0
: n % 100 == 2
? 1
: n % 100 == 3 || n % 100 == 4
? 2
: 3,
ga: (n: number): number =>
n == 1
? 0
: n == 2
? 1
: n >= 3 && n <= 6
? 2
: n >= 7 && n <= 10
? 3
: 4,
gd: (n: number): number =>
n == 1 || n == 11
? 0
: n == 2 || n == 12
? 1
: (n >= 3 && n <= 10) || (n >= 13 && n <= 19)
? 2
: 3,
hr: (n: number): number =>
n % 10 == 1 && n % 100 != 11
? 0
: n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)
? 1
: 2,
hsb: (n: number): number =>
n % 100 == 1
? 0
: n % 100 == 2
? 1
: n % 100 == 3 || n % 100 == 4
? 2
: 3,
is: (n: number): number => (n % 10 != 1 || n % 100 == 11 ? 1 : 0),
lt: (n: number): number =>
n % 10 == 1 && (n % 100 < 11 || n % 100 > 19)
? 0
: n % 10 >= 2 && n % 10 <= 9 && (n % 100 < 11 || n % 100 > 19)
? 1
: 2,
lv: (n: number): number =>
n % 10 == 0 || (n % 100 >= 11 && n % 100 <= 19)
? 0
: n % 10 == 1 && n % 100 != 11
? 1
: 2,
me: (n: number): number =>
n % 10 == 1 && n % 100 != 11
? 0
: n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20)
? 1
: 2,
mk: (n: number): number => (n % 10 != 1 || n % 100 == 11 ? 1 : 0),
pl: (n: number): number =>
n == 1
? 0
: n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)
? 1
: 2,
ro: (n: number): number =>
n == 1 ? 0 : n == 0 || (n % 100 >= 2 && n % 100 <= 19) ? 1 : 2,
ru: (n: number): number =>
n % 10 == 1 && n % 100 != 11
? 0
: n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)
? 1
: 2,
sk: (n: number): number => (n == 1 ? 0 : n >= 2 && n <= 4 ? 1 : 2),
sl: (n: number): number =>
n % 100 == 1
? 0
: n % 100 == 2
? 1
: n % 100 == 3 || n % 100 == 4
? 2
: 3,
sr: (n: number): number =>
n % 10 == 1 && n % 100 != 11
? 0
: n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)
? 1
: 2,
szl: (n: number): number =>
n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && n % 100 == 20 ? 1 : 2,
uk: (n: number): number =>
n % 10 == 1 && n % 100 != 11
? 0
: n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)
? 1
: 2,
},
}))
4 changes: 2 additions & 2 deletions frontend/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineNuxtConfig } from "nuxt/config"

import { disallowedBots } from "./src/constants/disallowed-bots"
import locales from "./src/locales/scripts/valid-locales.json"
import locales from "./i18n/locales/scripts/valid-locales.json"

import type { LocaleObject } from "@nuxtjs/i18n"

Expand Down Expand Up @@ -124,6 +124,6 @@ export default defineNuxtConfig({
* */
detectBrowserLanguage: false,
trailingSlash: false,
vueI18n: "./src/vue-i18n",
vueI18n: "./vue-i18n",
},
})
Loading

0 comments on commit d2c3fea

Please sign in to comment.