Single Page

Copy and translate a single page’s content to any target language from the command line, without opening the Panel.

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.

Prerequisites

Install the Kirby CLI and create a site/commands folder if it does not exist yet.

Command

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();
        $titles = array_map('strval', $siteChildren->pluck('title'));
        $input = $cli->radio(
            'Which page should be translated?',
            $titles
        );
        $response = $input->prompt();
        $cli->success('Selected page: ' . $response);

        $page = $siteChildren->findBy('title', $response);
        if ($page === null) {
            $cli->error('Page "' . $response . '" not found.');
            return;
        }

        $translator = $page->translator();
        $translator->copyContent($targetLanguage, $defaultLanguage);
        $translator->translateContent($targetLanguage, $targetLanguage, $defaultLanguage);
        $translator->translateTitle($targetLanguage, $targetLanguage, $defaultLanguage);
        // $translator->translateSlug($targetLanguage, $targetLanguage, $defaultLanguage);

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

Usage

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

Translate With AI for One Run

The fourth argument of translateContent() overrides the configured strategy for one call. Pass a CopilotAIStrategy to translate the page through Kirby Copilot even when DeepL is the global default. Import the class at the top of the command file, then hand it to the call:

use JohannSchopplich\ContentTranslator\Translation\Strategies\CopilotAIStrategy;

$translator->translateContent($targetLanguage, $targetLanguage, $defaultLanguage, new CopilotAIStrategy());

translateTitle() and translateSlug() take no strategy argument, so the title still goes through the strategy set by the strategy option.

Pass a custom prompt to the strategy constructor for domain-specific runs:

$translator->translateContent($targetLanguage, $targetLanguage, $defaultLanguage, new CopilotAIStrategy(
    systemPrompt: 'You are a medical translator. Preserve clinical terminology.',
));
See CopilotAIStrategy for its constructor and how it batches.