Create custom Symfony translation extractor

Licensed under Creative Commons.

This post is also available on my blog.

Overview

The Symfony translation component allows you to extract translations from your PHP codebase & Twig templates into the translation file format of your liking, for example .po files.

The documentation describes it like this:

The most time-consuming tasks when translating an application is to extract all the template contents to be translated and to keep all the translation files in sync. Symfony includes a command called translation:update that helps you with these tasks.

But what if not all my translations are hardcoded in code or templates, and some - or all - are dynamic? For example loaded from an external data source, like a REST API.

Create translation extractor

You can add your own translation extractor. Which will be run when executing the Symfony consoles’ translation:update command. In addition to the extractors that are already included.

Create a class that implements the ExtractorInterface:

<?php

declare(strict_types=1);

namespace App\Translation;

use Symfony\Component\Translation\Extractor\ExtractorInterface;
use Symfony\Component\Translation\MessageCatalogue;

/**
* Extracts custom translation strings.
*
*
@package App\Translation
*/
class TranslationsExtractor implements ExtractorInterface {

/**
* Prefix for new found message.
*
*
@var string
*/
private $prefix = '';

/**
* Returns the translation messages.
*
*
@return string[]
* All messages.
*/
protected function getMessages(): array {
$messages = [];

// TODO: Get all your translation strings here.
return $messages;
}

/**
* Extracts translation messages to the catalogue.
*
*
@param string|array $resource
* Files, a file or a directory.
*
@param \Symfony\Component\Translation\MessageCatalogue $catalogue
* The message catalogue.
*/
public function extract($resource, MessageCatalogue $catalogue) {
foreach ($this->getMessages() as $message) {
$catalogue->set($message, $this->prefix . $message);
}
}

/**
* {
@inheritdoc}
*/
public function setPrefix(string $prefix) {
$this->prefix = $prefix;
}

}

Tag it with name=translation.extractor & an alias.

# config/services.yml
services:
translation.translations_extractor:
class: App\Translation\TranslationsExtractor
tags:
- { name: translation.extractor, alias: custom }

This was written using Symfony version 5.1.6.

PHP Software & DevOps Engineer. Moved to https://thoeny.dev