i18n Tasks per Functional Area
Functional area tasks page.
Localize texts – JSP and JS files
- the JSP and JS files for functional areas of the Mifos application are located under /mifos/src/org/mifos/doc-root/application/
- the message bundles (properties files for localization) are all in the directory /mifos/src/org/mifos/config/localizedResources/
- [note: I think the idea is that UIResources.properties has generic keys and values for common UI phrases, such as "submit", "cancel", "Fields marked with an asterisk are required." etc. and that files such as SavingsUIResources.properties have more specific keys and values that pertain only to that functional area, e.g. "View deposit due details". Clearly, this pattern is not always followed and there appears to be a fair amount of duplication of keys across the files currently. It is desirable to put the commonly used terms in one place, so that they can be translated and updated more efficiently, but not a must-have.]
- Go through the *.jsp files and look for hard-coded text. If there is any move it the properties file for the corresponding message bundle. For example, the key may be in UIResources.properties file or may need to be added to that file. There is a custom jsp tag called mifos:mifoslabel which handles retrieval of message values for a given key. For example:
- In the page changeaccountstatus.jsp the hard-coded text "Approved" was found in this line <html-el:option value="3">Approved</html-el:option>. Since the resource file for this page is LoanUIResources.properties, first check if "Approved" is already defined there.
- If there is not already a message key for this value, then define a new one, such as loan.approved=Approved. Relace Approved in the jsp file with <mifos:mifoslabel name="loan.approved" /> so the line above will look like this <html-el:option value="3"><mifos:mifoslabel name=" loan.approved " /></html-el:option>.
- Sometimes the hardcoded text may come from a java file, such as ConfigurationConstants.java Client replace the text with <mifos:mifoslabel name="$
Unknown macro: {ConfigurationConstants.CLIENT}" />.- Another example is <option value="1" select>Select</option>. "Select" is hard-coded text and needs to be replaced. The hard-coded text can be the name of a button, too.
- Go through the *.jsp files and look at the javascripts embedded on the pages to see if there are any texts to be localized. One of the candidate is alert('....') messages. These alert messages should be removed and the error handling should be done on the ActionForm (Looks like there are no more alert messages in the javascript, but just check to make sure).
- Go through the *.js files and look at the javascripts for texts to be localized.
- While going through jsps and js files, it is a good time to check that the license is properly included, showing only in jsp comments but not html comments, for faster download times on slow internet connections. See MifosLicensing
- Note: When verifying if Unicode is displayed correctly in the browser you need to select View -> Encoding -> Unicode (UTF-8).
- JSPs can compound a phrase using a series of <mifos:mifoslabel> calls. This creates a certain rigidity in how this phrase can be translated into other languages, forcing the localization into incorrect grammar. These should be compacted into one <mifos:mifoslabel> displaying the entire phrase.
- When the aforementioned concatenation happens around a mifoslabel database call like <mifos:mifoslabel name="$
Unknown macro: {ConfigurationConstants.CENTER}" />" />, the same kind of localization needs to happen, but using a JSTL format api.
- For a sentence made like
- <mifos:mifoslabel name="Center.change" bundle="CenterUIResources"/>
- <mifos:mifoslabel name="$
- <mifos:mifoslabel name="Center.Membership" bundle="CenterUIResources"/>
- which would be "Change Center membership", it would look like:
- <fmt:message key="Center.changeMembership">
- <fmt:param><mifos:mifoslabel name="$
Unknown macro: {ConfigurationConstants.CENTER}" /></fmt:param>- </fmt:message>
- where Center.changeMembership=Change
Unknown macro: {0}is.membership.
- When an apostrophe ' or a left curly bracket { needs to be included in the string, it can be escaped with an apostrophe. So to display the string "he's" it will need to be "he''s" in the properties file.
- So the resulting string representing Center would be put into the spot where
- For this to work, the fmt tags must be defined, as well as the locale and the bundle, like so:
- <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
- <fmt:setLocale value='$
Unknown macro: {sessionScope["LOCALE"]}'/>- <fmt:setBundle basename="org.mifos.config.localizedResources.LoanUIResources"/>
Action Form and Action java files
- Look for hard-coded exception messages. For example if the LoanAccountAction .java has this code throw new RuntimeException ("ChartOfAcctionsCache already contains an account with id: " + coa.getCategoryId());
Replace this with throw new RuntimeException ("errors.duplicateAccountId"); where errors.duplicateAccountId is defined in the LoanUIResources .properties as errors.duplicateAccountId= ChartOfAcctionsCache already contains an account with id:
- Search for addError and errors.add and see if the parameters to this method are hard-coded texts or string constants. These hard-coded texts and string constants need to be moved to properties files.
1. Example of hard-coded text is addError (errors, "officeId", "errors.mandatoryselect", "Branch"); The error.mandatoryselect is defined in the LoanUIResources .properties as Please select the {0}so the text "Branch" is the parameter to the string Please select the {0}. Branch needs to be moved to theLoanUIResources.properties and define as loan.branch=Branch. So the code above becomes: Locale locale= getUserContext(request).getPreferredLocale(); ResourceBundleresources =ResourceBundle .getBundle(FilePaths .LOAN_UI_RESOURCE_PROPERTYFILE, locale); String branch = resources.getString("loan.branch"); and the addError(errors, "officeId", "errors.mandatoryselect", branch);
2. Example of string constant is addError(errors,LoanConstants .CUSTOMER, LoanConstants .CUSTOMERNOTSELECTEDERROR, ConfigurationConstants .CLIENT,ConfigurationConstants .GROUP); LoanConstants .CUSTOMERNOTSELECTEDERROR is errors.customernotselected and errors.customernotselected points to the string Please select a {0\ / {1}
which has 2 parametersConfigurationConstants.CLIENT,ConfigurationConstants .GROUP So the constantConfigurationConstants.CLIENT would be replaced by the method call getLabel(ConfigurationConstants .CLIENT, userContext).
3. Tag/UI/UIHelper folder: review the java files which serve as the tags to the functional area pages to generate html code. Look for the hard-coded texts the tags generate to the pages and move them to properties files. Example: html.text("Edit"); in the fileCustomFieldListTag.java.
4. Look for string concatenations of message keys or values. For example "there are" + n + "loans". In some languages, the translation for this phrase may have a different ordering of these words in the English phrase. So, it is better to do "there are
loans" as a text format, rather than by concatenating strings. For example, this looks like a grammar problem waiting to happen in some other language, from SavingsUIResources.properties:
Savings.ANew=A new Savings.for= for Savings.accountAssigned= has been assigned account #
Fixing button sizes so that they will display localized texts properly
Open a jsp file and search for style="width:. Get to that location and see if there is a property styleClass="buttn" or styleClass="insidebuttn" or styleClass="cancelbuttn" which means that is a button. If so remove the style="width:...." property. For example the search leads to <html-el:submit style="WIDTH: 60px" styleClass="buttn">. So remove the style="WIDTH: 60px" and this will become <html-el:submit styleClass="buttn">.