Examples
DeepL Custom Target Language
In certain cases, a language code defined in Kirby might not match the language code expected by the translation service.
For example, you may have defined en
as a language code in your Kirby installation, but you want to translate to either British English (en-GB
) or American English (en-US
). DeepL even recommends to specify the target English variant to improve the translation quality:
EN
- English (unspecified variant for backward compatibility; please selectEN-GB
orEN-US
instead)
Use the custom translator function to map language codes on the fly:
use JohannSchopplich\ContentTranslator\DeepL;
return [
'johannschopplich.content-translator' => [
'translateFn' => function (string $text, string $toLanguageCode, string|null $fromLanguageCode = null): string {
// Translate all English content to British English
if ($toLanguageCode === 'en') {
$toLanguageCode = 'en-gb';
}
$deepL = new DeepL();
return $deepL->translate($text, $toLanguageCode, $fromLanguageCode);
}
]
];
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:
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:
label: Translate Files Metadata
type: janitor
command: janitor-translate-files --language de
Then, create the Janitor command in your site/commands
folder:
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 four 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 does not 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:
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:
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:
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
Translate Content of the Whole Website
For large projects, you might want to translate the content of the whole website from the primary language to the secondary languages.
Use the translate-all.php
command to translate the content of the whole website:
use Kirby\CLI\CLI;
use Kirby\Cms\Language;
$defaultAllLanguagesLabel = 'All Languages';
return [
'description' => 'Translates the content of the whole website',
'args' => [],
'command' => static function (CLI $cli) use ($defaultTranslatorOptions, $defaultAllLanguagesLabel): void {
$kirby = $cli->kirby();
$defaultLanguage = $kirby->defaultLanguage()->code();
$nonDefaultLanguages = $kirby->languages()->filter(fn (Language $language) => !$language->isDefault());
$input = $cli->radio(
'Content of which language/languages should be translated?',
[
$defaultAllLanguagesLabel,
...$nonDefaultLanguages->pluck('name')
]
);
$targetLanguage = $input->prompt();
$hasAllLanguagesSelected = $targetLanguage === $defaultAllLanguagesLabel;
$selectedLanguages = $hasAllLanguagesSelected
? $nonDefaultLanguages
: $nonDefaultLanguages->filter(fn (Language $language) => $language->name() === $targetLanguage);
$cli->success('Translating to: ' . implode(', ', $selectedLanguages->pluck('name')));
// Translate all site translations
foreach ($selectedLanguages as $language) {
/** @var \JohannSchopplich\ContentTranslator\Translator */
$translator = $kirby->site()->translator($defaultTranslatorOptions);
$translator->copyContent($language->code(), $defaultLanguage);
$translator->translateContent($language->code(), $language->code(), $defaultLanguage);
$cli->{$hasAllLanguagesSelected ? 'out' : 'success'}('Translated site data to ' . $language->name());
}
if ($hasAllLanguagesSelected) {
$cli->success('Successfully translated all ' . $kirby->site()->title() . ' site data');
}
// Recursively translate all pages
foreach ($kirby->site()->index() as $page) {
/** @var \JohannSchopplich\ContentTranslator\Translator */
$translator = $page->translator($defaultTranslatorOptions);
foreach ($selectedLanguages as $language) {
/** @var \Kirby\Cms\Language $language */
$translator->copyContent($language->code(), $defaultLanguage);
$translator->translateContent($language->code(), $language->code(), $defaultLanguage);
$translator->translateTitle($language->code(), $language->code(), $defaultLanguage);
}
$cli->out('Translated ' . $page->id());
}
$cli->success('Successfully translated all ' . $kirby->site()->title() . ' pages');
}
];
Run the command in your terminal:
# Translate all pages of the selected language/languages to their target language
kirby translate-all