Interactive Builder for Form Translations within the Form Builder (Interactive Translation Builder?)
Problem Statement
Current translations for forms in OpenMRS are restricted to:
Pre-boot form translations only: Translations for forms can only be loaded during instance initialization via config files (example). This means that you can only add translations for predefined forms that are also loaded during initialization, and there is no in-built feature to support adding translations for forms you create/import on the form builder.
Form translation config files are not intuitive: The translation files for forms are not very intuitive, and can be confusing unless done by a person who knows what they are looking at. In addition, forms are usually not always made by technical personnel, so adding form translations must also be a more user-friendly feature.
Current workflow to add translations for a form:
Users have to add the form into a configuration folder that can be picked up by the initializer e.g - https://github.com/openmrs/openmrs-content-referenceapplication-demo/blob/main/configuration/backend_configuration/ampathforms/ampath_poc_adult_return_visit_form_v1.6_core-demo.json
Users then have to create the translation file for each language into a configuration folder for the form that they added e.g - https://github.com/openmrs/openmrs-content-referenceapplication-demo/blob/main/configuration/backend_configuration/ampathformstranslations/Ampath%20POC%20adult%20return%20visit%20form_translations_fr-core_demo.json
The openmrs instance must then be created to see this in effect.
How do you update the translations? Well, you have to do the above workflow from step 2 all over again.
Project Size
Large
Why we need it?
In the day and age of content packages, this would be a method for people to re-use forms but customize it to their language in a user-friendly way.
Project Idea
Similar to the interactive builder, a UI that would enable users to add the translations for a form for any language.
Here’s a (very high level) flow of how that might look like:
A separate UI editor(from the interactive builder) to manage translations
Preview the form in selected language and add language options
Screenshot 1.1Adding the translation strings
Screenshot 1.2
Obviously, this is not how the UI should look and neither are these mockups for the project. These are merely a guide to understand the use case.
Implementation
A UI editor needs to be implemented to manage the translation strings for each question (interactive translation builder)
We need to display all the translatable strings within the form (e.g. - question labels, answer labels) within the UI and allow the user to enter the respective string for it in a different language.
For example, refer to screenshot 1.2. The translation builder should display
Was this visit scheduled
(the label of the question on line number 64 on the JSON) as a translatable string. The user should be able to add the translation this string.
Manage translations for different languages
Users should be able to add translations for different languages for a translatable string.
Preview the form in a specific language.
Currently, the form builder has a
Preview
tab, that allows you to preview a form (as how an end user using a form would see it). How this works is, the JSON (that can be seen in theSchema Editor
tab gets rendered by theform-engine
- https://github.com/openmrs/openmrs-esm-form-builder/blob/eff9e72db3964140f0c1068d9086397a45236520/src/components/form-renderer/form-renderer.component.tsx#L83Currently you’d see if you change the language to French and launch the
Adult HIV Return Visit
form, the form would be displayed in French. How the translations for the form get loaded is, each translation file is saved as aformResource
of a form. This is because translations for a form are separate from the form itself. The translations are saved as aformResource
to the form. The backend moduleo3-forms
, when you request a form, adds the translations to the form json. You can see this if you look at the response of the API call for getting a call (e.g, make an API call to https://test3.openmrs.org/openmrs/ws/rest/v1/o3/forms/107c32e8-a318-30bf-acfc-a0244f3a795a on postman, see fig 1.1). The backend module got these translations because it was saved as a configuration file, and it can only do this if the translation files are saved in the database as aformResource
for the relevant form. We can’t render the translations this way while a user edits the translations because they aren’t saved to the database, and we shouldn’t be saving them to the database and refetching it every time an edit is made.So what you need to do is update the translations object in the form’s JSON schema in the schema editor, similar to how when you create/update a question using the interactive builder, it updates the form’s JSON schema in the schema editor. Please look at the form, the above point and the translation file for the form to understand the structure of the form and translations and where the translations should be in the JSON schema. The translation strings SHOULD NOT replace the labels itself of a question, all translation strings should be in the translation object in the form JSON.
This can be complicated when managing multiple languages. When changing languages, it should be checked if we can maintain the strings for all languages within the schema, i.e. if it is possible to do something like:
"translations": { "fr" : { ... }, "it" : { ... } }
If not, we should fallback to an user only being able to edit translations for only one language at a time, and show a danger prompt saying that they’ll lose their changes if they switch languages and ask them to download the translations before they switch.
Since this schema that has the translations is what gets passed to the
form-engine
, it should be able to render the form in a specific language.There should be a dropdown where a user can select which language to preview the form in.
Possible complication: currently in patient chart where the forms are being used, you need to change the overall language of the entire application (through the top navbar) in order for the form to be rendered in that language. We need to figure if we can render a form in a specific language without changing the overall language of the entire application.
Users should be able to download the translation resource file (check the reference materials to see what the file format should be) for a specific language.
The current scope of the project isn’t to save these translations to the backend. Its to allow users to download the JSON document of translations that they can add to their Initializer configuration.
The user just needs to able to see an option to download the translation files for a specific language. e.g. - for this form -https://github.com/openmrs/openmrs-content-referenceapplication-demo/blob/main/configuration/backend_configuration/ampathforms/ampath_poc_adult_return_visit_form_v1.6_core-demo.json the user needs to be able to download the translation file for example for French, which should be formatted to this - https://github.com/openmrs/openmrs-content-referenceapplication-demo/blob/main/configuration/backend_configuration/ampathformstranslations/Ampath%20POC%20adult%20return%20visit%20form_translations_fr-core_demo.json(this is the format that the file a user downloads should be in, and each language should have its own file like this that contains the translation strings for that language)
Although the idea itself seems simple, there’s a considerable amount of work that would require to make the entire UI and to manage multiple translations, and actually making the translation file resource itself.
Reference materials
An example form translation file in English - https://github.com/openmrs/openmrs-content-referenceapplication-demo/blob/main/configuration/backend_configuration/ampathformstranslations/Ampath%20POC%20adult%20return%20visit%20form_translations_en-core_demo.json
An example form translation in French - https://github.com/openmrs/openmrs-content-referenceapplication-demo/blob/main/configuration/backend_configuration/ampathformstranslations/Ampath%20POC%20adult%20return%20visit%20form_translations_fr-core_demo.json
Conventions for the form translation file - https://github.com/mekomsolutions/openmrs-module-initializer/blob/b5a6cabd5bccba78c1fd13710d1e929adc1e42bf/readme/ampathformstranslations.md
The original form itself - https://github.com/openmrs/openmrs-content-referenceapplication-demo/blob/main/configuration/backend_configuration/ampathforms/ampath_poc_adult_return_visit_form_v1.6_core-demo.json
The form builder’s source code - https://github.com/openmrs/openmrs-esm-form-builder
The backend form module - https://github.com/openmrs/openmrs-module-o3forms
The form engine source code - https://github.com/openmrs/openmrs-esm-form-engine-lib
Learn about the O3 Form Builder - https://www.youtube.com/playlist?list=PL5jj7JoBifSkI_MBt1uKGTCEkk11KuZAL and https://www.youtube.com/playlist?list=PL5jj7JoBifSm-jke5ofzZiGbS_n8phHaG