Skip to content

Contributing to Translations

NOT_A_ROBOT edited this page Aug 15, 2024 · 8 revisions

Below is a guide on how to contribute by translating the site into your language.

Section 0. Downloading the repository

The first step to contributing to translations is to download the source code. Don't forget to extract the .zip file!

Section 1. Adding a new language

If you're planning to translate this website to a language that this site hasn't been translated into, the first step would be to add the new language into the site.

Add the language into Nuxt.js' config

In nuxt.config.ts, search for a line starting with i18n. Just a few lines underneath it, you should find a line that starts with locales:

  modules: ['@nuxtjs/i18n'],

  i18n: { // !! i18n here
    vueI18n: './i18n.config.ts',
    locales: ['en', 'id'], // !! locales here
    defaultLocale: 'en',
  },

  $production: {
    devtools: { enabled: false }
  },

In that locales variable, add your new language code. If you don't know the language code, you should be able to get it by searching up "(language) language code". For example, if you're translating this into French, you should search "french language code" into your favorite search engine.
It doesn't really matter what kind of language code you use, but if you can, try to use the two-letter ones. If the language varies greatly by region (e.g. Portugal Portuguese vs Brazilian Portuguese), feel free to break this convention.
To add the language code to the list, put , '(your-language-code)' right before the ].
It should then look something like this:

    locales: ['en', 'id', 'br-pt'],

Adding the language's name

In /assets/types/lang.ts, search for a line starting with export const langNameMap. This contains a "map" of the language's code to the language's name. It should look something like this:

/** A map from a language ID to its name in that language. */
export const langNameMap = {
    en: "English",
    id: "Bahasa Indonesia",
} as { [index: string]: string | undefined };

To add your language's name into the "map", add (lang_code): "(language name)", in a new line right before the line that starts with } as {.
However, if your language code has a hyphen, you have to wrap it in quotes, like 'en-gb': "English (UK)", It should then look something like this:

export const langNameMap = {
    en: "English",
    id: "Bahasa Indonesia",
    fr: "Français",
    'br-pt': "Português (Brasil)",
} as { [index: string]: string | undefined };

Creating the language file

In /assets/lang, duplicate the en.ts file by copying it and then pasting it.
Then, rename it to something like (lang_code).ts. For example, if you're translating into German, it should be named de.ts.
You don't need to worry about the contents for now, what matters is that you've created that file out of the English language file.
We will cover editing the language file in Section 2.

Binding the language file into i18n

Now go back to the project folder. You should see a file named i18n.config.ts. Open it.
Once the file is opened, find the line that starts with import * as lang. It should be near the top of the file.
It should look something like this:

import * as langEN from '~/assets/lang/en';
import * as langID from '~/assets/lang/id';

Duplicate (copy and paste) one of those lines. It should then look something like this:

import * as langEN from '~/assets/lang/en';
import * as langID from '~/assets/lang/id';
import * as langID from '~/assets/lang/id';

Now, modify the line you just pasted, such that it refers to the language code you are adding. For example, if you're adding a Russian translation, it should look something like this:

import * as langEN from '~/assets/lang/en';
import * as langID from '~/assets/lang/id';
import * as langRU from '~/assets/lang/ru';

Now that you've imported the file into i18n, we'll need to tell it to use that import.
Look for the line that starts with export default defineI18nConfig. A few lines under that, you should find a line starting with messages:.
It should look something like this:

export default defineI18nConfig(() => ({
    // --snip--
    messages: {
        en: processLangEntry(langEN.default),
        id: processLangEntry(langID.default),
    },
}));

Duplicate one of the lines that's inside messages. It should then look something like this:

    messages: {
        en: processLangEntry(langEN.default),
        id: processLangEntry(langID.default),
        id: processLangEntry(langID.default),
    },

After that, modify your newly-pasted line such that it matches with your language code. If you're adding Chinese, for example, it should then look something like this:

    messages: {
        en: processLangEntry(langEN.default),
        id: processLangEntry(langID.default),
        zh: processLangEntry(langZH.default),
    },

If you're here, you have successfully set up the translation! Now, it's time to actually translate entries.

Section 2. Language files and entries

Go to your language file. It should be located inside /assets/lang/. If not, then you should do the steps in Section 1 if you haven't; and start a new discussion if you have.

Inside the language file, you should see a line starting with export default {, with a bunch of lines underneath that have things between quotation marks " or backticks ```. In general, these are called strings, but here, we will refer to each of them as a language entry.

The two different types of strings

(Note: feel free to skip this portion if you know about JS strings) Notice how some of the the strings are in between quotation marks "like this", while others are in between backticks `like this`.
These are two different kinds of strings, and they can do slightly different things.

  1. Quotation mark strings cannot span multiple lines.
"hello
world" // invalid
  1. Backticks can span multiple lines.
`# Large Article
By Techmino Hub
Hello World` // valid

There are more differences, but it's not very important for translators.

Markdown strings

Notice how some of the strings start with md_. This signals that the language entry should be processed using Markdown, instead of being served as-is.
For example, Testing **string** will just be Testing **string**, but md_Testing **string** will become Testing string.
Note that the md_ will be omitted from the final display. If you want to have md_ in the result, you'll have to have it twice: md_md_Hello!
Markdown is a pretty simple way to style text. it allows things such as:

  • Styled text
  • List
  • Tables
  • A lot more!

You can learn more about Markdown here.

HTML strings

If you don't prefix a "markdown-able" string with md_, you can use HTML in it.
However, it's highly recommended to use Markdown whenever you can.
Explaining the HTML syntax is out of the scope of this documentation; you can search up a tutorial on your favorite search engine.

Function entries

Some language entries may be TypeScript functions. Here's an example:

leaderboard: {
  scoreDisp: {
    masterExGrade: ({ named }) => {
      const val = named('value') as number;
      const idx = Math.floor(val / 10);

      return [
        "D","C","B","A","A+","S-","S","S+","S+",
        "SS","SS","U","U","X","X+"
      ][idx];
    }
  }
}

Function language entries are often used to 'transform' a value into another form. In the example above, it converts a grade value (a number) into a string that represents the value. So, a grade value of 1 will get turned into "C", a grade value of 2 will get turned into "B", and so on.

The primary input of a function can be accessed by doing named('value'). To output a value to be displayed, simply return the value.

If you aren't experienced at coding, don't worry! We know not all translators have programming experience, so you can ask for help on Techmino's official Discord server. Just tell us what you want the function to do given certain inputs, and we'll be ready to help!

Section 3. Translating the language entries

Now for the nitty-gritty: translating the language entries.
This part's pretty straightforward; for each language entry in the language file, translate each of them. Make sure to only edit the text between the quotation marks " or between the backticks `.
Don't forget to preserve the starting md_ if there is one.
Also: don't add an md_ where there isn't one yet. It's not supported and will result in some HTML being rendered as text.

Here's an example before the translation:

    nav: {
      home: "Home",
      faq: "FAQ",
      map: "Map",
      signIn: "Sign In",
      settings: "Settings"
    },

Here's an example after translating into Indonesian:

    nav: {
      home: "Beranda",
      faq: "FAQ",
      map: "Peta",
      signIn: "Masuk",
      settings: "Peraturan"
    },

This is by far the most time-consuming part of helping translate the project. Good luck!

Section 4. Add your contribution

There are two methods to add your contribution to the project.

Making a Pull Request

Making a pull request is the most surefire way that you'll end up on this repository's contributor list.
This requires you to have a GitHub account.
This part also assumes you have at least some experience with using Git.
If you don't have that, feel free to skip to the second method.

With that out of the way, here are the steps you need to do:

  1. Commit your local changes.
  2. Push your local repository to a remote, such as a GitHub repository.
  3. Create a pull request

Sending your contribution through email

Alternatively, you can send your /assets/lang/(language code).ts file to @Not-A-Normal-Robot's public e-mail. They can help you add your contribution to your project.

Section 5. Periodically updating your translations (Optional)

If you're feeling especially helpful, you can help keep the translations up-to-date by periodically cross-check the English language file and your language file and see if there are any missing entries.
We would very much appreciate your dedication to keeping the translations up-to-date.