CSC/ECE 517 Fall 2021 - E2159. Expertiza internationalization
Introduction - Purpose & Problem
Currently, all Expertiza screens can only be viewed in English. Many Expertiza users are from other countries. This is a problem since this limits the accessibility of Expertiza. An important step in solving this problem is by making Expertiza available in more languages, which is a form of internationalization. W3C defines internationalization as “the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language.”
Survey of home country of Expertiza users for a given course
Scope: The scope of this project is limited however only to static strings. i.e. user-generated content will not be automatically translated to other languages.
Breaking down internationalization into 3 sequential subproblems:
1. Language selection
@rsabu
Internationalization is done for pages viewed by students only. Any user other than students views all pages in English. The student has the option to set a language preference.
LOFI UI sketch
<Insert image here>
There is also an option where the instructor can choose a default language for a course.
<Insert image here>
Thus, the language not only varies from user to user but also across screens for the same user. Thus we need to recompute the language in which the page is to be rendered. If the student has given a language preference, then the choice is given weightage over the default language chosen by the instructor.
2. Rendering the language
How do we go about rendering the screen in that language?
In the previous step, we’ve identified the language in which a view is to be rendered. It is important to note that this language may not only differ for a different user, but also for a different page for the same user. The question now becomes, how do we render the screen in this language?
To tackle this question, we explore 2 fundamental concepts:
2.1 Views are composed of independent language elements
While this is something we typically take for granted, it becomes especially important in the context of translation. That is, a view is not a single contiguous block of text, nor is it an atomic visualization of information (unlike a screenshot), but rather a carefully organized collection of individual elements such as texts, buttons, etc that each contain language that needs to be translated separately. Crucially, this means that we cannot swap out a page in one language in its entirety for a page in another language in its entirety. Instead, each individual element needs to be swapped out individually so as to only impact the language and not the structural composition of the page itself.
2.2 Views require translation at a large number of call sites
Given that a view is composed of individual elements, this also means that the computation of how to translate such an element such as a button’s text would need to be done separately for each element. This would result in not only a single centralized
3. Translation gaps
What if the translation for the target language is not available? Even translation for a language like Hindi may be available in general, the translation for a given text may not be available Hindi. This may be due to a variety of reasons: The specific text may have been accidentally missed out (remember the translation is not being done at runtime through an API, but rather curated by the developer) The given text is non-trivial to translate to the target language Our design would thus need to accommodate this by seamlessly falling back on another language whose translation is available.
Scope
The scope of this project is limited however only to static strings. I.e. user-generated content will not be automatically translated to other languages.
Design
Proposed Solution
1. Language selection
The language in which the page is rendered depends on a set of conditions.
If the student has set a language preference, it overrides the default language setting saved by the instructor, and all pages are displayed in the language preferred by the student.
If the student has not set a language preference and is on a page that is specific to a course for which the instructor has added a default language, the page is displayed in the course’s default language.
If the student has not set a language preference and is not on a course-specific page, then the page is displayed in English.
If a language preference is obtained by following the above conditions but some keys in the page don't have a translation for the language, the English translation for that key is returned as a fallback.
2. Rendering the language
Once we have determined the language in which to render the page, we now need to update the rails view code to actually generate the appropriate HTML in the target language. This is the responsibility of the view. However, currently, the actual content of the HTML is hardcoded in (red) English. For example:
<h2>Summary Report for assignment: <%= @assignment.name %></h2> <h4>Team: <%= @team.name %></h4>
As discussed earlier, “Views are composed of independent language elements” and so we cannot simply swap out the entire page content for a separate page in another language (Why? - See “swap out the entire view” in the alternative approaches section):
<h2>Rapport de synthèse pour l'affectation: <%= @assignment.name %></h2> <h4>Équipe: <%= @team.name %></h4>
Instead, the better approach is to have a single unified view that dynamically changes based on the selected language:
<h2><%=language==’en’ ? ‘Summary Report for assignment’ : ‘Rapport de synthèse pour l'affectation’>: <%= @assignment.name %></h2> <h4><%=language==’en’ ? ‘Team’ : ‘Équipe’>: <%= @team.name %></h4>
However this is clearly infeasible considering the number of call sites where we have to apply this logic. Thus, in order to maximize how concise the call site is, we can pull out this logic into a common helper function:
<h2><%=localized(“report_summary.page_header”)>: <%= @assignment.name %></h2> <h4><%=localized(“report_summary.team_label”)>: <%= @team.name %></h4>
Here the assumption is that the localized(“key”) is aware of the currently selected language and that “report_summary.page_header” is the key for the header which is available in English and Hindi. The helper intelligently selects and returns the right text based on the currently selected language. Through this approach, we are able to render the view in multiple possible languages without any significant increase in the verbosity of the view.
What’s more, is that the above problem is a common problem for user-facing applications and a standard library for doing the above and much more already exists for rails applications called i18n
I18n - Internationalisation, How are we using I18n in Ruby on Rail
I18n is a ruby library/gem which helps us render the static string on the view dynamically. Dynamicity means that based on a local decision of choosing the current language of the view, the library returns the strings of that particular language at runtime.
These strings, instead of hardcoding in the view.rb, are provided in external .yml files. Now at the View level, we can pass an id to the 't' function and the I18n library returns the string for that id of the current set language(called as locale).
For this purpose, we have to provide .yml files for each language and in those language-specific .yml, we have to provide a map of key-value pairs where the key is the id of the string and value is the string in that particular language. By default the language or locale is set to be English(:en).
THE GREATEST BENEFITS of using this library are -
- The strings aren't hardcoded in the code/build. The strings are being fetched from external files which can be easily modified. For example, if one needs to change the text from 'Please Help' to 'Help', then one just needs to make a change in the .yml file and the change would reflect on the browser. For this change, we didn't need to redeploy the server. We just Decoupled the view when and where from what content is to be shown.
- Adding more languages is now super easy. Adding support for another language is just one line change in the config and adding a .yml file (having all the key-value pairs for the strings) for the new language. By doing this we can extend the language support as much as we want.
3. Translation gaps
Also, if the language is set to be Hindi or any other language but the key-value pair is not set for that particular string then, automatically the library returns the default which is the English text.
config.i18n.fallbacks = [:en]
Alternate approaches
1. Why not simply swap out the entire view for another language instead of each text?
A view is an organized collection of multiple separate elements, views often involve dynamic generation and some level of sophistication. If we were to swap out one page in its entirety for another page this would often violate the DRY principle since we would have to have two separate implementations of the view in each language. Thus in the worst case, you have a complex view that has to be replicated dozens of times in various languages.
The majority of complexity of the page is not in the content itself but rather the code that executes to generate that content, thus it makes sense to instead maintain a single view and embed the language switching logic at each location where translation needs to occur to avoid replication of everything around it.
2. Why did we pick i18n over implementing it ourselves?
@ajulka
3, Do we store the language preference, in the session or in the database?
@rsabu
Use Case Diagram
Major design patterns and principles used
1. DRY: The i18n ‘t’ function
We observe an extreme case of DRY with the t function of i18n.
For some background, the t function of the library takes in a key representing a text and returns the content referred to by that key in the preferred language of the user. It also performs many other functions such as falling back to a backup language if the translation for the preferred language has not been configured for that specific key. Thus since this logic has to be applied at every element of the view, it would behove us to extract this logic into a reusable function which is what the designers of the i18n library have employed
The I18n library gives us an option to have many fall back options. When the required text for a given language is not found, we then move on to find the text for the next language in the chain and so on until we find it. And in the end we will put english as default language. So if the key value pair for the text is not found in none of the yml files then the text will be fetched from the English language yml file.
3. Open closed principle & Strategy Pattern
As discussed in the “Language selection" design proposal above, if the user has not selected a preferred language, we do not simply default the view to render in the application language (English). Instead, the project requirements state that for course specific screens such as the assignment view, we would need to render the view in the course’s language.
While we could implement this code into the application controller that checks the controller being access and accordingly applies overrides on the default language, this violates the open closed principle since we would need to extend this logic any time we introduce a new course specific screen. Instead a better approach is to delegate the decision of selecting the language to the view itself since the view would be most aware of whether the view is course specific or not. We can also preserve the DRYness through mix-ins.
Database Design
Database Modification ==
Test Plan
Test Details Manual Testing Scenario 1 Scenario 2 Scenario 3 Scenario 4 Scenario 5
Future Scope
1. Expand to more languages
As part of this project we have targetted Hindi as a second language, however our work makes it easy to extend to other languages as well.
2. Identify and implement the course language override on more course specific screens
As part of this project, we have introduced a generic framework by which any view can provide a preferred language in which it should be rendered, this is required by this project for the course language feature set by the instructor.
We have currently made the assignment screen display in the course’s language, however other screens such as the “Your work” screen and so on are also specific to the course could also be rendered in the course language when the user has not provided a preference.
Team
Team Members
Reuben M. V. John [rmjohn2@ncsu.edu]
Renji Joseph Sabu [rsabu@ncsu.edu]
Ashwin Das [adas9@ncsu.edu]
Arnav Julka [ajulka@ncsu.edu]
Mentor
Jialin Cui [jcui9@ncsu.edu]