diff --git a/README.md b/README.md index 5b51f42d..dee8d685 100644 --- a/README.md +++ b/README.md @@ -73,3 +73,29 @@ All commands are run from the root of the project, from a terminal: | `bun run preview` | Preview your build locally, before deploying | | `bun run astro ...` | Run CLI commands like `astro add`, `astro check` | | `bun run astro -- --help` | Get help using the Astro CLI | + +## Automatic i18n + +The website aims at having an automatic i18n done via various scripts in the `scripts` directory. + +The [translations.tsx](./scripts/translations.tsx) script is used to translate the website content into the desired language. It has two methods to create translations, via `OpenAI API`, and the other via `api.datpmt.com`. To use the OpenAI API method, make sure you have an `OPENAI_API_KEY` as the environment variable set. To use the other API, just un-comment the `translateText` function call using it. + +Now, let's say that you want to update translations or add a new locale, `fr`. + +First, make sure to update the files `scripts/setup_new_locale.tsx` and `scripts/generate_translation_ts_file.tsx` to have the latest locale values as the following respectively. + +```tsx +const newLocale = 'fr' +``` + +```tsx +const locales = ['fr'] +``` + +Now to have translations generated for `fr`, you'd want to run: + +- `bun run setup:new:locale`: This script copies the existing files in `src/pages` directory to `src/pages/fr` directory and makes sure to replace each reference to `content/blog` to `content/fr/blog`. Then, it copies the `src/content/blog` directory to `src/content/fr/blog` and makes sure to set `locale` frontmatter in each markdown file as `fr`. Then, it runs all the translation scripts mentioned below. +- `bun run generate:locale:translations`: This script uses the translate function to translate the `en.yml` key value pairs into the desired language, and creates a `fr.yml` file. +- `bun run generate:translation.ts`: This script uses all the `.yml` files in the `locales` directory to generate two files, `src/services/locale.ts` and `src/services/translation.ts` files with all the locales translations key value pair. +- `bun run generate:blog:translations`: This script uses all the `.md` files in the `src/content/blog` directory to generate the translated version of the file in the `src/content/fr/blog` directory. +- `bun run generate:plugin:translations`: This script uses all the `.md` files in the `src/content/plugins-tutorials` directory to generate the translated version of the file in the `src/content/fr/plugins-tutorials` directory. diff --git a/_redirects b/_redirects index 51e81508..63b13d27 100644 --- a/_redirects +++ b/_redirects @@ -7,5 +7,6 @@ docs/plugin/know-issues docs/plugin/known-issues/ 200 /self-hosted-capgo /docs/plugin/self-hosted/getting-started/ 200 /self-hosted-live-updates /docs/plugin/self-hosted/auto-update/ 200 /docs/getting-started/ /docs/plugin/cloud-mode/getting-started/ 302 +/sitemap.xml /sitemap-index.xml 301 /sitemap-index.xml/ /sitemap-index.xml 301 /sitemap-0.xml/ /sitemap-0.xml 301 diff --git a/scripts/translate.tsx b/scripts/translate.tsx index 6263417f..ae7f8c15 100644 --- a/scripts/translate.tsx +++ b/scripts/translate.tsx @@ -1,41 +1,41 @@ -// import 'dotenv/config' - -// export const translateText = async (text: string, lang: string) => { -// const response = await fetch('https://api.openai.com/v1/chat/completions', { -// method: 'POST', -// headers: { -// 'Content-Type': 'application/json', -// Authorization: `Bearer ${process.env.OPENAI_API_KEY}`, -// }, -// body: JSON.stringify({ -// model: 'gpt-4o-mini', -// messages: [ -// { -// role: 'system', -// content: `Only respond with the translation of the text. No other or unrelated text or characters. Make sure to avoid translating links, HTML tags, code blocks, image links.`, -// }, -// { -// role: 'user', -// content: `Translate the following text to ${lang} locale:\n\n${text}`, -// }, -// ], -// max_tokens: 4000, -// }), -// }) -// if (response.status !== 200) { -// console.error(response.statusText) -// process.exit(1) -// } -// const data = await response.json() -// return data.choices[0].message.content.trim() -// } +import 'dotenv/config' export const translateText = async (text: string, lang: string) => { - const params = new URLSearchParams({ - string: text, - to_lang: lang, - from_lang: 'en', + const response = await fetch('https://api.openai.com/v1/chat/completions', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${process.env.OPENAI_API_KEY}`, + }, + body: JSON.stringify({ + model: 'gpt-4o-mini', + messages: [ + { + role: 'system', + content: `Only respond with the translation of the text. No other or unrelated text or characters. Make sure to avoid translating links, HTML tags, code blocks, image links.`, + }, + { + role: 'user', + content: `Translate the following text to ${lang} locale:\n\n${text}`, + }, + ], + max_tokens: 4000, + }), }) - const response = await fetch(`https://api.datpmt.com/api/v2/dictionary/translate?${params.toString()}`) - return await response.json() + if (response.status !== 200) { + console.error(response.statusText) + process.exit(1) + } + const data = await response.json() + return data.choices[0].message.content.trim() } + +// export const translateText = async (text: string, lang: string) => { +// const params = new URLSearchParams({ +// string: text, +// to_lang: lang, +// from_lang: 'en', +// }) +// const response = await fetch(`https://api.datpmt.com/api/v2/dictionary/translate?${params.toString()}`) +// return await response.json() +// }