IBX-10684: Document translation management - #3249
Conversation
Co-Authored-By: dabrt <dabrt@users.noreply.github.com> Co-Authored-By: Marek Nocoń <mnocon@users.noreply.github.com>
code_samples/ change report
|
|
|
||
| | Event | Dispatched by | Dispatched when | Properties | | ||
| |---|---|---|----| | ||
| | [`BeforeTranslateEvent`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-TranslationsManagement-AutoTranslate-Event-BeforeTranslateEvent.html) | `TranslationService` | Before a translation request is sent to the provider | `TranslationProviderInterface $provider`</br>`string $text`</br>`string $sourceLanguage`</br>`string $targetLanguage` | |
There was a problem hiding this comment.
| | [`BeforeTranslateEvent`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-TranslationsManagement-AutoTranslate-Event-BeforeTranslateEvent.html) | `TranslationService` | Before a translation request is sent to the provider | `TranslationProviderInterface $provider`</br>`string $text`</br>`string $sourceLanguage`</br>`string $targetLanguage` | | |
| | [`BeforeTranslateEvent`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-TranslationsManagement-AutoTranslate-Event-BeforeTranslateEvent.html) | `EventDispatchingProviderTranslator` | Before a translation request is sent to the provider | `TranslationProviderInterface $provider`</br>`string $text`</br>`string $sourceLanguage`</br>`string $targetLanguage` | |
| - Draft conflict warning | ||
|
|
||
| When an user opens the translation modal and selects a target language which already has a draft translation, a warning appears in the modal. | ||
| The warning is shown or hidden dynamically by `side-by-side-translation-modal-warning.js` when the user changes the target language selection. |
There was a problem hiding this comment.
| The warning is shown or hidden dynamically by `side-by-side-translation-modal-warning.js` when the user changes the target language selection. | |
| The warning is shown or hidden dynamically by `add.translation.modal.warning.js` when the user changes the target language selection. |
| tags: | ||
| - name: 'ibexa.translations_management.auto_translate.provider' | ||
| identifier: 'my_custom_provider' | ||
| validation_profile: 'ai_generic' |
There was a problem hiding this comment.
Validation profile should be based on registered Validators and their profile identifier.
| validation_profile: 'ai_generic' | |
| validation_profile: 'my_custom_profile' |
| ## Manage language pairs programmatically | ||
|
|
||
| To manage language pairs programmatically, create a service class and inject `LanguagePairServiceInterface` into its constructor. | ||
| Symfony autowires it automatically so no manual service configuration is needed. | ||
|
|
||
| ``` php hl_lines="2" | ||
| [[= include_code('code_samples/translations_management/src/TranslationsManagement/TranslationPairManager.php', 14, 35) =]] | ||
| ``` | ||
|
|
||
| The service exposes the following methods: | ||
|
|
||
| | Method | Description | | ||
| |---|---| | ||
| | `createLanguagePair()` | Create a new language pair. Pass `true` as the fourth argument to overwrite an existing pair with the same source and target. | | ||
| | `updateLanguagePair()` | Update an existing language pair by ID. | | ||
| | `syncLanguagePairsForSourceAndProvider()` | Synchronize all target languages for a given source language and provider. | | ||
| | `loadLanguagePairs()` | Load all configured language pairs. | | ||
| | `deleteLanguagePairById()` | Delete a language pair by ID. | | ||
| | `deleteLanguagePairsForProvider()` | Delete all language pairs associated with a given provider. | | ||
|
|
There was a problem hiding this comment.
IMO, this should be dropped because LanguagePairServiceInterface is not a contract and should not be exposed as example to manage Language Pairs outside of the translations management bundle.
|
|
||
| When an editor clicks the **Copy all from source** action, all translatable field values are copied from the source to target column. | ||
| It's a single server-side operation handled by `SideBySideFieldCopyService::copyAllFields()` after which the view is reloaded. | ||
|
|
There was a problem hiding this comment.
We should consider to add new section: Review of automatic translations or something similar.
When a draft is created with automatic translation, it's marked for review; editors accept or reject the result. - This could point to example from user documentation with snack back contains actions.
|
|
||
| The [side-by-side translation view]([[= user_doc =]]/content_management/translate_content/#side-by-side-translation-view) is a two-column content editing interface where the source column is read-only and the target column is an editable form. | ||
|
|
||
| Content types that contain the `ibexa_landing_page` or `ibexa_form` fields are not supported, and editors can open them in the standard single-language editor only. |
There was a problem hiding this comment.
Maybe we should to clarify that excluding a content type from the side-by-side view does not make it untranslatable. Landing Page and other excluded content types can still be auto-translated through the standard translation flow and the CLI command - only the side-by-side editing interface is unavailable for them.
|
|
||
| To exclude additional content types, for example, content types whose fields render incorrectly in the side-by-side layout, implement [`SideBySideExclusionRuleInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-TranslationsManagement-SideBySide-Service-SideBySideExclusionRuleInterface.html). | ||
| The `isExcluded()` method receives a [`ContentInfo`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Core-Repository-Values-Content-ContentInfo.html) object and returns `true` if the content item should be excluded. | ||
| Classes that implement this interface are automatically tagged with `autoconfigure`: |
There was a problem hiding this comment.
| Classes that implement this interface are automatically tagged with `autoconfigure`: | |
| Register the rule with the `ibexa.translations_management.side_by_side.exclusion_rule` tag. This interface is not registered for Symfony autoconfiguration, so the tag is required. |
| [[= include_code('code_samples/translations_management/src/TranslationsManagement/MyCustomExclusionRule.php') =]] | ||
| ``` | ||
|
|
||
| If `autoconfigure` is not available, register the tag explicitly: |
There was a problem hiding this comment.
| If `autoconfigure` is not available, register the tag explicitly: |
| `ContentProxyTranslateEvent` is marked `@internal` in `ibexa/admin-ui`. | ||
| While it functions as an extension point in practice, its name and signature may change. | ||
| It may even be removed entirely without a deprecation notice. | ||
|
|
There was a problem hiding this comment.
We could consider to be more precise here and clarify that when the package's Subscriber fails to create the auto-translated draft in this flow (for example, the provider is unreachable), it catches the error, shows an error notification, and redirects to the content view. It does not surface a full error page.
| In all cases, you follow the same pattern: implement an interface or extend a base class, then register the service with a service tag. | ||
| The package discovers and registers tagged services automatically. | ||
|
|
||
| ## Add custom translation provider |
There was a problem hiding this comment.
We should distinguish regular translation provider from Ai translation provider. There are two different interfaces which allows to determine which provider will be added:
- TranslationProviderInterface
- AiTranslationProviderInterface
Document translation management
Checklist