Translating Metadata in Bahmni

We’ve been working on the endtb project and have noticed that when viewing our non-English implementations there’s a lot of text that isn’t properly localized, specifically all metadata other than Concepts.

This is generally due to a lack of a built-in means within the OpenMRS Platform to localize metadata other than Concepts.

For what it’s worth, the OpenMRS UI Framework and OpenMRS Rest Web Services have added support to localize metadata using messages.properties code that rely on the uuid of the underlying OpenMRS update. (An explanation of this approach can be found here: https://issues.openmrs.org/browse/RESTWS-437) However, for Bahmni, we are thinking it would be better to have a native way to specify localized names for metadata using the standard angular translate json files that are defined in the bahmniapps i18n directory and are extendable within implementation-config.

Seems like it would be straightforward to define an angular filter that given a piece of OpenMRS metadata, would check to see of the name property of that metadata is really a code, and, if so, look up that code in the translation files. (And if no code is found, just display the name property as-is).

For instance, if you wanted to localize the name of an identifier type, you’d do the following:

  1. In the database, set patientIdentifierType.name = “SOME_CODE_FOR_LOCALIZATION”

  2. In the .json translation file add key/value pair “SOME_CODE_FOR_LOCALIZATION”: “My Localized Name”

  3. Then when displaying, do something like this: “{{ :patient.primaryIdentifier.identifierType || localize}}” (or “{{ patient.primaryIdentifier.identifierType.name || localize }}” if we didn’t want to bake in the idea of looking at the name property in particular).

Obviously one downside is that you’d have to retrofit a call to the “localize” filter at every point within the code where you are displaying metadata you want to localize, but this could be something that could happen over time as relevant untranslated metadata is encountered.

Thoughts? We’d likely have some time to work on this if we can agree upon an approach.

Thanks! Mark

Hi @mogoodrich, This approach is similar to what is with labels & text in the other places of app. Is it a better idea if we can get OOB support from OpenMRS like we have for concepts? This means some data model changes to metadata tables, but I think it is worth it instead of every distro doing it their own way. Thoughts? @darius @angshuonline @vinay

Supporting this OOB in openmrs-core is a (very) large piece of work. It was attempted once as a Google Summer of Code project in 2010 (@mseaton was the mentor). See the work at TRUNK-51. The idea was to have a special LocalizedString hibernate datatype (that wouldn’t require changing the DB model for every metadata table) and allowed you to store localizations inline. In the end, this work was never merged in, and when we needed this feature for Mirebalais we implemented what Mark described that is mentioned on RESTWS-437.

I don’t see a lot of value in implementing the localization within the database schema, when it’s easy to handle it using standard i18n tooling.

(Concepts do need special treatment because of all the synonyms, name types, etc, but plain metadata that has one name in English and another in French, Spanish, etc, isn’t so complex.)

Yes, I’ll second what Darius said. Getting OpenMRS Platform to support localization of OpenMRS metadata natively would be better, but this hasn’t proven to be better, so I think it would make sense for Bahmni to define their own standard to use.

Take care, Mark

@mogoodrich The approach you mentioned in the original post sounds fine to me. You can go ahead and give a PR. We are starting 0.89 release now. Backporting to previous releases might be little difficult as it needs a full round of regression testing. Hope this information helps.

Thanks @bharatak ! Not sure exactly when we will start–were are working on prioritizing endtb tickets, but will keep you posted.

Take care, Mark

We did a little spike on creating a “metadataTranslate” filter that tried to do some intelligent logic mentioned above, but then realized it probably makes the most sense to take the simplest approach possible and instead of creating a new filter, just apply the existing translate filter on all metadata we want to localize. Since the translate filter just returns the input string if no match is found, this should have no impact on existing implementations.

Thoughts? Mark

One concern we came up with for the approach I suggest above was if assing in strings with single or double quotes into the translate filter would cause it to break… I just tested with that, and a few special characters, and angular translate appears to be able to handle them without issue.

Mark