Developers Guide¶
Some notes for developers and system integrators. Developers are recommended to read the Terminology guide.
Export process¶
A collection is exported as a ZIP Package containing the source texts in XLIFF format (one XLIFF file for each target language to be translated into). The exported package will be sent to a translator, who will return separate XLIFF files with added target translations, one for each language.
A Package is created from Ibexa through the AdminUI interface at https://admin.example.com/translation/collection
when new translation export job is created by clicking on the Start New Translation Export button.
This job is represented by a message of class Xrow\TranslationBundle\Message\ExportMessage
which is processed by a
handler of class Xrow\TranslationBundle\MessageHandler\ExportMessageHandler
. For more information about the message
bus read the symfony/messenger documentation.
The generated Package can then be downloaded from Ibexa through the AdminUI interface at https://admin.example.com/translation/export
by clicking on the Download button.
Upload process¶
Each translated XLIFF file completed by the Translator must be uploaded into Ibexa.
This is usually done through the AdminUI interface at https://admin.example.com/translation/export
by clicking on
the Upload button.
An upload job is represented by a message of class Xrow\TranslationBundle\Message\UploadMessage
which is processed by a
handler of class Xrow\TranslationBundle\MessageHandler\UploadMessageHandler
.
Import process¶
Once all the translated XLIFF files for a collection have been uploaded (one for each target language), the translations
can be imported into Ibexa through the AdminUI interface at https://admin.example.com/translation/export
by clicking on
the Import button.
An import job is represented by a message of class Xrow\TranslationBundle\Message\ImportMessage
which is processed by a
handler of class Xrow\TranslationBundle\MessageHandler\ImportMessageHandler
.
This processes the XLIFF of each target language, and creates new translated versions of Ibexa content from the supplied translations.
When using the Import button, RabbitMQ is leveraged to process the job, see method startImportAction
in
CollectionImportController.
The process is asynchronous and relies on the ImportMessageHandler
updating the Status of the collection.
Configuration¶
Define source translation languages¶
By default, all system languages will be regarded as valid sources for translation.
If you want to restrict the list of source languages, optionally configure it in config/packages/xrow_translation.yaml
:
xrow_translation:
source_languages:
- eng-GB
- ger-DE
This will restrict the allowed source languages for translation to (British) English and German. Any language codes that are not system languages will be ignored.
Define languages for automatic queuing¶
To restrict which language versions of contents are automatically added to the translation queue, configure it in config/packages/xrow_translation.yaml
:
xrow_translation:
recent_items:
allowed_languages:
- ger-DE
- eng-GB
In the above example, only content versions in British English and German will be automatically added to the translation queue after publishing.
Define sub-trees for automatic queuing¶
To restrict by sub-tree whether a content can be automatically added to the translation queue, configure it in config/packages/xrow_translation.yaml
:
xrow_translation:
recent_items:
allowed_content_trees:
- 12345
- 678
In the above example, content in the 2 sub-trees below (and including) locations 12345 and 678 may be automatically added to the translation queue after publishing, depending on any language restrictions (if configured by allowed_languages
).
Contents in other sub-trees will not be added to the translation queue automatically.
Enable export of empty fields¶
By default, empty fields are not exported in XLIFF because they cannot be translated. But if needed by the Translator, export of empty
field values can be enabled in the bundle configuration in config/packages/xrow_translation.yaml
:
xrow_translation:
xliff:
keep_empty: true
Define empty placeholder text¶
If needed by the Translator, empty placeholder text as described in the User Guide can be configured in config/packages/xrow_translation.yaml
:
xrow_translation:
xliff:
empty_placeholder: '**do_not_translate**'
Note that when an empty_placeholder
value is defined, keep_empty
is assumed to be true if it is not configured explicitly.
Define translation provider¶
The Translation Manager supports different translation providers.
Note that only one translation provider can be enabled at a time.
By default the manual translation provider is enabled, where a human user manually downloads untranslated Packages, and uploads translated XLIFF files.
Two automatic translation providers are also supported and can be configured in config/packages/xrow_translation.yaml
.
Demo translation provider¶
This is an internal translation provider for demo and testing purposes. It automatically generates 'fake' translated text for each content in a collection.
xrow_translation:
xliff:
provider: demo
Google translation provider¶
This translation provider leverages the ibexa/automated-translation package to connect to the Google Translation API. You will need an API key.
xrow_translation:
xliff:
provider: google
ibexa_automated_translation:
system:
default:
configurations:
google:
apiKey: 'my-secret-api-key'
Using an automatic translation provider¶
When an automatic translation provider is enabled, the Translation Export page renders a Translate button for each collection. This allows the user to start an asynchronous translation process by sending the collection to a third-party provider via an API. When the required translations for a collection have all been received from the third party system, the Translation Export page renders an Import button to allow the user to start importing the translated contents.
Supported XLIFF modules¶
XLIFF 2.1 can be extended by modules, declared as namespaces in the top-level <xliff>
element.
Currently the following modules are supported out-of-the-box by the translation bundle:
urn:oasis:names:tc:xliff:fs:2.0
urn:oasis:names:tc:xliff:sizerestriction:2.0
See Size and Length Restriction Module.
urn:oasis:names:tc:xliff:xrow:2.0
Entities¶
Allowed Translation¶
It is a PHP class Xrow\TranslationBundle\Entity\AllowTranslation which will hold the details of content while making any changes in edit content page. When content is published it will send it to Queued Items section according to settings selected for that content.
Queued Items¶
Queued Items lists out all the contents which are ready to be translated using collection export. Properties are defined in the PHP class Xrow\TranslationBundle\Entity\RecentItem.
Collection¶
A collection is a set of content versions created within Ibexa DXP that should be translated into one or more languages. Properties are defined in the PHP class Xrow\TranslationBundle\Entity\Collection.
This entity stores all the required information in JSON format using serialize()
in the data field as below.
- collection (array of content IDs with selected setting to include children or exclude self node)
- list (Array having location ID and version of contents which are going to be exported)
- target (Target language selected during collection export)
- source (Source language selected during collection export)
- Job Name (Name given during collection export)
Collection Items¶
Collection Items are contents added by user to include in collection export. Properties are defined in the PHP class Xrow\TranslationBundle\Entity\CollectionItem.
ErrorLog¶
Errors that occur during the processes of collection export and import are inserted in the PHP class Xrow\TranslationBundle\Entity\ErrorLog.
ImportFile¶
PHP class Xrow\TranslationBundle\Entity\ImportFile stores the information about uploaded XLIFF file for every collection import.
Custom translation providers¶
As well as the two supported automatic translation providers, as long as a third-party translation provider has an API, it should be possible to extend the Translation Manager to support it.
Any custom translation provider must implement the methods defined by TranslationProviderInterface
:
namespace App;
use Xrow\TranslationBundle\API\TranslationProviderInterface;
use Xrow\TranslationBundle\Entity\Collection;
class MyTranslationProvider implements TranslationProviderInterface
{
public function __construct(...)
{
// Initialize whatever dependencies your provider needs.
}
public static function getIdentifier(): string
{
return 'my_translation_provider';
}
public function getFullName(): string
{
return 'My Translation Provider';
}
public function getType(): string
{
return self::TYPE_API;
}
public function getStatus(Collection $collection, string $language): int
{
// Currently this method is unused by the Translation Manager but must be provided.
return 0;
}
public function send(Collection $collection, string $language): void
{
// Connect to the third party API and send the relevant collection data to it (typically XLIFF), plus any supported metadata.
// If this method fails, the Translation Manager will not retry it, so handle any communication errors in your own code.
}
public function get(Collection $collection, string $language): void
{
// Connect to the third party API and fetch relevant data (typically XLIFF) from it for the specified collection and target language.
// It is up to the get() method to store the received data by dispatching an UploadMessage so that it can later be imported.
// If relevant data is not (yet) available, throw 'TranslationNotProvidedException'. The Translation Manager will try again later.
// If this method fails, the Translation Manager will not retry, so handle any communication errors in your own code.
//
// Currently only XLIFF 2 can be imported. Override Xrow\TranslationBundle\Service\Management and
// Xrow\TranslationBundle\Model\Collection if you want to use a data structure other than XLIFF 2.
}
Enable your translation provider in config/packages/xrow_translation.yaml
:
xrow_translation:
xliff:
# Use the identifier defined by your getIdentifier() method
provider: my_translation_provider
Hints for developers¶
Using RabbitMQ¶
Currently there is no option to disable use of RabbitMQ, it must be installed.
Messages are consumed asynchronously, so the calling controller and the message handlers should handle collection statuses properly, to make sure that:
- jobs are not run more than once
- job completion is detected correctly
- errors are handled correctly