Skip to content

Commit 5577c12

Browse files
committed
Added examples
1 parent 29c94c7 commit 5577c12

File tree

7 files changed

+211
-61
lines changed

7 files changed

+211
-61
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
services:
2+
# default configuration for services in *this* file
3+
_defaults:
4+
autowire: true # Automatically injects dependencies in your services.
5+
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
6+
7+
# makes classes in src/ available to be used as services
8+
# this creates a service per class whose id is the fully-qualified class name
9+
App\:
10+
resource: '../src/'
11+
exclude:
12+
- '../src/DependencyInjection/'
13+
- '../src/Entity/'
14+
- '../src/Kernel.php'
15+
16+
App\AutomatedTranslation\AiClient:
17+
tags:
18+
- ibexa.automated_translation.client
19+
20+
App\AutomatedTranslation\ImageFieldEncoder:
21+
tags:
22+
- ibexa.automated_translation.field_encoder
23+
24+
ibexa_automated_translation:
25+
system:
26+
default:
27+
configurations:
28+
aiclient:
29+
languages:
30+
- 'en_GB'
31+
- 'fr_FR'
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App\AutomatedTranslation;
4+
5+
use Ibexa\AutomatedTranslation\Exception\ClientNotConfiguredException;
6+
use Ibexa\Contracts\AutomatedTranslation\Client\ClientInterface;
7+
use Ibexa\Contracts\ConnectorAi\Action\DataType\Text;
8+
use Ibexa\Contracts\ConnectorAi\Action\RuntimeContext;
9+
use Ibexa\Contracts\ConnectorAi\ActionConfigurationServiceInterface;
10+
use Ibexa\Contracts\ConnectorAi\ActionServiceInterface;
11+
12+
final class AiClient implements ClientInterface
13+
{
14+
/** @var array<string> */
15+
private array $supportedLanguages;
16+
17+
private ActionServiceInterface $actionService;
18+
19+
private ActionConfigurationServiceInterface $actionConfigurationService;
20+
21+
public function __construct(ActionServiceInterface $actionService, ActionConfigurationServiceInterface $actionConfigurationService)
22+
{
23+
$this->actionService = $actionService;
24+
$this->actionConfigurationService = $actionConfigurationService;
25+
}
26+
27+
public function setConfiguration(array $configuration): void
28+
{
29+
if (!array_key_exists('languages', $configuration)) {
30+
throw new ClientNotConfiguredException('List of supported languages is missing in the configuration under the "languages" key');
31+
}
32+
$this->supportedLanguages = $configuration['languages'];
33+
}
34+
35+
public function translate(string $payload, ?string $from, string $to): string
36+
{
37+
$action = new TranslateAction(new Text([$payload]));
38+
$action->setRuntimeContext(
39+
new RuntimeContext(
40+
[
41+
'from' => $from,
42+
'to' => $to,
43+
]
44+
)
45+
);
46+
$actionConfiguration = $this->actionConfigurationService->getActionConfiguration('translate');
47+
$actionResponse = $this->actionService->execute($action, $actionConfiguration)->getOutput();
48+
49+
assert($actionResponse instanceof Text);
50+
51+
return $actionResponse->getText();
52+
}
53+
54+
public function supportsLanguage(string $languageCode): bool
55+
{
56+
return in_array($languageCode, $this->supportedLanguages, true);
57+
}
58+
59+
public function getServiceAlias(): string
60+
{
61+
return 'aiclient';
62+
}
63+
64+
public function getServiceFullName(): string
65+
{
66+
return 'Custom AI Automated Translation';
67+
}
68+
}

code_samples/multisite/automated_translation/src/AutomatedTranslation/CustomClient.php

Lines changed: 0 additions & 42 deletions
This file was deleted.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App\AutomatedTranslation;
4+
5+
use Ibexa\Contracts\AutomatedTranslation\Encoder\Field\FieldEncoderInterface;
6+
use Ibexa\Contracts\Core\Repository\Values\Content\Field;
7+
use Ibexa\Core\FieldType\Image\Value;
8+
9+
final class ImageFieldEncoder implements FieldEncoderInterface
10+
{
11+
public function canEncode(Field $field): bool
12+
{
13+
return $field->fieldTypeIdentifier === 'ezimage';
14+
}
15+
16+
public function canDecode(string $type): bool
17+
{
18+
return $type === 'ezimage';
19+
}
20+
21+
public function encode(Field $field): string
22+
{
23+
/** @var \Ibexa\Core\FieldType\Image\Value $value */
24+
$value = $field->getValue();
25+
26+
return $value->alternativeText ?? '';
27+
}
28+
29+
/**
30+
* @param string $value
31+
* @param \Ibexa\Core\FieldType\Image\Value $previousFieldValue
32+
*/
33+
public function decode(string $value, $previousFieldValue): Value
34+
{
35+
$previousFieldValue->alternativeText = $value;
36+
37+
return $previousFieldValue;
38+
}
39+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App\AutomatedTranslation;
4+
5+
use Ibexa\Contracts\ConnectorAi\Action\TextToText\Action;
6+
7+
final class TranslateAction extends Action
8+
{
9+
public function getActionTypeIdentifier(): string
10+
{
11+
return 'translate';
12+
}
13+
}

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"require-dev": {
1515
"phpstan/phpstan": "^1.10",
1616
"phpstan/phpstan-symfony": "^1.3",
17+
"ibexa/automated-translation": "5.0.x-dev",
1718
"ibexa/doctrine-schema": "5.0.x-dev",
1819
"ibexa/search": "5.0.x-dev",
1920
"ibexa/content-forms": "5.0.x-dev",
@@ -54,7 +55,6 @@
5455
"ibexa/activity-log": "5.0.x-dev",
5556
"ibexa/workflow": "5.0.x-dev",
5657
"ibexa/checkout": "5.0.x-dev",
57-
"ibexa/oauth2-server": "5.0.x-dev",
5858
"ibexa/elasticsearch": "5.0.x-dev",
5959
"ibexa/oauth2-client": "5.0.x-dev",
6060
"ibexa/form-builder": "5.0.x-dev",

docs/multisite/languages/automated_translations.md

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,7 @@ The following field types are supported out of the box:
1717
- [Page](pagefield.md):
1818
- The content of `text` and `richtext` [block attributes](page_block_attributes.md#block-attribute-types)
1919

20-
See [adding a custom field encoder](##add-a-custom-field-encoder) for more information on how to expand this.
21-
22-
!!! note "DeepL limitations"
23-
24-
At this point a list of languages available when using DeepL is limited to English, German, French, Spanish, Italian, Dutch, Polish and Japanese.
20+
See [adding a custom field or block attribute encoder](##add-a-custom-field-encoder) for more information how you can extend this list.
2521

2622
## Configure automated content translation
2723

@@ -36,7 +32,7 @@ composer require ibexa/automated-translation
3632
!!! caution "Modify the default configuration"
3733

3834
Symfony Flex installs and activates the package.
39-
However, you must modify the `config/bundles.php` file to change the bundle loading order so that`IbexaAutomatedTranslationBundle` is before `IbexaAdminUiBundle`:
35+
However, you must modify the `config/bundles.php` file to change the bundle loading order so tha `IbexaAutomatedTranslationBundle` is loaded before `IbexaAdminUiBundle`:
4036

4137
```php
4238
<?php
@@ -72,33 +68,78 @@ The configuration is SiteAccess-aware, therefore, you can configure different en
7268
7369
## Translate content items with CLI
7470
75-
To create a machine translation of a specific content item, run the following command:
71+
To create a machine translation of a specific content item, you can use the `ibexa:automated:translate` command.
72+
73+
The following arguments and options are supported:
7674

77-
```shell
78-
php bin/console ibexa:automated:translate [contentId] [serviceName] --from=eng-GB --to=fre-FR
75+
- `--from` - the source language
76+
- `--to` - the target language
77+
- `contentId` - ID of the content to translate
78+
- `serviceName` - the service to use for translation
79+
80+
For example, to translate the root content item from the English translation into French with the help of Google Translate, run:
81+
82+
``` bash
83+
php bin/console ibexa:automated:translate --from=eng-GB --to=fre-FR 52 google
7984
```
8085

81-
## Add a custom machine translation service
86+
## Extend automated content translations
87+
88+
### Add a custom machine translation service
8289

8390
By default, the automated translation package can connect to Google Translate or DeepL, but you can configure it to use a custom machine translation service.
8491
You would do it, for example, when a new service emerges on the market, or your company requires that a specific service is used.
8592

86-
To add a custom engine to a list of available translation services, do the following:
93+
The following example adds a new translation service.
94+
It uses the [AI actions framework](ai_actions_md) and assumes a custom `TranslateAction` AI Action exists.
95+
To learn how to build custom AI actions see [Extending AI actions](extend_ai_actions.md#custom-action-type-use-case).
8796

8897
1. Create a service that implements the [`\Ibexa\AutomatedTranslation\Client\ClientInterface`](REFERENCE LINK) interface
89-
1. In `services.yaml` file, tag the service as `ibexa.automated_translation.client`
9098

91-
See the example below:
99+
``` php
100+
[[= include_file('code_samples/multisite/automated_translation/src/AutomatedTranslation/AiClient.php') =]]
101+
```
102+
103+
2\. Tag the service as `ibexa.automated_translation.client` in the Symfony container
104+
105+
``` yaml
106+
[[= include_file('code_samples/multisite/automated_translation/config/services.yaml', 15, 18) =]]
107+
```
108+
109+
3\. Specify the configuration under the `ibexa_automated_translation.system.default.configurations` key
110+
111+
``` yaml
112+
[[= include_file('code_samples/multisite/automated_translation/config/services.yaml', 23, 32) =]]
113+
```
114+
115+
### Create custom field or block attribute encoder
92116

93-
<example here>
117+
You can expand the list of supported field types and block attributes for automated translation, adding support for even more use cases than the ones built into [[= product_name =]].
94118

95119
The whole automated translation process consists of 3 phases:
96-
1. Encoding - the raw data stored in the fieldtype is processed so that it can be translated by the automated translation service. Google and Deepl can h
97-
1. Translating - the data is translated using an Automated Translatin client.
98-
1. Decoding - the translated data is decoded back to the original structure so that it can be stored back in [= product_name =]]
99120

100-
## Add a custom field or block encoder
121+
1. **Encoding** - data is extracted from the field types and block attributes and serialized into XML format
122+
1. **Translating** - the serialized XML is sent into specified translation service
123+
1. **Decoding** - the translated response is deserialized into the original data structures for storage in [[= product_name =]]
101124

125+
The following example adds support for automatically translating alternative text in image fields by using the [AI Actions](ai_actions.md).
102126

127+
1. Create a class implementing the [`FieldEncoderInterface`](TODO:Referencelink) and add the required methods:
103128

129+
``` php hl_lines="11-14 16-19 21-27 33-38"
130+
[[= include_file('code_samples/multisite/automated_translation/src/AutomatedTranslation/ImageFieldEncoder.php') =]]
131+
```
132+
In this example, the methods are responsible for:
133+
134+
- `canEncode` - deciding if the field to be encoded is an [Image](imagefield.md) field.
135+
- `canDecode` - deciding if the field to be decoded is an [Image](imagefield.md) field.
136+
- `encode` - extracting the alternative text from the field type.
137+
- `decode` - saving the translated alternative text in the field type's value object.
138+
139+
2\. Register it as a service. If you're not using [Symfony's autoconfiguration]([[= symfony_doc =]]/service_container.html#the-autoconfigure-option), use the `ibexa.automated_translation.field_encoder` service tag.
140+
141+
``` yaml
142+
[[= include_file('code_samples/multisite/automated_translation/config/services.yaml', 19, 22) =]]
143+
```
104144

145+
For custom block attributes the appropriate interface is [`BlockAttributeEncoderInterface`](TODO: Reference link) and the service tag is `ibexa.automated_translation.block_attribute_encoder`.

0 commit comments

Comments
 (0)