#LyX 1.6.1 created this file. For more info see http://www.lyx.org/
\lyxformat 345
\begin_document
\begin_header
\textclass book
\use_default_options false
\language english
\inputencoding auto
\font_roman default
\font_sans default
\font_typewriter default
\font_default_family default
\font_sc false
\font_osf false
\font_sf_scale 100
\font_tt_scale 100
\graphics default
\paperfontsize default
\spacing single
\use_hyperref false
\papersize default
\use_geometry false
\use_amsmath 1
\use_esint 1
\cite_engine basic
\use_bibtopic false
\paperorientation portrait
\secnumdepth 3
\tocdepth 3
\paragraph_separation indent
\defskip medskip
\quotes_language english
\papercolumns 1
\papersides 1
\paperpagestyle default
\tracking_changes false
\output_changes false
\author ""
\author ""
\end_header
\begin_body
\begin_layout Chapter
Internationalization
\begin_inset CommandInset label
LatexCommand label
name "cha:Internationalization"
\end_inset
\end_layout
\begin_layout Standard
The ability to display pages to users of multiple languages is a common
feature of many web frameworks.
Lift builds on the underlying Java I18N foundations
\begin_inset Foot
status open
\begin_layout Plain Layout
Primarily java.util.Locale and java.util.ResourceBundle
\end_layout
\end_inset
to provide a simple yet flexible means for using Locales and translated
strings in your app.
Locales are used to control not only what language the text is in that's
presented to the user, but also number and date formatting, among others.
If you want more details on the underlying foundation of Java I18N we suggest
you visit the Internationalization Homepage at
\begin_inset CommandInset href
LatexCommand href
target "http://java.sun.com/javase/technologies/core/basic/intl/"
\end_inset
.
\end_layout
\begin_layout Section
Resource Bundles
\begin_inset CommandInset label
LatexCommand label
name "sec:Resource-Bundles"
\end_inset
\end_layout
\begin_layout Standard
Resource bundles are sets of property files
\begin_inset Foot
status open
\begin_layout Plain Layout
Technically, they can have other formats, but Lift generally only deals
with PropertyResourceBundles
\end_layout
\end_inset
that contain keyed strings for your application to use in messages.
In addition to the key/value pair contents of the files, the filename itself
is significant.
When a ResourceBundle is specified by name, the base name is used as the
default, and additional files with names of the form
\begin_inset Quotes eld
\end_inset
<base name>_<ISO language code>
\begin_inset Quotes erd
\end_inset
can be used to specify translations of the default strings in a given language.
As an example, consider listing
\begin_inset CommandInset ref
LatexCommand ref
reference "lst:Default-door-bundle"
\end_inset
, which specifies a default resource bundle for an application that reports
the status of a door (open or closed).
\end_layout
\begin_layout Standard
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
\begin_inset Caption
\begin_layout Plain Layout
Default door bundle
\begin_inset CommandInset label
LatexCommand label
name "lst:Default-door-bundle"
\end_inset
\end_layout
\end_inset
\end_layout
\begin_layout Plain Layout
openStatus=The door is open
\end_layout
\begin_layout Plain Layout
closedStatus=The door is closed
\end_layout
\end_inset
\end_layout
\begin_layout Standard
Suppose this file is called
\begin_inset Quotes eld
\end_inset
DoorMessages.properties
\begin_inset Quotes erd
\end_inset
; we can provide an additional translation for Spanish by creating a file
called
\begin_inset Quotes eld
\end_inset
DoorMessages_es.properties
\begin_inset Quotes erd
\end_inset
, shown in listing
\begin_inset CommandInset ref
LatexCommand ref
reference "lst:Spanish-door-bundle"
\end_inset
.
\end_layout
\begin_layout Standard
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
\begin_inset Caption
\begin_layout Plain Layout
Spanish door bundle
\begin_inset CommandInset label
LatexCommand label
name "lst:Spanish-door-bundle"
\end_inset
\end_layout
\end_inset
\end_layout
\begin_layout Plain Layout
openStatus=La puerta está abierta
\end_layout
\begin_layout Plain Layout
closedStatus=La puerta está cerrada
\end_layout
\end_inset
\end_layout
\begin_layout Standard
When you want to retrieve a message (covered in the next two sections) Lift
will check the current Locale and see if there's a specialized ResourceBundle
available for it.
If so, it uses the messages in that file; otherwise, it uses the default
bundle.
\end_layout
\begin_layout Standard
Lift supports using multiple resource bundle files so that you can break
your messages up into functional groups.
You specify this by setting the
\family typewriter
LiftRules.resourceNames
\family default
property to a list of the base names (without a language or
\begin_inset Quotes eld
\end_inset
.properties
\begin_inset Quotes erd
\end_inset
extension):
\end_layout
\begin_layout LyX-Code
LiftRules.resourceNames = "DoorMessages" ::
\end_layout
\begin_layout LyX-Code
"DoorknobMessages" :: Nil
\end_layout
\begin_layout Standard
The order that you define the resource bundle names is the order that they'll
be searched for keys.
The message properties files should be located in your
\family typewriter
WEB-INF/classes
\family default
folder so that they are accessible from Lift's classloader
\begin_inset Foot
status open
\begin_layout Plain Layout
The properties files are retrieved with ClassLoader.getResourceAsStream
\end_layout
\end_inset
; if you're using Maven this will happen if you put your files in the
\family typewriter
src/main/resources
\family default
directory.
\end_layout
\begin_layout Section
Localized Strings in Scala Code
\end_layout
\begin_layout Standard
Retrieving localized strings in your Scala code is primarily performed using
the
\family typewriter
S.?
\family default
method.
When invoked with one argument the resource bundles are searched for a
key matching the given argument.
If a matching value is found it's returned.
If it can't be found then Lift calls
\family typewriter
LiftRules.localizationLookupFailureNotice
\family default
on the (key, current Locale) pair and then simply returns the key.
If you call
\family typewriter
S.?
\family default
with more than one argument, the first argument is still the key to look
up, but any remaining arguments are used as format parameters for String.format
executed on the retrieved value.
For example, listing
\begin_inset CommandInset ref
LatexCommand ref
reference "lst:Formatted-bundles"
\end_inset
shows a sample bundle file and the associated Scala code for using message
formatting.
\end_layout
\begin_layout Standard
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
\begin_inset Caption
\begin_layout Plain Layout
Formatted bundles
\begin_inset CommandInset label
LatexCommand label
name "lst:Formatted-bundles"
\end_inset
\end_layout
\end_inset
\end_layout
\begin_layout Plain Layout
// bundle
\end_layout
\begin_layout Plain Layout
tempMsg=The current temperature is %0.1 degrees
\end_layout
\begin_layout Plain Layout
// code
\end_layout
\begin_layout Plain Layout
var currentTmp : Double = getTemp()
\end_layout
\begin_layout Plain Layout
Text(S.?("tempMsg", currentTemp))
\end_layout
\end_inset
\end_layout
\begin_layout Standard
Lift also provides the
\family typewriter
S.??
\family default
method, which is similar to
\family typewriter
S.?
\family default
but uses the ResourceBundle for internal Lift strings.
Lift's resource-bundles are located in the i18n folder with the name lift-core.p
roperties The resource-bundle name is given by LiftRules.liftCoreResourceName
variable.
Generally you won't use this method.
\end_layout
\begin_layout Section
Localized Strings in Templates
\end_layout
\begin_layout Standard
You can add localized strings directly in your templates through the <lift:loc
/> tag.
You can either provide a locid attribute on the tag which is used as the
lookup key, or if you don't provide one, the contents of the tag will be
used as the key.
In either case, if the key can't be found in any resource bundles, the
contents of the tag will be used.
Listing
\begin_inset CommandInset ref
LatexCommand ref
reference "lst:Using-the-loc-tag"
\end_inset
shows some examples of how you could use lift:loc.
In both examples, assume that we're using the resource bundle shown in
listing
\begin_inset CommandInset ref
LatexCommand ref
reference "lst:Spanish-door-bundle"
\end_inset
.
The fallthrough behavior lets us put a default text (English) directly
in the template, although for consistency you should usually provide an
explicit bundle for all languages.
\end_layout
\begin_layout Standard
\begin_inset listings
lstparams "language=XML"
inline false
status open
\begin_layout Plain Layout
\begin_inset Caption
\begin_layout Plain Layout
Using the loc tag
\begin_inset CommandInset label
LatexCommand label
name "lst:Using-the-loc-tag"
\end_inset
\end_layout
\end_inset
\end_layout
\begin_layout Plain Layout
<!-- using explicit key -->
\end_layout
\begin_layout Plain Layout
<lift:loc locid="openStatus">The door is open</lift:loc>
\end_layout
\begin_layout Plain Layout
\end_layout
\begin_layout Plain Layout
<!-- should be the same result -->
\end_layout
\begin_layout Plain Layout
<lift:loc>openStatus</lift:loc>
\end_layout
\end_inset
\end_layout
\begin_layout Section
Calculating Locale
\end_layout
\begin_layout Standard
The Locale for a given request is calculated by the function set in
\family typewriter
LiftRules.localeCalculator
\family default
, a
\begin_inset Formula $(Box[HttpServletRequest])\Rightarrow Locale$
\end_inset
.
The default behavior is to call getLocale on the HttpServletRequest, which
allows the server to set it if your clients send locale preferences.
If that call returns null, then Locale.getDefault is used.
You can provide your own function for calculating locales if you desire.
\end_layout
\end_body
\end_document