opencms days 2016: multilingual websites with opencms
TRANSCRIPT
● Build multilingual websites in OpenCms● Work on an example
● The „Tutorial“ of the OpenCms demo● Discuss the interesting bits:
● The concept of multilingual containerpages● The properties that are important for localization● Message bundles● Different approaches for the website structure
● Show new features of OpenCms 10.5
What will we do?
● User-Interface localization● Editor fields for XML Contents● Workplace menus
● Diskus pre-containerpage approaches● Talk about charset, encoding-problems and
alike
What will we NOT do?
XML contents building a web page
Content 1 Content 2
Content 3
Content 4
Content 5
Content 6
content-00003.xmlType: specification of
xmlcontent
multilingual
One page can show the same contents in different languages
index.htmlType: containerpage
unilingualSince Opencms 9.5
● Just add a translation via the content editor
● Depending on the context the correct version is chosen
How to localize XML content?
Available locale variantsnot yet existing ones marked by "[-]"
Copy locale
Next question:Why can we choose between only
four locales?
Locales: Global configuration
<opencms> <system><internationalization><!-- ... --><localesconfigured><locale>en</locale><locale>de</locale><locale>fr</locale><locale>it</locale>
</localesconfigured><localesdefault><locale>en</locale><locale>de</locale><locale>fr</locale><locale>it</locale>
</localesdefault><!-- ... -->
opencms-system.xml
All locales, the installation supports
The order locales are chosen
Typically the entries in both local lists are identical
● locale=en,de● Locales in which pages can be shown● Order is significant
● locale-available=en,de,fr,it● Locales editable via the content editor
● Locales, not globally configured are discarded
Locale configuration via properties
Next question:Is localization in content enough?
● Templates and Formatters may contain text that is not part of the content● Example: Login-Form
● Localization via message bundles
● Default Java mechanism + OpenCms extension
Localization in JSPs
<%@ taglib prefix="cms" uri="http://www.opencms.org/taglib/cms" %><%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<fmt:setLocale value="${cms.locale}" /><cms:bundle basename="org.opencms.apollo.template.schemas.login">
<!-- ... --><fmt:message key="apollo.login.title.loggedoff" /><!-- ... -->
</cms:bundle>
● Problem with default bundles● Restart of OpenCms necessary after update
● Solution● Special resource bundle types in OpenCms● Manipulation of the Java bundle mechanism to
work with “special bundles” as well● No restart required● Bundles are updated when published
Extension to Java bundles
● XML resource bundle● XML content● One file for all languages● Name scheme:bundle.base.name
● Property resource bundle● One file per language● Key-Value pairs as in normal
Java “.properties”-Files● Name scheme:bundle.base.name_{locale}
OpenCms bundle types
+ Content editor usable+ “Copy locale” available+ Everything in one place- Only one person can work on a
translation at a time- Format makes source code
editing annoying
+ Source code easily editable+ Many Translations could be
done at the same time by different people
- Several resources for one bundle
Since 10.5: Graphical editor
● OpenCms 10.5 ships with a new bundle editor● For XML and property resource bundles
The Bundle Editor
FilterSort
Switch language Select
key setEdited file
Add/delete entry
üEasy navigation and searchüOverview on all keys
üPotentially editing multiple files in one editorüNice GUI
üSupport for bundle descriptors
Add bundle descriptor
● New resource type in OpenCms 10.5● Unilingual● 3 Entries: key, default value, description● Fixes the key set for a bundle● Name scheme: {bundle base name}_desc● Szenario:
● JSP Developer creates descriptor● Translation is done by differently skilled people● Descriptor is editable only by JSP developers (via
permissions on the descriptor file)
The bundle descriptor
● Descriptor can be directly edited via bundle editor (open it with the editor)
● Descriptor can be edited when the bundle is edited● If permissions suffice
Editing bundles with descriptor
View change
● Description and default value can be used arbitrarily
● Even other editor columns can be renamed● Adjust the column names in the editor:
● Set property bundle.descriptor.messages at the descriptor to another bundle that contains keys● GUI_COLUMN_HEADER_DEFAULT_0● GUI_COLUMN_HEADER_DESCRIPTION_0● GUI_COLUMN_HEADER_KEY_0● GUI_COLUMN_HEADER_TRANSLATION_0
Flexibility of descriptors
● We have seen● Concept of container pages● Configuration of locales● Translation of contents● Localization in JSPs● OpenCms specific message bundles● The new bundle editor● Bundle descriptors
● We are missing● Approaches for a multilingual website's structure
Short summary
● Situation: We can render the same container page in different locales and get the same content
● Idea: Have just the one page for the different languages
● Problems● Same URL?● How to determine the wanted language (links?)● Localized navigation?● More general: Localized properties?
One page – all languages
OpenCms 10.5 tackles all these
problems!
OpenCms Servlet
Resolution of URLs
Cm
sSingleTreeLocaleH
andler
/sites/default/program/de
/sites/default/program/en
days.org/de/program/
days.org/en/program/
Page rendered in German
Page rendered in English
<Link><!-- ... Text ... --><URI><link internal="true" type="WEAK"> <target><![CDATA[/sites/singletree/step-1-modify-a-
page/]]></target><uuid>dff93a85-7e43-11e6-9fb2-61374ff35fd2</uuid>
</link></URI>
</Link>
Generation of Links
CmsLocalePrefixLinkSubstitutionHandler
ü Adds the locale prefix according to the context
ü Not necessary to store links differentlyx Can't link to other languages (from content)
● Extension of the <cms:link>-tag● New attribute locale
JSP API – Links from JSPs
<c:set var="availableLocales"><cms:property name="locale-available" file="search" /></c:set>
<c:set var="locales" value="${fn:split(availableLocales,',')}" /><c:set var="currentLocale">${cms.locale}</c:set><c:forEach var="locale" items="${locales}"><li><c:choose><c:when test="${currentLocale eq locale}">${locale}</c:when><c:otherwise><a href="<cms:link locale='${locale}'>
${cms.requestContext.uri}</cms:link>">${locale}</a>
</c:otherwise></c:choose></li>
</c:forEach>Implementation: A language switcher
● Adjusted locale handler
● Adjusted link generation
Single-Tree Configuration (I)
<!-- ... --><localehandler class=
"org.opencms.i18n.CmsSingleTreeLocaleHandler" /><!-- ... -->
opencms-system.xml
<!-- ... --><linksubstitutionhandler>org.opencms.staticexport.
CmsLocalePrefixLinkSubstitutionHandler</linksubstitutionhandler><!-- ... -->
opencms-importexport.xml
● Add parameter "localizationMode"
● Set property "available-locales" at the site root● Determine available locales for the language
switcher
Single-Tree Configuration (II)
<!-- ... --><site <!-- ... --> ><parameters><param name="localizationMode">singleTree</param>
</parameters></site><!-- ... -->
opencms-system.xml
● Optionally add parameter "locale.main"
● Setting this parameter improves locale switching/copying.
Single-Tree Configuration (III)
<!-- ... --><site <!-- ... --> ><parameters><param name="localizationMode">singleTree</param><param name="locale.main">en</param>
</parameters></site><!-- ... -->
opencms-system.xml
● Properties extended with locale postfix● E.g.: Title, Title_en, Title_en_GB
● Special JSP API for locale-specific access● Access from "most specific" to "least specific"
● E.g.: Title in locale "en_GB" requested● If "Title_en_GB" is found, return it. Otherwise● If "Title_en" is found, return it. Otherwise● If "Title" is found, return it. Otherwise● Return Null-Property
● If a property is searched, the result with the most specific locale, not the most direct result is returned.● E.g.: "Title_en" from the folder is returned instead of "Title" from
the contained file, if the English title for the file is searched.
Multilingual properties - Idea
● Navigation
● Page title
● Other methods
●●●
Multilingual properties - Access
<cms:navigation locale="${cms.locale}" <!-- ... --> />
${cms.titleLocale[cms.locale]}
${cms:vfs(pageContext).propertyLocale["/index.html"]["de"]["Title"]
CmsJspVfsAccessBean
<cms:resourceload <!-- ... -->><cms:resourceaccess var="res">${res.propertyLocale['de']['Title']
</cms:resourceload> CmsJspResourceAccessBean
Evaluation: Single-Tree approach
Easy to set upEasy to maintain
Pros
Publish always for every languageBad SEO behavior (same path for each language)
Cons
Use it for "Applications"
Essence
● Typically, the top folder structure of a site in OpenCms is organized according to the language, this means:● /de/ contains all German pages● /en/ contains all English pages ● …
● The top folders should have set the property “locale” to the respective locale
Idea: Language specific subtrees
+ Very flexible (subtrees can be totally different)+ No SEO problems+ Easy to understand (no implicit link adjustments)
Expected Pros and Cons
- More pages to maintain- Hard to keep versions synchronized- No real "link" between pages
OpenCms 10.5 tackles the problem with missing relations between
language versions
● Szenario● Create the site in your "main locale"● Copy pages to other locales● Translate page properties and content● Keep track of pages that are local variants /
translations of each other● New features
● "Copy page" function in Sitemap editor● "Compare locales" view in Sitemap editor● Some JSP API extensions (switch between
locales)
Szenario + new features
● Add parameters "locale.main" and "locale.secondary" to the site configuration
● You can also use the workplace tool "Site configuration"
Multi-Tree Configuration
<!-- ... --><site <!-- ... --> ><parameters><param name="locale.main">en</param><param name="locale.secondary">de,fr</param>
</parameters></site><!-- ... -->
opencms-system.xml
● Only for containerpages● Different copy modes
● "Copy": Copy all suitable elements● Option "Copy this element" on elements in
containerpages● Copied to configured place in target sitemap
● "Reuse": Reuse all elements● Copies only the containerpage
● "Automatic":● "Copy" when copying to the same locale● "Reuse" when copying to another locale (configurable)
● Page + folder are copied
The "Copy page" feature
"Copy page"is an interesting new feature even without different locales
But don't get your content scattered all across the system
Compare locales features
• Locale for which related pages are shown• Main locale marked by [*]• Switching to all locales that are configured as
main/secondary locale for the current site
Related page in the "Compared to" locale
Sitemap for the "Locale"(initially the sitemap you opened)
Context menu for linked page(of the main locale)Show any of the linked locale variants
Menu for an unlinked page
• Locale of currently shown sitemap• Main locale marked by [*]• Switching to other locales, for which a
variant of the sitemap's root page exists
● Sites view
The "Link locale variant" dialog
Site selector
Show only pages in the sitemap
Not linkable page
Already linked page
Linkable page
Colors do not indicate the "link-state" of subpages
● Locales view
The "Link locale variant" dialog
"Locale selector"switches between sitemaps localely linked to the current
sitemap (root pages)
Show all pages
Already linked page
Linkable page
Not linkable page
Colors do not indicate the "link-state" of subpages
● Suggested usage variants:● Different subsites for different locale variants● Different sites for different locale variants
(configure the same locale.main and locale.secondary for each site)
● Keep the structure of the locale variants of the site as similar as possible
● But, you can also:● Connect pages of different locales somewhere in
the systemThe GUI can handle this
Flexibility of the approach
● Group of locale variants of a page● There is one fixed main locale● Implemented via OpenCms relations from the
page variant in the secondary locale to the page variant in the main locale
● When copying from main to other locale, relation is added automatically
Background: Locale groups
de fr
en
CmsRelationType.LOCALE_VARIANT
● The mechanism is designed and tested for the default OpenCms site structure● i.e., folders with "index.html" inside● (so "page and folder" is somehow similar)
● "Do not translate" marks are only possible for the main locale
● Linking secondary locale variants is only possible via the main locale
● Publish the main locale variant always first● Delete the main locale variant always as last● For adding/deleting a link you must have write
access to the affected secondary locale variant
Restrictions of locale groups
● "Link locale variant" is also available in the explorer● Context menu à Advanced à "Link locale variant"● Only for "index.html" files (default files)
Usage without the sitemap editor
What about language switching?
Language switcher implementation
<c:set var="langlinks" value="" /><c:set var="showlang" value="false" /><c:forEach var="locentry" items="${cms.localeResource}"><c:choose><c:when test="${empty locentry.value}"></c:when><c:when test="${locentry.key == cms.locale}"><c:set var="langlinks">${langlinks}<li class="active"><ahref="#">${locentry.key}</a></li></c:set>
</c:when><c:otherwise><c:set var="showlang" value="true" /><c:set var="langlinks">${langlinks}<li><ahref="<cms:link>${locentry.value.link}</cms:link>">${locentry.key}</a></li></c:set>
</c:otherwise></c:choose>
</c:forEach><c:if test="${showlang}"><ul>${langlinks}</ul></c:if>
● CmsJspStandardContextBean(access for the currently requested resource)● Map<String, CmsJspResourceWrapper> getLocaleResource()● <c:forEach var="loc" items="${cms.localeResource}>● ${cms.localeResource["de"]}
● Locale getMainLocale()● ${cms.mainLocale}
● CmsJspVfsAccessBean(access for arbitrary resources in the VFS)● Map<String, Map<String, CmsJspResourceWrapper>> getLocaleResource()● ${cms.vfs["/index.html"]["de"]}
● Map<String, Locale> getMainLocale()● ${cms.vfs["/index.html"]
Overview: API extensions (I)
● New class: CmsJspResourceWrapper● Extension of CmsResource with methods● String getLink()
● Locale getMainLocale()
● Map<String, CmsJspResourceWrapper> getLocaleResource()
● Return value of all new JSP API methods that return resources
● Return value of altered method● CmsJspVfsAccessBean.getReadResource()
Overview: API extensions (II)
Evaluation: Multi-Tree approach
Easy to understandVery flexible
Maybe already your current setupNo SEO problems
Language variants can be published separatelyGreat management tools in OpenCms 10.5
Pros
Takes some setup timeMaintenance overhead
Cons
Use it for all "Non-Applications"Essence
● New bundle editor● Bundle descriptors● "Copy page" for containerpages● Multilingual sites: Single-tree support
● Locale and link substitution handler● Multilingual properties (incl. extended JSP API)
● Multilingual sites: Enhanced multi-tree support● Locale groups● "Compare locale" tab in the Sitemap editor● Extended JSP API
● Enhanced content editing (auto-copy locale)
Summary – OpenCms 10.5 features
Message of the talk:We greatly improved the support
for multilingual websites in OpenCms 10.5
Daniel SeidelAlkacon Software GmbH
http://www.alkacon.comhttp://www.opencms.org
Thank you very much for your attention!