tobento/app-machine-translator

Machine translation integration with optional UI support for applications.

Maintainers

Package info

github.com/tobento-ch/app-machine-translator

Homepage

pkg:composer/tobento/app-machine-translator

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

2.0 2026-04-01 13:44 UTC

This package is auto-updated.

Last update: 2026-04-01 13:45:30 UTC


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.php configuration
  • 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-translate endpoint (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-translate permission)
  • 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:

  1. Resolve the source text
    The translator determines which field(s) to read from using:

    • from (explicit source fields), or
    • from_first (fallback selector inside the nearest [data-field] container)
  2. Determine the target field
    The to attribute specifies where the translated text should be written.
    If no locale is provided, the locale is inferred from the last segment of the target name
    (e.g., text.de to de).

  3. Send a request to the Translate Feature endpoint
    A POST request is sent to the configured url (usually the /machine-translate route).

  4. Write the translated text into the target field
    The response from the server is inserted into the field defined by to.

  5. 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.

Credits