Content Translator

PHP API

Get to know the available methods and global functions to copy and translate your content.

Giving editors the power to copy and translate content is a great. But for certain use cases, you might want to automate this process. This is where the PHP API comes into play. The plugin provides a set of methods and global functions to copy and translate content programmatically.

For example, you can write a CLI command to translate all pages for a new language that was just added to your project:

Global Functions

Kirby Content Translator provides two global functions to simplify the usage of the PHP API. Call them from anywhere in your project.

translator()

The translator() function creates a new instance of the Translator class. It accepts a Kirby Site, Page, or File model as the first argument and an optional array of options as the second argument.

$page = page('example');
$translator = translator($page);

Type Definitions

function translator(Site|Page|File $model, array $options = []): \JohannSchopplich\ContentTranslator\Translator

translate()

The translate() function translates a given text from a source language to a target language. It accepts the text to translate as the first argument, the target language as the second argument, and the source language as the third argument. The source language is optional.

echo translate('Hello', 'de');

Passing the source language as the third argument can improve the translation quality, since DeepL does not always detect the source language correctly (especially for short texts). If you know the source language, you can provide it to get better results:

echo translate('Hello', 'de', 'en');
Be aware that translations are not cached. If you need to translate the same text multiple times, it is recommended to cache the results.

Type Definitions

function translate(string $text, string $targetLanguage, string|null $sourceLanguage = null): string

Site, Page and File Methods

You can initialize a new Translator instance directly on a Site, Page, or File model, instead of using the global translator() function:

$site = site();
$translator = $site->translator();

$page = page('example');
$translator = $page->translator();

Translator Class Methods

The JohannSchopplich\ContentTranslator\Translator class provides a set of methods to copy and translate content programmatically. It is initialized when using the global translator() function or the translator() method on a Site, Page, or File model.

copyContent

The copyContent() method copies the content of the source language to the content of the target language. This will overwrite the content of the target language. It accepts the target language and the source language as the first and second arguments.

$page = page('example');
$translator = $page->translator();
// Copy the default language (English) content to the secondary language (German)
$translator->copyContent('de', 'en');

Type Definitions

public function copyContent(string $toLanguageCode, string $fromLanguageCode): void

translateContent

The translateContent() method translates the content from the source language to the target language. It accepts the content language, the target language, and the source language as the first, second, and third arguments. Note that the source language is optional.

Say you have already copied the content from the default language to a secondary language and now want to translate the content of the secondary language, which is still just a copy of the default language:

$page = page('example');
$translator = translator($page);
// Or use the translator method on the page model
$translator = $page->translator();

// Copy the default language (English) content to the secondary language (German)
$translator->copyContent('de', 'en');

// Translate the copied content to German, because the content is still in English
$translator->translateContent(
    // This is the language of the content that should be translated
    'de',
    // This is the target language
    'de'
);

Type Definitions

public function translateContent(string $contentLanguageCode, string $toLanguageCode, string|null $fromLanguageCode = null): void

translateTitle

The translateTitle() method translates the title of a page. It accepts the content language, the target language, and the source language as the first, second, and third arguments. Note that the source language is optional.

$page = page('example');
$translator = $page->translator();
// Translate the title of the German content to English
$translator->translateTitle('de', 'en');

Type Definitions

public function translateTitle(string $contentLanguageCode, string $toLanguageCode, string|null $fromLanguageCode = null): void

model

When making changes to a model's content, Kirby will return a clone of the model. That's why you need to reassign the model to the variable you are using if you want to access the updated (translated) content.

To get the updated model, you can use the model() method:

$page = page('example');
$translator = $page->translator();

// Translate the content
$translator->translateContent('de', 'de');

// Now, the `$page` model still contains the untranslated content…
echo $page->content()->get('text'); // Outputs the untranslated text

// Reassign the model to get the updated content
$page = $translator->model();

// Now, the `$page` model contains the translated content
echo $page->content()->get('text'); // Outputs the translated text

Type Definitions

public function model(): Site|Page|File

Configuration

You can configure the PHP API similarly to the Panel Configuration. In fact, the following configuration options are available and behave the same way as in the Panel:

  • fieldTypes
  • includeFields
  • excludeFields

To pass the configuration to the Translator class, you can use the second argument of the translator() function or the translator() method on a Site, Page, or File model:

$translator = translator(page('example'), [
    'fieldTypes' => ['text', 'textarea'],
    'excludeFields' => ['company']
]);

$site = site();
$translator = $site->translator([
    'fieldTypes' => ['text', 'textarea'],
    'excludeFields' => ['company']
]);

$page = page('example');
$translator = $page->translator([
    'fieldTypes' => ['text', 'textarea'],
    'excludeFields' => ['company']
]);

Examples

Janitor Panel Button

While you can run Kirby commands from the CLI, you can also create a custom Kirby Janitor command to translate content and run it from the Panel. Below is an example of a Janitor command that translates the metadata of all files of a specific page to German:

Kirby Tools section preview

First, create a field in your blueprint that triggers the Janitor command. Make sure to replace de with the target language you want to translate the files metadata to:

fields/janitor-translate-files.yml
label: Translate Files Metadata
type: janitor
command: janitor-translate-files --language de

Then, create the Janitor command in your site/commands folder:

site/commands/janitor-translate-files.php
use Bnomei\Janitor;
use Kirby\CLI\CLI;

return [
    'description' => 'Translates all files metadata of a specific page.',
    'args' => [
        'language' => [
            'longPrefix' => 'language',
            'description' => 'The target language to translate the content to.',
            'required' => true
        ]
    ] + Janitor::ARGS,
    'command' => static function (CLI $cli): void {
        $kirby = $cli->kirby();
        $defaultLanguage = $kirby->defaultLanguage()->code();
        $targetLanguage = $cli->arg('language');
        $page = $kirby->page($cli->arg('page'));

        foreach ($page->files() as $file) {
            $translator = $file->translator();
            $translator->copyContent($targetLanguage, $defaultLanguage);
            $translator->translateContent($targetLanguage, $targetLanguage, $defaultLanguage);
        }

        Janitor::singleton()->data($cli->arg('command'), [
            'status' => 200,
            'message' => 'Files translated successfully!'
        ]);
    }
];

CLI Commands

You can leverage the Kirby CLI to automate the translation process. Below are two examples of CLI commands that you can use to translate content.

For these examples to work, install the Kirby CLI and create a new site/commands folder if it doesn't exist yet.

Translate Content of a Page

The most common use case is to copy the content from the default language to a secondary language and then translate the duplicated content to the target language. You can create a CLI command to automate this process:

site/commands/translate-page.php
use Kirby\CLI\CLI;

return [
    'description' => 'Translates the content of a specific page.',
    'args' => [
        'language' => [
            'description' => 'The target language to translate the content to.',
            'defaultValue' => 'de'
        ]
    ],
    'command' => static function (CLI $cli): void {
        $kirby = $cli->kirby();
        $defaultLanguage = $kirby->defaultLanguage()->code();
        $targetLanguage = $cli->arg('language');

        $siteChildren = $kirby->site()->children();
        $input = $cli->radio(
            'Which page should be translated?',
            $siteChildren->pluck('title')
        );
        $response = $input->prompt();
        $cli->success('Selected page: ' . $response);

        $page = $siteChildren->findBy('title', $response);
        $translator = $page->translator();
        $translator->copyContent($targetLanguage, $defaultLanguage);
        $translator->translateContent($targetLanguage, $targetLanguage, $defaultLanguage);

        $cli->success('Successfully translated ' . $page->id());
    }
];

Run the command in your terminal:

# Translate the content of a specific page to German
kirby translate-page de

Translate All Children of a Page

By leveraging the prompts, you can create a CLI command to translate all children of a specific page to a target language:

site/commands/translate-children.php
use Kirby\CLI\CLI;

return [
    'description' => 'Translates the content of all children of a specific page.',
    'args' => [
        'language' => [
            'description' => 'The target language to translate the content to.',
            'defaultValue' => 'de'
        ]
    ],
    'command' => static function (CLI $cli): void {
        $kirby = $cli->kirby();
        $defaultLanguage = $kirby->defaultLanguage()->code();
        $targetLanguage = $cli->arg('language');

        $siteChildren = $kirby->site()->children();
        $input = $cli->radio(
            'Which page\'s children should be translated?',
            $siteChildren->pluck('title')
        );
        $response = $input->prompt();
        $cli->success('Selected parent page: ' . $response);

        $page = $siteChildren->findBy('title', $response);

        foreach ($page->children()->listed() as $child) {
            $translator = $child->translator();
            $translator->copyContent($targetLanguage, $defaultLanguage);
            $translator->translateContent($targetLanguage, $targetLanguage, $defaultLanguage);
            $cli->out('Translated ' . $child->id());
        }

        $cli->success('Successfully translated all ' . $page->id() . ' children');
    }
];

Run the command in your terminal:

# Translate all children of a selected page to German
kirby translate-children de

Translate Files Metadata of a Page

Most of the time, you will want to translate the content of a page. But sometimes, you might want to translate the metadata of files (like the title or description) of a page. Use the translate-files.php command to translate the files metadata of all children of a specific page:

site/commands/translate-files.php
use Kirby\CLI\CLI;

return [
    'description' => 'Translates the files metadata of listed children pages.',
    'args' => [
        'language' => [
            'description' => 'The target language to translate the content to.',
            'defaultValue' => 'de'
        ]
    ],
    'command' => static function (CLI $cli): void {
        $kirby = $cli->kirby();
        $defaultLanguage = $kirby->defaultLanguage()->code();
        $targetLanguage = $cli->arg('language');

        $siteChildren = $kirby->site()->children();
        $input = $cli->radio(
            'Which page\'s files metadata should be translated?',
            $siteChildren->pluck('title')
        );
        $response = $input->prompt();
        $cli->success('Selected parent page: ' . $response);

        $page = $siteChildren->findBy('title', $response);

        foreach ($page->children()->listed() as $child) {
            foreach ($child->files() as $file) {
                $translator = $file->translator();
                $translator->copyContent($targetLanguage, $defaultLanguage);
                $translator->translateContent($targetLanguage, $targetLanguage, $defaultLanguage);
                $cli->out('Translated ' . $file->id() . ' metadata');
            }
        }

        $cli->success('Successfully translated all ' . $page->id() . ' files');
    }
];

Run the command in your terminal:

# Translate all children of a selected page to German
kirby translate-files de