What is the correct way to set up translations for a third-party XBlock

Hi everyone!

I’m trying to understand the current, correct approach for adding translations to a third-party XBlock (one not included in the openedx-translations repo).

Initially, we added translations to our XBlock following this guide

We use i18n-tools for extraction and generation, with supported languages defined in locale/config.yaml. Translated strings live in translations/<lang>/LC_MESSAGES/text.po|mo as documented.

To be fair, I am not certain at which point our translations stopped working, but now in Ulmo they are definitely not working.

This document also confirms that XBlocks not included in the openedx-translations repo should be using the fallback path /translations/<lang>/LC_MESSAGES/text.po|mo, which it is not working anymore.

After digging into XBlockI18nService.get_python_locale()(openedx-platform/xmodule/modulestore/django.py at release/ulmo.3 · openedx/openedx-platform · GitHub), called from our XBlock runtime, I found it returns ('django', Path('/openedx/edx-platform/conf/plugins-locale/xblock.v1/stackamole')) and I guess that’s why the /translations directory never gets loaded?

I am not sure if it’s a bug or I am missing something?

What I found to be working though, is moving the translations to /locale/<lang>/LC_MESSAGES/django.po|mo (not text.po|mo) which is actually more convenient since that’s the default path when using i18n-tools and compilejsi18n commands. However, that feels like a coincidence rather than an intentional design as it’s not listed as an option in any related docs that I’ve found.

There is a comment in the code:

  • Alternatively, it looks for bundled translations in the XBlock pip package which are found at <python_environment_xblock_root>/conf/locale//LC_MESSAGES/.po | mo

That is the closest to what appears to be working for me, but includes the /conf/ directory. Funny enough, if I move the translations to a path with /conf/ the translations stop working again. Using this path is documented as a prerequisite step to add your translations for the openedx-translations repo (Enabling Translations on a New Repo — Latest documentation) and there is no mention of third-party XBlocks there.

So my question is, can I consider moving the translations from translations/<lang>/LC_MESSAGES/text.po|mo to /locale/<lang>/LC_MESSAGES/django.po|mo an actual fix and expect it to work in the future releases as well? Or what would be the correct way to include translations to our XBlock?

Thanks in advance!

Hello, Maari (@mrtmm).

In my understanding, the new standard way to add translations is to use a fork of openedx-translations.

Here, you can find more documentation about it: Customizing and Overriding Translations — Tutor documentation.

In this case, your XBlock should be considered a custom plugin (Python/Django). I had used that documentation to translate an XBlock, and it worked as expected. :sparkles:

Hi @mafermazu, thank you so much for the reply!

I’ve tested your suggestion and using a forked openedx-translations repo does indeed work. However, I really don’t love the idea of maintaining a fork for this. What if we’d want to run multiple third-party XBlocks on our site? Maybe not all maintained by us, then we’ll need to maintain and merge forks?

I’ve been thinking, if we’d have an option to patch the openedx Dockerfile after pulling the atlas translations and before compiling the translations, something like:

# Pull latest translations via atlas
RUN make clean_translations
RUN ./manage.py lms --settings=tutor.i18n pull_plugin_translations --verbose --repository='{{ ATLAS_REPOSITORY }}' --revision='{{ ATLAS_REVISION }}' {{ ATLAS_OPTIONS }}
RUN ./manage.py lms --settings=tutor.i18n pull_xblock_translations --repository='{{ ATLAS_REPOSITORY }}' --revision='{{ ATLAS_REVISION }}' {{ ATLAS_OPTIONS }}
RUN atlas pull --repository='{{ ATLAS_REPOSITORY }}' --revision='{{ ATLAS_REVISION }}' {{ ATLAS_OPTIONS }} \
    translations/edx-platform/conf/locale:conf/locale \
    translations/studio-frontend/src/i18n/messages:conf/plugins-locale/studio-frontend

{{ patch("openedx-dockerfile-pre-compile-translations") }}

RUN ./manage.py lms --settings=tutor.i18n compile_xblock_translations
RUN ./manage.py cms --settings=tutor.i18n compile_xblock_translations
RUN ./manage.py lms --settings=tutor.i18n compile_plugin_translations
RUN ./manage.py lms --settings=tutor.i18n compilemessages -v1
RUN ./manage.py lms --settings=tutor.i18n compilejsi18n
RUN ./manage.py cms --settings=tutor.i18n compilejsi18n

we could include our translations with a simple tutor patch, given that the XBlock includes the translation files as django.po & djangojs.po files

I’ve tested the following case:

XBlock includes translation files as

locale/
└──<lang>/
   └──LC_MESSAGES/
      ├── django.po
      └── djangojs.po

and is installed via OPENEDX_EXTRA_PIP_REQUIREMENTS

translations are included with

hooks.Filters.ENV_PATCHES.add_item(
  (
      "openedx-dockerfile-pre-compile-translations",
      "RUN cp -a /openedx/venv/lib/python3.11/site-packages/stackamole/locale/. /openedx/edx-platform/conf/plugins-locale/xblock.v1/stackamole/"
  )
)

after a rebuild of the openedx image, all translations are compiled and working.

I wonder if a PR for this would be welcomed upstream? I understand this a corner case for third-party XBlocks but this might be useful for any smaller translation tweaks as well.

@omar @brian.smith @dave - any thoughts on this, or anyone else I could tag?

I think it is perfectly reasonable for third party xblocks to ship with translations, and if that isn’t something that currently works smoothly we should improve that process.

We should also ensure the “fork openedx-translations” flow continues to work, as it is possible (or likely) that operators would want to override translations or add languages for third party xblocks.

Hi @mrtmm, XBlocks internal i18n are supported. You can embed them there without a problem. Please check my pull request from 2019. It still works today with some modifications:

However, you won’t be using Transifex. Only Open edX · GitHub XBlocks are hosted on the Open edX Transifex projects.