I am very confused by symfony translation module. How can one configure a custom translation loader in the config files?
I have my custom loader an it works, based on this example: https://symfony.com/doc/current/components/translation/custom_formats.html
This works, if I put it in a controller
$translator = new Translator( 'de' );
$translator->addLoader( 'my_format', new MyCsvLoader() );
$translator->addResource( 'my_format', $root . '/translations/translations.csv', 'de' );
var_dump( $translator->trans( 'LB_ABOUT' ) );
But I cannot figure it out how can I register this as my "default" translation loader; as this should be used by default.
https://symfony.com/doc/current/reference/dic_tags.html#dic-tags-translation-loader
translation.yaml
framework:
default_locale: 'en'
translator:
paths:
- '%kernel.project_dir%/translations/'
fallbacks:
- '%locale%'
services.yaml:
App\Translate\MyCsvLoader:
tags:
- { name: translation.loader, alias: csv }
i did some test and your configuration is ok. But you have to respect some rules to make it right. Symfony is trying to load catalog from a locale. So you have to put this locale in your filename: translations.de.csv
Like i said in my comment the loader is only to load data then the magic happens and symfony take care to put messages in the catalog. The right loader is resolved and use by a DelegatingLoader
class, that's why you have to configure an alias in the tag's service.
here a demo:
App\Translate\MyCsvLoader:
tags:
- { name: translation.loader, alias: csv }
framework:
default_locale: 'en'
translator:
default_path: '%kernel.project_dir%/translations'
fallbacks:
- '%locale%'
<?php
namespace App\Translate;
use Symfony\Component\Translation\Exception\NotFoundResourceException;
use Symfony\Component\Translation\Loader\FileLoader;
class MyCsvLoader extends FileLoader
{
private $delimiter = ';';
private $enclosure = '"';
private $escape = '\\';
/**
* {@inheritdoc}
*/
protected function loadResource($resource)
{
$messages = [];
try {
$file = new \SplFileObject($resource, 'rb');
} catch (\RuntimeException $e) {
throw new NotFoundResourceException(sprintf('Error opening file "%s".', $resource), 0, $e);
}
$file->setFlags(\SplFileObject::READ_CSV | \SplFileObject::SKIP_EMPTY);
$file->setCsvControl($this->delimiter, $this->enclosure, $this->escape);
foreach ($file as $data) {
if ('#' !== substr($data[0], 0, 1) && isset($data[1]) && 2 === \count($data)) {
$messages[$data[0]] = $data[1];
}
}
return $messages;
}
/**
* Sets the delimiter, enclosure, and escape character for CSV.
*
* @param string $delimiter Delimiter character
* @param string $enclosure Enclosure character
* @param string $escape Escape character
*/
public function setCsvControl($delimiter = ';', $enclosure = '"', $escape = '\\')
{
$this->delimiter = $delimiter;
$this->enclosure = $enclosure;
$this->escape = $escape;
}
}
/**
* @Route("/{_locale}/test", name="test", requirements={"_locale": "en|fr"})
*/
public function index()
{
return $this->render('index.html.twig');
}
{% extends 'base.html.twig' %}
{% block body %}
<p>{{ 'symfony.great'|trans }}</p>
{% endblock %}
symfony.great;Symfony is great
symfony.great;Symfony est génial
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With