Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are a lot of things that need to be taken care of while internationalizing application:</p> <p><strong>Locale detection</strong></p> <p>The very first thing you need to think about is to detect end-user's Locale. Depending on what you want to support it might be easy or a bit complicated.</p> <ol> <li>As you surely know, web browsers tend to send end-user's preferred language via HTTP Accept-Language header. Accessing this information in the Servlet might be as simple as calling <code>request.getLocale()</code>. If you are not planning to support any fancy <a href="https://softwareengineering.stackexchange.com/q/15050/2554">Locale Detection workflow</a>, you might just stick to this method.</li> <li>If you have User Profiles in your application, you might want to add Preferred Language and Preferred Formatting Locale to it. In such case you would need to switch Locale after user logs in.</li> <li>You might want to support URL-based language switching (for example: <a href="http://deutsch.example.com/" rel="nofollow noreferrer">http://deutsch.example.com/</a> or <a href="http://example.com?lang=de" rel="nofollow noreferrer">http://example.com?lang=de</a>). You would need to set valid Locale based on URL information - this could be done in various ways (i.e. URL Filter).</li> <li>You might want to support language switching (selecting it from drop-down menu, or something), however I would not recommend it (unless it is combined with point 3).</li> </ol> <p><strong><em>JSTL</em></strong> approach could be sufficient if you just want to support first method or if you are not planning to add any additional dependencies (like Spring Framework).</p> <p>While we are at <strong><em>Spring Framework</em></strong> it has quite a few nice features that you can use both to detect Locale (like <a href="http://static.springsource.org/spring/docs/1.2.x/api/org/springframework/web/servlet/i18n/CookieLocaleResolver.html" rel="nofollow noreferrer">CookieLocaleResolver</a>, <a href="http://static.springsource.org/spring/docs/1.2.x/api/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.html" rel="nofollow noreferrer">AcceptHeaderLocaleResolver</a>, <a href="http://static.springsource.org/spring/docs/1.2.x/api/org/springframework/web/servlet/i18n/SessionLocaleResolver.html" rel="nofollow noreferrer">SessionLocaleResolver</a> and <a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.html" rel="nofollow noreferrer">LocaleChangeInterceptor</a>) and externalizing strings and formatting messages (see <a href="http://static.springsource.org/spring/docs/1.2.x/taglib/tag/MessageTag.html" rel="nofollow noreferrer">spring:message tab</a>).<br> Spring Framework would allow you to quite easily implement all the scenarios above and that is why I prefer it.</p> <p><strong>String externalization</strong></p> <p>This is something that should be easy, right? Well, mostly it is - just use appropriate tag. The only problem you might face is when it comes to externalizing client-side (JavaScript) texts. There are several possible approaches, but let me mention these two:</p> <ol> <li>Have each JSP written array of translated strings (with message tag) and simply access that array in client code. This is easier approach but less maintainable - you would need to actually write valid strings from valid pages (the ones that actually reference your client-side scripts). I have done that before and believe me, this is not something you want to do in large application (but it is probably the best solution for small one).</li> <li>Another approach may sound hard in principle but it is actually way easier to handle in the future. The idea is to centralize strings on client side (move them to some common JavaScript file). After that you would need to implement your own Servlet that will return this script upon request - the contents should be translated. You won't be able to use JSTL here, you would need to get strings from Resource Bundles directly.<br> It is much easier to maintain, because you would have one, central point to add translatable strings.</li> </ol> <p><strong>Concatenations</strong></p> <p>I hate to say that, but concatenations are really painful from Localizability perspective. They are very common and most people don't realize it.</p> <p>So what is concatenation then? </p> <p>On the principle, each English sentence need to be translated to target language. The problem is, it happens many times that correctly translated message uses different word order than its English counterpart (so English "Security policy" is translated to Polish "Polityka bezpieczeństwa" - "policy" is "polityka" - the order is different).</p> <p>OK, but how it is related to software?</p> <p>In web application you could concatenate Strings like this:</p> <pre><code>String securityPolicy = "Security " + "policy"; </code></pre> <p>or like this:</p> <pre><code>&lt;p&gt;&lt;span style="font-weight:bold"&gt;Security&lt;/span&gt; policy&lt;/p&gt; </code></pre> <p>Both would be problematic. In the first case you would need to use <code>MessageFormat.format()</code> method and externalize strings as (for example) <code>"Security {0}"</code> and <code>"policy"</code>, in the latter you would externalize the contents of the whole paragraph (p tag), <strong>including</strong> span tag. I know that this is painful for translators but there is really no better way.<br> Sometimes you have to use dynamic content in your paragraph - JSTL fmt:format tag will help you here as well (it works lime MessageFormat on the backend side).</p> <p><strong>Layouts</strong></p> <p>In localized application, it often happens that translated strings are way longer than English ones. The result could look very ugly. Somehow, you would need to fix styles. There are again two approaches:</p> <ol> <li>Fix issues as they happen by adjusting common styles (and pray that it won't break other languages). This is very painful to maintain.</li> <li>Implement CSS Localization Mechanism. The mechanism I am talking about should serve default, language-independent CSS file and per-language overrides. The idea is to have override CSS file for each language, so that you can adjust layouts on-demand (just for one language). In order to do that, default CSS file, as well as JSP pages must not contain <code>!important</code> keyword next to any style definitions. If you really have to use it, move them to language-based en.css - this would allow other languages to modify them.</li> </ol> <p><strong>Culture specific issues</strong></p> <p>Avoid using graphics, colors and sounds that might be specific for western culture. If you really need it, please provide means of Localization. Avoid direction-sensitive graphics (as this would be a problem when you try to localize to say Arabic or Hebrew). Also, do not assume that whole world is using the same numbers (i.e. not true for Arabic).</p> <p><strong>Dates and time zones</strong></p> <p>Handling dates in times in Java is to say the least not easy. If you are not going to support anything else than Gregorian Calendar, you could stick to built-in Date and Calendar classes. You can use JSTL fmt:timeZone, fmt:formatDate and fmt:parseDate to correctly set time zone, format and parse date in JSP.</p> <p>I strongly suggest to use fmt:formatDate like this:</p> <pre><code>&lt;fmt:formatDate value="${someController.somedate}" timeZone="${someController.detectedTimeZone}" dateStyle="default" timeStyle="default" /&gt; </code></pre> <p>It is important to covert date and time to valid (end user's) time zone. Also it is quite important to convert it to easily understandable format - that is why I recommend default formatting style.<br> BTW. Time zone detection is not something easy, as web browsers are not so nice to send anything. Instead, you can either add preferred time zone field to User preferences (if you have one) or get current time zone offset from web browser via client side script (see <a href="http://www.w3schools.com/jsref/jsref_obj_date.asp" rel="nofollow noreferrer">Date object's methods</a>)</p> <p><strong>Numbers and currencies</strong></p> <p>Numbers as well as currencies should be converted to local format. It is done in the similar way to formatting dates (parsing is also done similarly):</p> <pre><code>&lt;fmt:formatNumber value="1.21" type="currency"/&gt; </code></pre> <p><strong>Compound messages</strong></p> <p>You already have been warned not to concatenate strings. Instead you would probably use <code>MessgageFormat</code>. However, I must state that you should minimize use of compound messages. That is just because target grammar rules are quite commonly different, so translators might need not only to re-order the sentence (this would be resolved by using placeholders and <code>MessageFormat.format()</code>), but translate the whole sentence in different way based on what will be substituted. Let me give you some examples:</p> <pre><code>// Multiple plural forms English: 4 viruses found. Polish: Znaleziono 4 wirusy. **OR** Znaleziono 5 wirusów. // Conjugation English: Program encountered incorrect character | Application encountered incorrect character. Polish: Program napotkał nieznaną literę | Aplikacja napotkała nieznaną literę. </code></pre> <p><strong>Character encoding</strong></p> <p>If you are planning to Localize into languages that does not support ISO 8859-1 code page, you would need to support Unicode - the best way is to set page encoding to UTF-8. I have seen people doing it like this:</p> <pre><code>&lt;%@ page contentType="text/html; charset=UTF-8" %&gt; </code></pre> <p>I must warn you: this is <strong><em>not enough</em></strong>. You actually need this declaration:</p> <pre><code>&lt;%@page pageEncoding="UTF-8" %&gt; </code></pre> <p>Also, you would still need to declare encoding in the page header, just to be on the safe side:</p> <pre><code>&lt;META http-equiv="Content-Type" content="text/html;charset=UTF-8"&gt; </code></pre> <p>The list I gave you is not exhaustive but this is good starting point. Good luck :) </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload