Adding a non supported language to Open Edx MFEs
(This guide could possibly be used for any custom changes on the MFEs)
@Wasabi and @onurcan helped quite a lot and their guides here are quite explanatory but I decided to add a bit more detail in the steps needed, for guys like me that are just starting dealing with the MFEs and are quite lost (like I was). I really hope this guide will be helpful!!!
To change the language in which a MFE will be displayed, if this particular language is not in the current limited list of supported languages, (up to the current Open Edx release, olive.3), we must follow the steps below:
PART 1: Forking an MFE
First we have to go on github and fork each one of the MFEs we want to change, moreover, I’d suggest to fork and edit first the frontend-app-account
(the Account) MFE in order to add our new language in the dropdown selection of the languages list under “Site Preferences>Site Language
” options.
IMPORTANT: After forking an MFE we should clone it locally on our computer and then checkout the respective tag of the Open Edx Release we wish to make the change on, in our case this tag should be “open-release/olive.3
” as this is the latest stable release at the time of this guide.
After that, my personal preference is to create a branch from this tag.
The branch name on this guide is named as “dagg
” just to make things simpler, but you could use something like “dagg.olive.3
” so as to have a clear view of which release it is based on!
Forking is done in github and the forked repo is placed in your github area, so, In detail, the steps are the following (after forking an MFE –e.g. the ‘frontend-app-learning
’ MFE– from its original github repo to our own and cloning it to our local computer):
$ git clone https://github.com/dagg/frontend-app-learning.git
$ cd frontend-app-learning
For the ACCOUNT MFE we do the following:
$ git clone https://github.com/dagg/frontend-app-account.git
$ cd frontend-app-account
And similarly for all MFEs.
Then we checkout the TAG we want to make the changes on:
$ git checkout open-release/olive.3
After that we create a branch based on this tag and we checkout on it:
$ git branch dagg
$ git checkout dagg
or we just run:
$ git checkout -b dagg
Now we can work on this branch directly.
PART 2: Mounting an MFE to our tutor dev Open Edx for being able to see live changes.
Using “tutor dev
” we can work on this branch and see every change we make in the code on the fly by using the “--mount
” option. This will mount the forked MFE on the dev version of Open Edx we are currently running on our computer using “tutor dev
”.
Firstly though, and while we are inside the cloned MFE’s folder, we must run the following:
$ npm install
We have to do this in order for the “node-modules
” folder to be created so our forked and mounted MFE can run properly with our tutor dev Open Edx implementation.
If the “npm install
” produces any errors there is a chance this might help:
$ npm cache clear --force
Now, to mount the MFE to our dev platform (our tutor dev must be already up and running) we run the following (from inside our forked and locally cloned MFE folder):
$ tutor dev start learning --mount=.
Or for the ACCOUNT MFE (from inside the MFE’s forked and locally cloned folder):
$ tutor dev start account --mount=.
And so on, for each MFE…
According to the above command, the “learning
” (or “account
” etc) MFE will be mounted to our tutor dev Open Edx installation and every time we make an edit to its code it will show directly on the Open Edx page in our browser.
If we feel quite optimistic, we can avoid the above steps for mounting the MFE locally to our “tutor dev …
” and directly make the changes in the code, but even the easiest and smallest change could have some errors which we won’t be able to see until we deploy the changes to production, so, this is not suggested!
PART 3: Changes to MFEs for supporting a new language
STEP 1:
Once we have mounted the MFE to tutor dev
, we can edit the MFE’s code using our preferred editor.
First we need to change the ACCOUNT MFE for adding the new language to the “site language” dropdown so the user will be able to select it.
To do that we need to edit this file:
frontend-app-account/src/account-settings/site-language/constants.js
And add out language (in my case the Greek language) like so:
In the “siteLanguageList
” array we add this:
{
code: 'el',
name: 'Ελληνικά',
released: true,
}
So it will become something like this:
const siteLanguageList = [
{
code: 'el',
name: 'Ελληνικά',
released: true,
},
{
code: 'en',
name: 'English',
released: true,
},
...
]
Be very careful with the “code” part because if it’s not the correct code for the specified language it will not work!
STEP 2:
After that, we need to add the file with the added language’s translations to our MFE so the translations will be applied on the web pages created by the MFE.
We can find this file in Transifex, under the Edx Platform translations, with a name that corresponds to this particular MFE for the particular translation language.
The translation file for the Greek language on Trasifex for the Account MFE will have the following name: “for_use_edx-platform_frontend-app-account_el.json
”
(Transifex allows to download several different versions of the resource files, for example, one for translation and one for use on the platform etc, we choose the one for use on the platform)
Of course if we want we can create our own messages file but this needs to be done according to the translation guidelines. It’s much easier and faster to download it from Transifex after making the needed translations there so they’ll be available for all users.
After we download the file, we rename it to our language’s code, so this particular file will be renamed to: “el.json
” since “el
” is the code for the Greek language.
We must copy this file in the following folder inside our MFE, as follows:
“frontend-app-account/src/i18n/messages/el.json
”
STEP3:
We then need to edit the following file:
“frontend-app-account/src/i18n/index.js
”
To make it “aware” of the new translations file we added and the new supported language. It’s a very simple file, and we just need to add two things there:
At the first part of the file we add the following line in between the other similar lines:
import elMessages from './messages/el.json';
And at the second part (inside the “messages” object) we similarly add the following:
el: elMessages,
So the whole file will become something like this:
import arMessages from './messages/ar.json';
import elMessages from './messages/el.json'; //This is the first line we added
import caMessages from './messages/ca.json';
// no need to import en messages-- they are in the defaultMessage field
import es419Messages from './messages/es_419.json';
import frMessages from './messages/fr.json';
import zhcnMessages from './messages/zh_CN.json';
import heMessages from './messages/he.json';
import idMessages from './messages/id.json';
import kokrMessages from './messages/ko_kr.json';
import plMessages from './messages/pl.json';
import ptbrMessages from './messages/pt_br.json';
import ruMessages from './messages/ru.json';
import thMessages from './messages/th.json';
import ukMessages from './messages/uk.json';
const messages = {
ar: arMessages,
el: elMessages, //This is the second line we added
'es-419': es419Messages,
fr: frMessages,
'zh-cn': zhcnMessages,
ca: caMessages,
he: heMessages,
id: idMessages,
'ko-kr': kokrMessages,
pl: plMessages,
'pt-br': ptbrMessages,
ru: ruMessages,
th: thMessages,
uk: ukMessages,
};
export default messages;
That’s all !!!
After we save these changes we should be able to see (on the fly, if we mounted the MFE to our tutor dev) the new language (the Greek language in our example) in the “site languages
” dropdown, and the whole Account MFE and its pages should be translated to the Greek language (since we have selected the Greek language as the default language of our platform, or, we choose Greek from the dropdown), according to the translations inside the “el.json
” file we put inside the corresponding folder in the MFE as shown above.
PART 4: Deploying the changes to tutor local (Open edX Production Platform)
Now that we have added the new language and made sure it works properly, we need to deploy these changes to our production platform.
First we need to commit our local changes and then push them to our forked repo on github (we use “git add
”, “git commit
” and “git push
” respectively).
After all changes are pushed to our github repo, (on the “dagg
” branch in this example’s case, but as I suggested, your branch should preferably be named in accordance to the Open edX Release Tag it represents), we need to make our production platform aware of our changed MFE’s new repo and make it pull it from there instead of the original repo.
Thankfully, and thanks to the amazing guys at Tutor, this is quite easy!
In our production machine (tutor local
), we first want to see which repo is used by our production platform for the ACCOUNT MFE, and some other configuration info it needs to run properly (like the local port it uses, etc).
To do that we just run:
$ tutor config printvalue MFE_ACCOUNT_MFE_APP
Most likely the result will be the following:
{'name': 'account', 'repository': 'https://github.com/openedx/frontend-app-account', 'port': 1997}
This looks like a python dictionary or a JSON object, and there we can see the name of the MFE (‘account
’), the remote repo from which it is pulled to be built locally on our platform during it’s setup (‘https://github.com/openedx/frontend-app-account
’) and the local port on which this particular MFE is supposed to run (‘1997’).
We can change these details and use our own repo address, the same port and name of course and we can also add our branch name to make sure that our platform will bring the changed code in our branch and not the original code from the master branch.
To do this we run the following:
$ tutor config save --set "MFE_ACCOUNT_MFE_APP={'name': 'account', 'port': 1997, 'repository': 'https://github.com/dagg/frontend-app-account', 'version': 'dagg'}"
Using “tutor config save --set ...
” we can change the value of several of tutor’s configuration variables, so here we have set the “MFE_ACCOUNT_MFE_APP” to get the same name as and port before (else it wouldn’t work), and use our own repo with the code containing the additional language, and we also use the key name “version
” to denote our branch containing the changed code from our repo.
Since we do this with “tutor config save
”, we can find these changes inside the tutor’s configuration file in the form of yaml, like so:
MFE_ACCOUNT_MFE_APP:
name: account
port: 1997
repository: https://github.com/dagg/frontend-app-account
version: dagg
We could have put these changes directly in this file, but I find the method above much easier. We can make changes directly to the config file though and then run
$ tutor config save
in order for these changes to take effect.
To edit (or view) the tutor config file we run:
$ vim "$(tutor config printroot)/config.yml"
Now, in order for these changes to be applied to our production platform (tutor local) we need to run:
$ tutor images build mfe
And although the official documentation doesn’t mention it (at least not on my knowledge), I found out that in order for the changes to take effect we also need to run:
$ tutor local launch
(Maybe this makes the “tutor images build mfe
” not necessary but I haven’t tried it yet)
And that’s all! After these last steps the new language (or any other changes we have made on the MFEs’ code) should be applied to the Account MFE !
Adding the new language to the other MFEs
In order to make the language available to the other MFEs as well we need to follow all the previous steps for each one of the MFEs, apart from the first step (STEP 1) that only applies to the Account MFE (the step where we add the new language to the dropdown)!
Everything else is the same!
If we need to make changes to more than one MFEs at the same time, we can follow all the above steps and only run
$ tutor images build mfe
and
$ tutor local launch
just once at the end for applying the changes for all the MFEs at once (since these steps take quite some time, sometimes).
THE END!