Translating Forms¶
If a form has been set up, all elements will use the labels, placeholders and so forth as configured. To have the form translated depending on the current locale, you need to configure a package to load the translations from and add the translations as XLIFF files.
Configuration¶
The package to load the translations from is configured in the form preset being used. The simplest way to configure it is this:
Neos:
Form:
presets:
default:
formElementTypes:
'Neos.Form:Base':
renderingOptions:
translationPackage: 'AcmeCom.SomePackage'
Of course it can be set in a custom preset in the same way.
The translation of validation error messages uses the Neos.Flow package by default, to avoid having to
copy the validation errors message catalog to all packages used for form translation. If you want to
adjust those error messages as well, copy ValidationErrors.xlf
to your package and set the option
validationErrorTranslationPackage
to your package key.
XLIFF files¶
The XLIFF files follow the usual rules, the Main
catalog is used. The Form package comes with the following
catalog (Main.xlf
):
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file original="" product-name="Neos.Form" source-language="en" datatype="plaintext">
<body>
<trans-unit id="forms.navigation.previousPage" xml:space="preserve">
<source>Previous page</source>
</trans-unit>
<trans-unit id="forms.navigation.nextPage" xml:space="preserve">
<source>Next page</source>
</trans-unit>
<trans-unit id="forms.navigation.submit" xml:space="preserve">
<source>Submit</source>
</trans-unit>
</body>
</file>
</xliff>
It should be copied to make sure the three expected units are available and can then be amended by your own units.
For most reliable translations, the units should be given id properties based on the form configuration. The schema is as follows:
- forms.navigation.nextPage
- In multi-page forms this is used for the navigation.
- forms.navigation.previousPage
- In multi-page forms this is used for the navigation.
- forms.navigation.submitButton
- In forms this is used for the submit button.
Forms and sections can have their labels translated using this, where where {identifier}
is the identifier
of the page or section itself:
- forms.pages.{identifier}.label
- The label used for a form page.
- forms.sections.{identifier}.label
- The label used for a form section.
The actual elements of a form have their id constructed by appending one of the following to
forms.elements.{identifier}.
, where {identifier}
is the identifier of the form element
itself:
- label
- The label for an element.
- placeholder
- The placeholder for an element, if applicable.
- description
- dkjsadhsajk
- text
- The text of a
StaticText
element. - confirmationLabel
- Used in the
PasswordWithConfirmation
element. - passwordDescription
- Used in the
PasswordWithConfirmation
element.
The labels of radio buttons and select field options can be translated using the following schema,
where {identifier}
is the identifier of the form element itself and value
is the value assigned
to the option:
- forms.elements.{identifier}.options.{value}
- Used to translate labels of radio buttons and select field entries.
Complete example¶
This is the example form used elsewhere in this documentation:
- Contact Form (Form)
- Page 01 (Page)
- Name (Single-line Text)
- Email (Single-line Text)
- Message (Multi-line Text)
Assume it is configured like this using YAML:
type: 'Neos.Form:Form'
identifier: 'contact'
label: 'Contact form'
renderables:
-
type: 'Neos.Form:Page'
identifier: 'page-one'
renderables:
-
type: 'Neos.Form:SingleLineText'
identifier: name
label: 'Name'
validators:
- identifier: 'Neos.Flow:NotEmpty'
properties:
placeholder: 'Please enter your full name'
-
type: 'Neos.Form:SingleLineText'
identifier: email
label: 'Email'
validators:
- identifier: 'Neos.Flow:NotEmpty'
- identifier: 'Neos.Flow:EmailAddress'
properties:
placeholder: 'Enter a valid email address'
-
type: 'Neos.Form:MultiLineText'
identifier: message
label: 'Message'
validators:
- identifier: 'Neos.Flow:NotEmpty'
properties:
placeholder: 'Enter your message here'
Note
You may leave out label
and placeholder
if you use id-based matching for the translation.
Be aware though, that you will get empty labels and placeholders in case the translation fails or is not
available.
The following XLIFF would allow to translate the form:
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file original="" product-name="Neos.Form" source-language="en" datatype="plaintext">
<body>
<trans-unit id="forms.navigation.previousPage" xml:space="preserve">
<source>Previous page</source>
</trans-unit>
<trans-unit id="forms.navigation.nextPage" xml:space="preserve">
<source>Next page</source>
</trans-unit>
<trans-unit id="forms.navigation.submit" xml:space="preserve">
<source>Submit</source>
</trans-unit>
<trans-unit id="forms.pages.page-one" xml:space="preserve">
<source>Submit</source>
</trans-unit>
<trans-unit id="forms.elements.name.label" xml:space="preserve">
<source>Name</source>
</trans-unit>
<trans-unit id="forms.elements.name.placeholder" xml:space="preserve">
<source>Please enter your full name</source>
</trans-unit>
<trans-unit id="forms.elements.email.label" xml:space="preserve">
<source>Email</source>
</trans-unit>
<trans-unit id="forms.elements.email.placeholder" xml:space="preserve">
<source>Enter a valid email address</source>
</trans-unit>
<trans-unit id="forms.elements.message.label" xml:space="preserve">
<source>Message</source>
</trans-unit>
<trans-unit id="forms.elements.message.placeholder" xml:space="preserve">
<source>Enter your message here</source>
</trans-unit>
</body>
</file>
</xliff>
Copy it to your target language and add the target-language
attribute as well as the needed
<target>…</target>
entries.