How to add a new language


(Neil Lalonde) #1

Contribute to the Transifex project

The first step is to do some translating in the Transifex project. Create an account at Transifex and join a team for one or more languages.

Add language to Discourse

You have two options when you think that the translation is ready to be included in Discourse:

  1. Post in this topic and ask for your language to be included in Discourse. There might be a helpful community member who will add it for you.

  2. You add it yourself. :muscle:
    If you do, please read on…


You will need a development environment (Linux, macOS or Windows) and a working Transifex client. Moreover, you need to fork and clone the discourse and translations-manager git repositories.

Find the language codes

I’ll use Welsh (cy_GB) as an example to show you the next steps. First, take not of the language code used by Transifex. It will look like this:

:bulb: In some cases, Transifex will use a language code that isn’t supported in Rails.

In order to find out, take a look at config/locales/plurals.rb in the discourse repository. For Welsh you will find a line like this:

cy: { i18n: { plural: { keys: [:one, :two, :many, :other], rule: lambda { |n| n == 1 ? :one : n == 2 ? :two : n == 8 || n == 11 ? :many : :other } } } },

So, the language code in Transifex is cy_GB and cy in Discourse.

Add language to translations-manager

Edit lib/translations_manager/locales.rb in the translations-manager repository and add the language code used by Discourse to the SUPPORTED_LOCALES array.

Add an entry to the LANGUAGE_MAP hash if the language code in Transifex differs from the one used by Discourse.

The diff for Welsh would look like this:

@@ -5,6 +5,7 @@ module TranslationsManager
+    'cy',
@@ -44,6 +45,7 @@ module TranslationsManager
   # 'language code in transifex' => 'language code in Discourse'
+    'cy_GB' => 'cy',
     'el_GR' => 'el',
     'es_ES' => 'es',
     'fr_FR' => 'fr',

Next, commit your changes and create a pull request.

Add language to Discourse

:warning: You need to wait for your pull request to be merged if you added an entry to LANGUAGE_MAP. If you didn’t, you can continue right away.

Run script/pull_translations.rb <language_code> in your discourse directory – <language_code> is the code used by Discourse. It will download all translations from Transifex and do some post-processing afterwards.

Transliteration (optional)

Discourse generates slugs from topic titles. Those are the nice looking topic titles in URLs. For example, this topic’s URL contains: /t/how-to-add-a-new-language/14970

But that only works for ASCII characters. You can add transliteration rules for your character set by creating the following file: /config/locales/transliterate.<language_code>.yml

You can take a look at the various existing files (e.g. if you need some inspiration.

:bulb: The slug generation method can be configured in the site settings. You don’t need to create transliteration rules if the users in your country are accustomed to encoded slugs or prefer to have no slugs.

Final checks

Now it’s time to make sure that everything is configured correctly.

Plural rules

Discourse has two files with plural rules – for Ruby and JavaScript. Please verify that the rules match the ones defined in the The Unicode Consortium’s Plural Rules.

  • config/locales/plurals.rb
  • lib/javascripts/locale/<language_code>.js

Language name

The file config/locales/names.yml should contain an entry for your language. Please make sure that the language code exists and that the nativeName is correct. For Welsh it looks like this:

  name: Welsh
  nativeName: Cymraeg

Other files

The following files also need to exist:

  • lib/javascripts/moment_locale/<language_code>.js

:bulb: The language code doesn’t have to match exactly. Only the part before the hyphen must match. So, for Welsh it doesn’t make any difference if the file is named cy-gb.js or cy.js – they are considered the same.

Integration tests

Run the following tests suite to check for known integrity issues:
bundle exec rspec spec/integrity/i18n_spec.rb

Live test

Start your Rails server and test that you can change to the new language using the default locale site setting.

Submit your Pull Request

If everything works, commit the files and send us a pull request. :tada:

Discourse in Croatian
Help me to merge old transladed file and new one
Changing default locale after installing Persian translation does not switch forum layout to rtl
Slovak translation - after switching to sk locale Discourse home page is not loaded
Translating Bosnian
Add persian translate for discourse
Rebuild says "no such locale exists"
Catalan translation
Missing translation in Github
Translation to Azerbaijan language
Translation to Azerbaijan language
Discourse-narrative-bot locales
Adding a new locale
How to translate discourse into Vietnamese
Adding Bulgarian to dropdown
So how to integrate new language to discourse?
Language Translation
How to add settings to your Discourse theme
Discourse creators can you add lithuanian language to next update?
Adding Bulgarian to dropdown
Multiple translations for Spanish on Transifex
Change "Confirm your new account" email
Discourse 1.9.0.beta17 Release Notes
Discourse 1.9.0.beta16 Release Notes
[PAID] Adding Catalan files to Discourse upstream
Catalan translation
Translating Bosnian
Translating Bosnian
Add a new locale from plugin
(probus) #2

This needs to be updated since the faq, privacy and tos erb files are not used any more.

Also, I wonder if poll and imgur files need to be manually added for the first time as well? They don’t seem to get pulled from transifex automatically during updates, there are only six localizations of the poll plugin in github.

(Renis) #3

Can I use a partial translated language?

(Neil Lalonde) #4

You mean a language that doesn’t show as 100% complete in Transifex? Yes you can, but there may be missing translations in some places. It won’t break the site, but it won’t look pretty.

Translating Bosnian
(Keith Guy) #5

Yes, you can use it.

(foobar) #6

Is there a way to copy all translations for a language A into language B, and then work on language B?

I’m working on the Catalan translation, and what would be easiest is to leverage the already-made Spanish translation as a basis (I’m fluent in both langs).

(Gerhard Schlager) #7

This is untested, but you could try to download the Spanish translation files in Transifex and upload them as Catalan translations.

Please add me as a Spanish (Spain) translator
(foobar) #8

Oh yes that does make a lot of sense. I will try. Thanks!

Edit: it did work. The YML file transifex generated was slightly broken (couple newlines missing) and could not be uploaded verbatim, but after fixing it I can work with Spanish as a basis. Thanks!

(Renis) #9

I did it, but the site appears white!

Any method how to merge/add non translated with English?

(foobar) #10

OK so I brought the Catalan translation to a (hopefully) usable state. Now I’m trying to deploy it locally to test it.

This is what I did:

cd /var/www/discourse
ls config/locales/*.en.yml | sed s/\\.en\\./.ca./ | xargs touch
ls plugins/poll/config/locales/*.en.yml | sed s/\\.en\\./.ca./ | xargs touch
ls vendor/gems/discourse_imgur/lib/discourse_imgur/locale/*.en.yml | sed s/\\.en\\./.ca./ | xargs touch
ls public/*.de.html | sed s/\\.de\\./.ca./ | xargs touch
ruby script/pull_translations.rb force

The ls | sed | touch business is just to create the files so that pull_translations.rb force downloads all the stuff.

Next I created app/assets/javascripts/locales/ca.js.erb, I copied the uk file to quickly get me going:

//= depend_on ''
//= require locales/i18n
<%= JsLocaleHelper.output_locale(:ca) %>

I18n.pluralizationRules['ca'] = function (n) {
  if (n == 0) return ["zero", "none", "other"];
  if (n % 10 == 1 && n % 100 != 11) return "one";
  if (n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20)) return "few";
  return "many";

Next I went to http://localhost and changed the global locale to ca. As @renis mentioned in the previous post, upon reloading the site appears as a 100% white blank page.

What to do? No idea on how to even start debugging this.

Edit: after stopping and restarting via launcher, the HTML is no longer blank, but the site is. http://localhost shows only a couple page load times. Chrome reports http://localhost/javascripts/locales/ca.js gives a 404, so that must be the problem now.

Edit2: Problem solved. I had to run RAILS_ENV=production bundle exec rake assets:clobber assets:precompile as suggested in Restart docker instance and rebuild translation cache, I didn’t realize I needed to do that.

It gave some permission errors but that’s because in my noobiness I had ran some commands as root which created a permissions mess that was fixed with chown -R discourse:discourse /var/www/discourse.

Vietnamese locale unable to load
(Tomo Vukasović) #11

This part is bit confusing. I translated few phrases in Bosnian and would like to see it live on our instance.

(Bahadır Yağan) #12

Here is how I do bit by bit, translate as you go process without using transifex.

First, put all files that needs translating to a github repository. This is mine:

Then modify the hooks part of your app.yml to look like this:

    - exec:
        cd: $home/plugins
          - mkdir -p plugins
          - git clone
    - exec:
        cd: /tmp
          - git clone
          - cp -rT discourse-turkish-i18n-kpn/ /var/www/discourse/
          - cp -f discourse-turkish-i18n-kpn/ /root/
          - chmod +x /root/
          - rm -rf discourse-turkish-i18n-kpn

we added the second exec section. This will ensure your translations will be in the container even after a rebuild.

Then you do your translations, push them to github and go inside your container and let rails regenarete assets. This is done using a script that we copied to /root directory above.

cd /var/discourse
./launcher ssh app
./launcher restart app

(Tomo Vukasović) #13

@bahadir Thanks. What if my language does not exist in current Discourse instance. Should I create new folder and files for my language or overwrite English instance.

Git that you are pulling. Which files need to be present in that git repository? I see you have some tests, but I assume this is all I need.

and this one

I am also downloading Ubuntu for local development usage. I have spent too many years working with PHP software on Windows environments. This is all new. Thanks all.

(Bahadır Yağan) #14

Copy the English ones and rename them like and start editing those new files.

You need to have all those files with correct naming in your repository. You don’t need to translate them at once. is the main one, so you can start there. app/assets/javascripts/locales/bs.js.erb file is also important, so do it first.

One final warning. All those yml files start with en: as first line. Change those to bs: as well.

(Tomo Vukasović) #15

Great help it worked. File must be named bs_BA to properly work without errors.

(ไก่จิกดตฎฏบปอ ) #16

I try translated Thailand

Translates to approximately 500 lines

I have followed the steps above.

But the web is steal not available in Thailand.

What is it

(Jeff Atwood) #17

Is this a new language? @techapj can you make sure it’s pulled in?

(Arpit Jalan) #18

The Thailand locale files are currently not available in official Discourse repo.

The example you included above is for manually overriding official translations files via discourse-locale-override hack created by @lidel.

PR for adding Thailand locale files following first post is highly welcome and appreciated! :smile:

(Tomo Vukasović) #21

@iLek2428 Do you see your language listed in admin setting?

Show us your app.yml file so we can see if everything is configured properly.

@bahadir and @lidel

Are you receiving error: Invalid Format: Plural Function not found for locale: bs_BA

This usually shows at the bottom of the topic page.


(Bahadır Yağan) #22

Are you sure about your locale code? I was trying with tr_TR for Turkish before and plural functions and date i18n wasn’t working. Then I noticed ISO 639-1 code for Turkish is tr and fixed it in all my files. I guess it is the same for you. Bosnian code seems to be just bs