i18n and L10n
in TYPO3 Flow
    Karsten Dambekalns




                         Inspiring people to
                         share
Karsten Dambekalns
co-lead of TYPO3 Neos and Flow
35 years old
lives in Lübeck, Germany
1 wife, 3 sons, 1 espresso machine
likes canoeing and climbing




                                     Inspiring people to
                                     share
Basics
 i18n is the process of making software
 localizable
 L10n means actually

 • formatting dates, numbers, …
 • translating text
 • adjusting other things (images, …)

                                Inspiring people to
                                share
Locale
 Locale instances encapsulate a locale
 identifier
 Locales define the language and formats
 to use
 Locales form a hierarchy

 • en is a parent of en_US which is a
   parent of en_US_POSIX

 • Thus items for the en_US locale that do
                                  Inspiring people to
                                 share
What you need
 A way to translate in templates
 A way to store translations of labels
 Formatters for dates, numbers, …
 An API for use in PHP




                                   Inspiring people to
                                   share
f:translate
     the way of translating you will use most

<f:translate id="my.label.1"/>

{f:translate(id: 'my.label.1')}

     translation by label is possible, but
     discouraged
   • less reliable than id-based translation
                                       Inspiring people to
                                       share
f:translate
<f:translate id="my.label.1"
 source="Registration"
 package="Acme.Demo"/>

<f:translate id="my.label.1"
  arguments="{0: 'hi'}" quantity="2"/>



                                         Inspiring people to
                                         share
f:form.select
    has translation support built in

<f:form.select options="{paymentOptions}"
translate="{by: 'id'}" />

<f:form.select options="{paymentOptions}"
translate="{by: 'id', prefix: 'payment.options.',
package: 'Acme.Demo.Translations'}" />


                                         Inspiring people to
                                         share
Message catalogs
 XML Localisation Interchange File Format
 is the standard we use
 Looked up in well-known location
 Resources/
   Private/
     Translations/
       <locale>/
        <source>.xlf


                                Inspiring people to
                                share
XLIFF basics
 An XLIFF file can hold translations for one
 locale
 It contains one or more <file> elements
 corresponding to a source
 Localizable data is stored in <trans-unit>
 elements which contain a
 <source> element to store the source
 text and a (non-mandatory) <target>


                                 Inspiring people to
                                 share
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
	

 <file original="" product-name="Acme.Demo" source-
language="en" datatype="plaintext">
	

 	

 <body>
                                Text
	

 	

 	

 <trans-unit id="my.label.1" xml:space="preserve">
                                 Text
	

 	

 	

 	

 <source>My Label 1</source>
	

 	

 	

 </trans-unit>
	

 	

 </body>
	

 </file>
</xliff>



                                                   Inspiring people to
                                                   share
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
	

 <file original="" product-name="Acme.Demo" source-
language="en" datatype="plaintext">
	

 	

 <body>
	

 	

 	

 <trans-unit id="my.label.1" xml:space="preserve">
	

 	

 	

 	

 <source>My Label 1</source>
	

 	

 	

 	

 <target>Mein Aufkleber 1</target>
	

 	

 	

 </trans-unit>
	

 	

 </body>
	

 </file>
</xliff>


                                                   Inspiring people to
                                                   share
i18n configuration
       Default locale can be set in Settings.yaml
       Locale fallback rules are configurable

TYPO3:
 Flow:
  i18n:
    defaultLocale: de
    fallbackRule:
      strict: FALSE
      order: [lv, en]


                                        Inspiring people to
                                        share
i18n configuration
       Default locale can be set in Settings.yaml
       Locale fallback rules are configurable

TYPO3:
 Flow:
  i18n:
    defaultLocale: de
    fallbackRule:
      strict: FALSE
      order: [lv, en]


                                        Inspiring people to
                                        share
Placeholder use
$this->view->assign('foo', 'QUUX');
$this->view->assign('bar', 'BAZ');


<f:translate id="my.label.3" arguments="{0: foo, 1: bar}"/>


<trans-unit id="my.label.3" xml:space="preserve">
	

 <source>I have {0} and {1}</source>
	

 <target>{1} habe ich und {0} habe ich auch</target>
</trans-unit>


                                                     Inspiring people to
                                                     share
String placeholders                        * will be available with Flow 2.0



$this->view->assign('foo', 'QUUX');
$this->view->assign('bar', 'BAZ');


<f:translate id="my.label.3" arguments="{'some': foo, 'thing': bar}"/>


<trans-unit id="my.label.3" xml:space="preserve">
	

 <source>I have {some} and {thing}</source>
	

 <target>{thing} habe ich und {some} habe ich auch</target>
</trans-unit>


                                                         Inspiring people to
                                                         share
Using formatters
$this->view->assign('currentDateAndTime', new DateTime());
$this->view->assign('currentCost', 1.25);


<f:translate id="my.label.4" arguments="{
   0: currentDateAndTime, 1: currentCost
}"/>


<source>
  At {0,datetime} it costs {1,number} monetary units
</source>

                                                  Inspiring people to
                                                  share
Plural forms
 The CLDR defines six plural forms

 • zero, one, two, few, many, other
 Different languages use more or less
 forms

 • singular and plurals for English
 • one, few and other for Polish
 • only other for Japanese
                                  Inspiring people to
                                  share
Plural forms
<f:translate id="my.label.6" quantity="{quarks->f:count()}"/>


<group id="my.label.6" restype="x-gettext-plurals">
	

 <trans-unit id="my.label.6[0]" xml:space="preserve">
   	

  <source>There is this quark</source>
	

 </trans-unit>
	

 <trans-unit id="my.label.6[1]" xml:space="preserve">
	

 	

 <source>There are these quarks</source>
	

 </trans-unit>
</group>


                                                    Inspiring people to
                                                    share
L10n of resources
 Resources can be localized as well
 The locale is part of the name

 • Image.png
 • Image.de.png
 • Image.lv.png
 Usable for all resources

 • Images, templates, …
                                  Inspiring people to
                                  share
f:resource
         uses localized resources by default*

     <img src="{f:uri.resource(path: 'Images/Image.png')}"/>

     <img src="../../../../Resources/Public/Images/Image.png"/>




* see Known

                                                  Inspiring people to
                                                  share
i18n in PHP code
 TYPO3FlowI18nTranslator

 • translateById()
 • translateByOriginalLabel()
 TYPO3FlowI18nService

 • getConfiguration()
 • getLocalizedFilename()
 TYPO3FlowI18nFormatter*

                                Inspiring people to
                                share
Setting current locale
/**
   * @param string $locale
   * @return void
   */
public function selectAction($locale = NULL) {
	

 if ($locale !== NULL) {
	

 	

 $this->i18nService->getConfiguration()->setCurrentLocale(
     	

 	

 new TYPO3FlowI18nLocale($locale)
	

 	

 );
	

 }                                             WARN   ING:
	

 $this->forward('index');                        Stupid
}
                                                    ex ample
                                                 Inspiring people to
                                                 share
Tips & Tricks
 Split catalogs at logical points
 Try to use.a.clever.id.system
 Avoid hardcoded labels from the start
 To change "original" labels simply
 translate to "original" language




                                    Inspiring people to
                                    share
Known issues
 L10n support in f:resource VH pending in
 review
 Fallback per label is missing, currently
 only done per catalog
 Overriding parts of catalogs is missing
 Model translation still missing




                                   Inspiring people to
                                   share
Thank You!
 These slides can be found at:
 http://speakerdeck.com/kdambekalns
 http://slideshare.net/kfish
 Give me feedback:
 karsten@typo3.org | karsten@dambekalns.de
 Download Flow: http://flow.typo3.org
 Follow me on twitter: @kdambekalns
 Support me using


                                  Inspiring people to
                                  share
i18n and L10n in TYPO3 Flow

i18n and L10n in TYPO3 Flow

  • 1.
    i18n and L10n inTYPO3 Flow Karsten Dambekalns Inspiring people to share
  • 2.
    Karsten Dambekalns co-lead ofTYPO3 Neos and Flow 35 years old lives in Lübeck, Germany 1 wife, 3 sons, 1 espresso machine likes canoeing and climbing Inspiring people to share
  • 3.
    Basics i18n isthe process of making software localizable L10n means actually • formatting dates, numbers, … • translating text • adjusting other things (images, …) Inspiring people to share
  • 4.
    Locale Locale instancesencapsulate a locale identifier Locales define the language and formats to use Locales form a hierarchy • en is a parent of en_US which is a parent of en_US_POSIX • Thus items for the en_US locale that do Inspiring people to share
  • 5.
    What you need A way to translate in templates A way to store translations of labels Formatters for dates, numbers, … An API for use in PHP Inspiring people to share
  • 6.
    f:translate the way of translating you will use most <f:translate id="my.label.1"/> {f:translate(id: 'my.label.1')} translation by label is possible, but discouraged • less reliable than id-based translation Inspiring people to share
  • 7.
    f:translate <f:translate id="my.label.1" source="Registration" package="Acme.Demo"/> <f:translate id="my.label.1" arguments="{0: 'hi'}" quantity="2"/> Inspiring people to share
  • 8.
    f:form.select has translation support built in <f:form.select options="{paymentOptions}" translate="{by: 'id'}" /> <f:form.select options="{paymentOptions}" translate="{by: 'id', prefix: 'payment.options.', package: 'Acme.Demo.Translations'}" /> Inspiring people to share
  • 9.
    Message catalogs XMLLocalisation Interchange File Format is the standard we use Looked up in well-known location Resources/ Private/ Translations/ <locale>/ <source>.xlf Inspiring people to share
  • 10.
    XLIFF basics AnXLIFF file can hold translations for one locale It contains one or more <file> elements corresponding to a source Localizable data is stored in <trans-unit> elements which contain a <source> element to store the source text and a (non-mandatory) <target> Inspiring people to share
  • 11.
    <?xml version="1.0" encoding="UTF-8"?> <xliffversion="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> <file original="" product-name="Acme.Demo" source- language="en" datatype="plaintext"> <body> Text <trans-unit id="my.label.1" xml:space="preserve"> Text <source>My Label 1</source> </trans-unit> </body> </file> </xliff> Inspiring people to share
  • 12.
    <?xml version="1.0" encoding="UTF-8"?> <xliffversion="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> <file original="" product-name="Acme.Demo" source- language="en" datatype="plaintext"> <body> <trans-unit id="my.label.1" xml:space="preserve"> <source>My Label 1</source> <target>Mein Aufkleber 1</target> </trans-unit> </body> </file> </xliff> Inspiring people to share
  • 13.
    i18n configuration Default locale can be set in Settings.yaml Locale fallback rules are configurable TYPO3: Flow: i18n: defaultLocale: de fallbackRule: strict: FALSE order: [lv, en] Inspiring people to share
  • 14.
    i18n configuration Default locale can be set in Settings.yaml Locale fallback rules are configurable TYPO3: Flow: i18n: defaultLocale: de fallbackRule: strict: FALSE order: [lv, en] Inspiring people to share
  • 15.
    Placeholder use $this->view->assign('foo', 'QUUX'); $this->view->assign('bar','BAZ'); <f:translate id="my.label.3" arguments="{0: foo, 1: bar}"/> <trans-unit id="my.label.3" xml:space="preserve"> <source>I have {0} and {1}</source> <target>{1} habe ich und {0} habe ich auch</target> </trans-unit> Inspiring people to share
  • 16.
    String placeholders * will be available with Flow 2.0 $this->view->assign('foo', 'QUUX'); $this->view->assign('bar', 'BAZ'); <f:translate id="my.label.3" arguments="{'some': foo, 'thing': bar}"/> <trans-unit id="my.label.3" xml:space="preserve"> <source>I have {some} and {thing}</source> <target>{thing} habe ich und {some} habe ich auch</target> </trans-unit> Inspiring people to share
  • 17.
    Using formatters $this->view->assign('currentDateAndTime', newDateTime()); $this->view->assign('currentCost', 1.25); <f:translate id="my.label.4" arguments="{ 0: currentDateAndTime, 1: currentCost }"/> <source> At {0,datetime} it costs {1,number} monetary units </source> Inspiring people to share
  • 18.
    Plural forms TheCLDR defines six plural forms • zero, one, two, few, many, other Different languages use more or less forms • singular and plurals for English • one, few and other for Polish • only other for Japanese Inspiring people to share
  • 19.
    Plural forms <f:translate id="my.label.6"quantity="{quarks->f:count()}"/> <group id="my.label.6" restype="x-gettext-plurals"> <trans-unit id="my.label.6[0]" xml:space="preserve"> <source>There is this quark</source> </trans-unit> <trans-unit id="my.label.6[1]" xml:space="preserve"> <source>There are these quarks</source> </trans-unit> </group> Inspiring people to share
  • 20.
    L10n of resources Resources can be localized as well The locale is part of the name • Image.png • Image.de.png • Image.lv.png Usable for all resources • Images, templates, … Inspiring people to share
  • 21.
    f:resource uses localized resources by default* <img src="{f:uri.resource(path: 'Images/Image.png')}"/> <img src="../../../../Resources/Public/Images/Image.png"/> * see Known Inspiring people to share
  • 22.
    i18n in PHPcode TYPO3FlowI18nTranslator • translateById() • translateByOriginalLabel() TYPO3FlowI18nService • getConfiguration() • getLocalizedFilename() TYPO3FlowI18nFormatter* Inspiring people to share
  • 23.
    Setting current locale /** * @param string $locale * @return void */ public function selectAction($locale = NULL) { if ($locale !== NULL) { $this->i18nService->getConfiguration()->setCurrentLocale( new TYPO3FlowI18nLocale($locale) ); } WARN ING: $this->forward('index'); Stupid } ex ample Inspiring people to share
  • 24.
    Tips & Tricks Split catalogs at logical points Try to use.a.clever.id.system Avoid hardcoded labels from the start To change "original" labels simply translate to "original" language Inspiring people to share
  • 25.
    Known issues L10nsupport in f:resource VH pending in review Fallback per label is missing, currently only done per catalog Overriding parts of catalogs is missing Model translation still missing Inspiring people to share
  • 26.
    Thank You! Theseslides can be found at: http://speakerdeck.com/kdambekalns http://slideshare.net/kfish Give me feedback: karsten@typo3.org | karsten@dambekalns.de Download Flow: http://flow.typo3.org Follow me on twitter: @kdambekalns Support me using Inspiring people to share