tobento / app-machine-translator
Machine translation integration with optional UI support for applications.
Package info
github.com/tobento-ch/app-machine-translator
pkg:composer/tobento/app-machine-translator
Requires
- php: >=8.4
- tobento/app: ^2.0
- tobento/app-http: ^2.0
- tobento/app-language: ^2.0
- tobento/app-logging: ^2.0
- tobento/app-migration: ^2.0
- tobento/app-queue: ^2.0
- tobento/app-translation: ^2.0
- tobento/app-user: ^2.0
- tobento/js-notifier: ^1.0
- tobento/service-machine-translator: ^2.0
- tobento/service-tag: ^2.0
Requires (Dev)
- phpunit/phpunit: ^12.3
- tobento/app-event: ^2.0
- tobento/app-testing: ^2.0
- tobento/app-view: ^2.0
- vimeo/psalm: ^6.13
Suggests
- tobento/app-view: May be used for the JavaScript Translator UI.
README
Application-level integration for machine translation, built on top of the Machine Translator Service.
Table of Contents
Getting Started
Add the latest version of the app machine-translator project running this command.
composer require tobento/app-machine-translator
Requirements
- PHP 8.4 or greater
Documentation
App
Check out the App Skeleton if you are using the skeleton.
You may also check out the App to learn more about the app in general.
Machine Translator Boot
The MachineTranslator boot integrates the Tobento Machine Translator Service into your application.
It provides:
- loading of the
machine-translator.phpconfiguration - binding of all service-machine-translator interfaces
- installing the machine-translator migration
- registering configured translation features
- setting up lazy machine translators and the default translator
use Tobento\App\AppFactory; use Tobento\Service\MachineTranslator\MachineTranslatorInterface; use Tobento\Service\MachineTranslator\MachineTranslatorsInterface; // Create the app $app = new AppFactory()->createApp(); // Add directories: $app->dirs() ->dir(realpath(__DIR__.'/../'), 'root') ->dir(realpath(__DIR__.'/../app/'), 'app') ->dir($app->dir('app').'config', 'config', group: 'config') ->dir($app->dir('root').'public', 'public') ->dir($app->dir('root').'vendor', 'vendor'); // Booting: $app->boot(\Tobento\App\MachineTranslator\Boot\MachineTranslator::class); $app->booting(); // Implemented interfaces $machineTranslator = $app->get(MachineTranslatorInterface::class); $machineTranslators = $app->get(MachineTranslatorsInterface::class); // Run the app $app->run();
Machine Translator Config
The configuration for the machine translator is located in the app/config/machine-translator.php file at the default App Skeleton config location.
Here you can define the Machine Translators available to your application, as well as enable optional Translation Features.
Basic Usage
If you're new to working with machine translators in Tobento, start with the
Basic Usage section of the Machine Translator Service.
It explains how to create and use translators, how translation results are structured, and provides the foundation for how App-Machine-Translator builds on top of the underlying service.
Features
Translate Feature
The Translate feature provides an HTTP endpoint for performing machine translations directly from your application.
It is designed for any workflow that requires on-demand machine translation through a simple HTTP API, such as backend services, admin tools, automation scripts, or JavaScript integrations.
This feature offers:
- a POST
/machine-translateendpoint (optionally localized per locale) - support for translating one or many texts in a single request
- automatic validation of input fields
- automatic selection of the default translator if none is specified
- ACL-protected access (
machine-translatepermission) - structured JSON responses for both success and error cases
- logging of translation failures via the
LoggerTrait - optional route localization using the
RouteLocalizerInterface
The feature installs an extended migration to support translation logging and tracking.
Config
Enable the feature in your machine-translator.php config:
'features' => [ new \Tobento\App\MachineTranslator\Feature\Translate( withAcl: false, // WARNING: Disables permission checks. Only use in development. localizeRoute: true, // Localize the route per locale ), ],
Warning
Security Warning:
Disabling ACL (withAcl: false) removes all permission checks for the translation endpoint.
This should only be used during development or in trusted internal environments.
ACL Permissions
This feature defines the following ACL permission:
machine-translate- User can perform machine translations.
If you are using the App Backend, you can assign these permissions to roles or users in the backend interface.
Request Format
You may send either:
- a single text:
text: string
or
- multiple texts:
texts: array<string>
Additional fields:
locale- the target locale (required)translator- the translator name (optional; defaults to the first configured translator)
Example Request (single)
POST /machine-translate { "text": "Hello world", "locale": "de" }
Example Success Response
{
"translated": "Hallo Welt",
"locale": "de",
"text": "Hello world"
}
Example Request (many)
POST /machine-translate { "texts": { "title": "Hello", "body": "How are you?" }, "locale": "fr" }
Example Success Response
{
"translated": {
"title": "Bonjour",
"body": "Comment allez-vous?"
},
"locale": "fr",
"texts": {
"title": "Hello",
"body": "How are you?"
}
}
For programmatic usage from JavaScript (e.g., admin tools, automation, UI helpers), see the JavaScript Translator.
Logging
The App Logging Boot is enabled by default, so no additional setup is required to log machine translation activity.
In the app/config/logging.php file you may define the logger to be used, otherwise the default logger will be used:
'aliases' => [ // Log translation failures using the "daily" logger: \Tobento\App\MachineTranslator\Feature\Translate::class => 'daily', // Or disable logging entirely: \Tobento\App\MachineTranslator\Feature\Translate::class => 'null', ],
JavaScript Translator
The JavaScript Translator provides a lightweight client for performing machine translations from JavaScript.
It is intended for use in admin interfaces, tooling, automation, or any environment where translations need to be requested from the browser or another JS runtime.
This module communicates with the Translate Feature endpoint and offers a simple API for translating one or many texts.
Example
The following example demonstrates how to use the JavaScript Translator together with App View.
Make sure App View is installed and its boot is enabled before using this example.
$app->boot(\Tobento\App\View\Boot\View::class); $app->boot(\Tobento\App\View\Boot\Form::class);
This setup allows you to attach translation behavior to any element using data-machine-translator attributes.
When clicked, the element triggers a request to the Translate Feature endpoint and writes the translated text into the target field.
Example View
<?php use Tobento\Service\Tag\Attributes; $mta = new Attributes([ 'class' => 'button', 'data-machine-translator' => [ // The translation endpoint (Translate Feature route): 'url' => (string)$view->routeUrl('machine-translate'), // Use the first matching field inside the nearest [data-field] container: 'from_first' => '[data-field]', // Explicit source field(s) (optional): //'from' => 'text.en', // or 'text[en]' - same result //'from' => ['text.en', 'text.fr'], // Override target locale (optional): //'locale' => 'de', // otherwise inferred from last segment of "to" // Target field is set individually on each button below: //'to' => 'text.de', // Optional messages: 'empty_message' => 'No text found to translate from.', 'target_not_empty_message' => 'Target already contains text.', ], ]); $form = $view->form(); ?> <!DOCTYPE html> <html lang="<?= $view->esc($view->get('htmlLang', 'en')) ?>"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Demo View</title> <?= $view->render('inc/head') ?> <?= $view->assets()->render() ?> <?php //$view->asset('css/basis.css'); // added in 'inc/head' //$view->asset('css/app.css'); // added in 'inc/head' $view->asset('assets/machine-translator/translator.js')->attr('type', 'module'); $view->asset('assets/js-notifier/notifier.css'); ?> </head> <body<?= $view->tagAttributes('body')->add('class', 'page')->render() ?>> <?= $view->render('inc/header') ?> <?= $view->render('inc/nav') ?> <main class="page-main"> <?= $view->render('inc.breadcrumb') ?> <?= $view->render('inc.messages') ?> <h1 class="text-xl">Demo View</h1> <?php $form = $view->form(); ?> <?= $form->form() ?> <div class="field" data-field="text"> <span<?= $mta->add('data-machine-translator', ['to' => 'text.de']) ?>>Translate</span> <?= $form->input( type: 'text', name: 'text.de', ) ?> <span<?= $mta->add('data-machine-translator', ['to' => 'text.fr']) ?>>Translate</span> <?= $form->input( type: 'text', name: 'text.fr', ) ?> <span<?= $mta->add('data-machine-translator', ['to' => 'text.en']) ?>>Translate</span> <?= $form->input( type: 'text', name: 'text.en', ) ?> </div> <?= $form->button('Submit') ?> <?= $form->close() ?> </main> <?= $view->render('inc/footer') ?> </body> </html>
How It Works
The JavaScript Translator activates on any element containing a data-machine-translator attribute.
When the element is clicked, the following steps occur:
-
Resolve the source text
The translator determines which field(s) to read from using:from(explicit source fields), orfrom_first(fallback selector inside the nearest[data-field]container)
-
Determine the target field
Thetoattribute specifies where the translated text should be written.
If nolocaleis provided, the locale is inferred from the last segment of the target name
(e.g.,text.detode). -
Send a request to the Translate Feature endpoint
A POST request is sent to the configuredurl(usually the/machine-translateroute). -
Write the translated text into the target field
The response from the server is inserted into the field defined byto. -
Display user feedback via js-notifier
The translator uses js-notifier to show:- success messages
- validation warnings (e.g., empty source field)
- server errors (e.g., translation failed)
This provides a smooth, interactive translation workflow without requiring custom JavaScript.
Integration with App CRUD
If you are using App CRUD, the JavaScript Translator is integrated automatically.
Translation buttons and field behaviors are added to CRUD forms without requiring any manual setup.
This means CRUD views can offer machine translation out of the box, using the same data-machine-translator attributes shown in the example above.
For more details on how translatable fields work in CRUD, see the Translatable Field documentation.
Learn More
Events For Translators
The Machine Translator Boot adapts each created translator to dispatch the events defined by the Event Machine Translator Adapter.
To enable event dispatching, install
App Event and boot it:
$app->boot(\Tobento\App\Event\Boot\Event::class);
Once booted, the translator will trigger the events described in the Machine Translator Adapter Events.
For listening to events, see the Add Listeners section.