# Internationalization

Internationalization is the process of making an application available in other languages. This is important, as not everyone is a native English speaker.

## Available Languages

An up-to-date list of all currently supported languages can be found in [`./src/utils/languages.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/languages.js).  Languages are specified by their 2-digit [ISO-639 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (e.g. `en`, `fr`, `de`, `es`, etc)

---

## How to change Language

By default, Dashy will attempt to use the language of your browser or system. If a translation for your language does not yet exist, it will fallback to English.

You can also manually select your language. This can be done, either through the UI (Config --> Language), or by setting it in your config file: 
```yaml
appConfig:
	lang: de
```

---

## Adding a new Language

Dashy is using [vue-i18n](https://vue-i18n.intlify.dev/guide/) to manage multi-language support.

Adding a new language is pretty straightforward, with just three steps:

##### 1. Create a new Language File
Create a new JSON file in `./src/assets/locales` name is a 2-digit [ISO-639 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) for your language, E.g. for German `de.json`, French `fr.json` or Spanish `es.json` - You can find a list of all ISO codes at [iso.org](https://www.iso.org/obp/ui).
If your language is a specific dialect or regional language, then use the Posfix [CLDR](http://cldr.unicode.org/) format, where, e.g. `en-GB.json` (British), `es-MX.json` (Spanish, in Mexico) or `zh-CN.json` (Chinese, simplified) - A list of which can be found [here](https://github.com/unicode-org/cldr-json/blob/master/cldr-json/cldr-core/availableLocales.json)


##### 2. Translate!
Using [`en.json`](https://github.com/Lissy93/dashy/tree/master/src/assets/locales/en.json) as an example, translate the JSON values to your language, while leaving the keys as they are. It's fine to leave out certain items, as if they're missing they will fall-back to English. If you see any attribute which include curly braces (`{xxx}`), then leave the inner value of these braces as is, as this is for variables.

```json
{
  "theme-maker": {
    "export-button": "Benutzerdefinierte Variablen exportieren",
    "reset-button": "Stile zurücksetzen für",
    "show-all-button": "Alle Variablen anzeigen",
    "save-button": "Speichern",
    "cancel-button": "Abbrechen",
    "saved-toast": "{theme} Erfolgreich aktualisiert",
    "reset-toast": "Benutzerdefinierte Farben für {theme} entfernt"
  },
}
```

##### 3. Add your file to the app

In [`./src/utils/languages.js`](https://github.com/Lissy93/dashy/tree/master/src/utils/languages.js), you need to do 2 small things:

First import your new translation file, do this at the top of the page.
E.g. `import de from '@/assets/locales/de.json';`

Second, add it to the array of languages, e.g:
```javascript
export const languages = [
  {
    name: 'English',
    code: 'en',
    locale: en,
    flag: '🇬🇧',
  },
  {
    name: 'German', // The name of your language
    code: 'de', // The ISO code of your language
    locale: de, // The name of the file you imported (no quotes)
    flag: '🇩🇪', // An optional flag emoji
  },
];
```
You can also add your new language to the readme, under the [Language Switching](https://github.com/Lissy93/dashy#language-switching-) section and optionally include your name/ username if you'd like to be credited for your work. Done!

If you are not comfortable with making pull requests, or do not want to modify the code, then feel free to instead send the translated file to me, and I can add it into the application. I will be sure to credit you appropriately. 

---

## Adding Text

If you're working on a new component, then any text that is displayed to the user should be extracted out of the component, and stored in the file. This also applies to any existing components, that might have been forgotten to be translated.

Thankfully, everything is already setup, and so is as easy as adding text to the JSON file, and pasting the key to that text in your component.


#### 1. Add Translated Text

Firstly, go to [`./src/assets/locales/en.json`](https://github.com/Lissy93/dashy/blob/master/src/assets/locales/en.json), and either find the appropriate section, or create a new section. Lets say you're new component is called `my-widget`, you could add `"my-widget": {}` to store all your text as key-value-pairs. E.g.

```json
"my-widget": {
	"awesome-text": "I am some text, that will be seen by the user"
}
```

Note that you **must** add English translations for all text. Missing languages are not a problem, as they will always fallback to Enslish, but if the English is missing, then nothing can be displayed.


#### 2. Use Text within Component

Once your text is in the translation file, you can now use it within your component. There is a global `$t` function, with takes the key of your new translation, and returns the value. For example:

```vue
<p>{{ $t('my-widget.awesome-text') }}</p>
```

Note that the `{{ }}` just tells Vue that this is JavaScript/ dynamic.
This will render: `<p>I am some text, that will be seen by the user</p>`

If you need to display text programmatically, from within the components JavaScript (e.g. in a toast popup), then use `this.$t`.
For example: `alert(this.$t('my-widget.awesome-text'))`.

You may also need to pass a variable to be displayed within a translation. Vue I18n supports [Interpolations](https://vue-i18n.intlify.dev/guide/essentials/syntax.html#interpolations) using mustache-like syntax.

For example, you would set your translation to:
```json
{
	"welcome-message": "Hello {name}!"
}
```

And then pass that variable (`name`) within a JSON object as the second parameter on `$t`, like:
```javascript
$t('welcome-message', { name: 'Alicia' })
```

Which will render:
```text
Hello Alicia!
```

There are many other advanced features, including  Pluralization,  Datetime & Number Formatting, Message Support and more, all of which are outlined in the [Vue-i18n Docs](https://vue-i18n.intlify.dev/guide/).

#### Basic Example

Using the search bar as an example, this would look something like:

In [`./src/components/Settings/SearchBar.vue`](https://github.com/Lissy93/dashy/blob/master/src/components/Settings/SearchBar.vue):
```vue
<template>
  <form>
    <label for="search-input">{{ $t('search.search-label') }}</label>
    <input
      id="search-input"
      v-model="searchValue"
      :placeholder="$t('search.search-placeholder')"
		/>
  </form>
</template>
```

Then in [`./src/assets/locales/en.json`](https://github.com/Lissy93/dashy/blob/master/src/assets/locales/en.json):

```json
{
"search": {
    "search-label": "Search",
    "search-placeholder": "Start typing to filter",
  },
	...
}
```
