Internationalization in the Java Stack Matt Wheeler.

18
Internationalization in the Java Stack Matt Wheeler

Transcript of Internationalization in the Java Stack Matt Wheeler.

Page 1: Internationalization in the Java Stack Matt Wheeler.

Internationalization in the Java StackMatt Wheeler

Page 2: Internationalization in the Java Stack Matt Wheeler.

Notes

• This is a training NOT a presentation• Please ask questions• Prerequisites

– Introduction to Java Stack– Introduction to Spring– Basic Java and XML skills– Installed LdsTech IDE (or other equivalent – good luck

there ;)

Page 3: Internationalization in the Java Stack Matt Wheeler.

Overview

• Stack provided internationalizaton tools• Message source expression language resolver• JS Message source

• Internationalization best practices• Internationalization testing

• Dynamic pseudo translation

Page 4: Internationalization in the Java Stack Matt Wheeler.

Expression Language Resolver

• Provide message resolver can be utilized in EL

• http://code.lds.org/maven-sites/stack/module.html?module=web-spring/#El_Message_Source

<%@ taglib prefix="web-spring" uri="http://code.lds.org/web/spring" %>

<!-- This makes the internationalized properties of the default MessageSource available as a map in the specified scope--><web-spring:message-source var="messages" scope="request"/>

<!- Reference the messages in EL by key -->${messages['abc.def.ghi']}

Page 5: Internationalization in the Java Stack Matt Wheeler.

JavaScript Source

• JS Configuration<bean id="messageSourceController" class="org.lds.stack.web.spring.i18n.MessageSourceController"> <property name="messageSource" ref="messageSource" /></bean>

<!-- Create adapter to handle all non-annotation controllers --><bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

<!-- Map the properties url to the controller --><bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/messageSource.js">messageSourceController</prop> </props> </property> <property name="order" value="#{T(org.springframework.core.Ordered).HIGHEST_PRECEDENCE}"/></bean>

Page 6: Internationalization in the Java Stack Matt Wheeler.

MessageSource with JS

• Usage in a JSP page<script charset="utf-8" src="${pageContext['request'].contextPath}/messageSource.js" type="text/javascript"></script>

<script type="text/javascript"> alert(msgs['abc']);</script>

Page 7: Internationalization in the Java Stack Matt Wheeler.

Some I18n Best Practices

• Externalize ALL translatable text• Do not concatenate translations• Create duplicate / separate resources• Avoid text in images

Page 8: Internationalization in the Java Stack Matt Wheeler.

Externalize ALL Text

• Page label - "Name: “• "Name:" including the colon, and not just "Name" externalized

– Otherwise require contatenation - the “Name”coming out of the bundle with : on the page

• : and associated formatting can be different in different languages– It might also be in a different order

Page 9: Internationalization in the Java Stack Matt Wheeler.

Do NOT Concatenate Translations

• For example:

• Attempted usage

key1=Someone namedkey2=likes hiking.

${messages['key1']} Billy ${messages['key2']}

Page 10: Internationalization in the Java Stack Matt Wheeler.

More Correct Way

• Create a single string with replaceable parameters

• Sentence maintains context – Parameters can be moved around to accommodate

language grammar• For example:

• And then it will be used as follows:

key=Someone named {0} likes hiking.

<spring:message code="key" arguments="${hikersName}" text="Default text."/>

Page 11: Internationalization in the Java Stack Matt Wheeler.

Create Separate Resources

• Counter intuitive to code reuse concept• Same English strings should not be shared

• Within the same application, or even the same page• Create a separate key value pair for each occurrence

• Words change based on context• Concept of masculine and/or feminine, age classes, … • Or usage

• Similar English words may not be similar in another language

Page 12: Internationalization in the Java Stack Matt Wheeler.

Avoid Placing Text in Images

• An image that contains text will require a new image for each language

• It will also require a custom way to load the image• Impose the text over the image, using .css or other ingenious

alternative– Then the text can be stored in the resource bundles with all other

strings– And it won’t require a new image for each language

Page 13: Internationalization in the Java Stack Matt Wheeler.

I18n Testing (Dynamic Pseudo Translation)

• Configured to translate for specified locales• Simplifies testing

– Expansion– Special characters– Completeness– zz locale

• http://code.lds.org/maven-sites/stack/module.html?module=web-spring/#Pseudo_Translation_Message_Source_Facade

Page 14: Internationalization in the Java Stack Matt Wheeler.

Dynamic Pseudo Translation

• The trick (delegate)<!-- Application Message Bundle --><bean id="messageSource" class="org.lds.stack.web.spring.i18n.message.PseudoMessageSourceFacade"> <constructor-arg ref="delegatingMessageSource" /></bean>

<bean id="delegatingMessageSource"    class="org.springframework.context.support.ReloadableResourceBundleMessageSource">    <property name="basename"> <list> <value>classpath:messages</value> </list> </property>    <property name="defaultEncoding" value="UTF-8"/></bean>

Page 15: Internationalization in the Java Stack Matt Wheeler.

Lab

Page 16: Internationalization in the Java Stack Matt Wheeler.

asdf

Page 17: Internationalization in the Java Stack Matt Wheeler.

Lab 1: Internationalize a page

https://tech.lds.org/wiki/Introduction_to_Spring#Lab_2_Dependency_Inje

ction

Page 18: Internationalization in the Java Stack Matt Wheeler.

Credit where credit is due

• http://www.ibm.com/developerworks/java/tutorials/j-i18n/section2.html