Symfony 3或4自定义翻译加载器

时间:2018-02-09 08:05:35

标签: symfony symfony4

我对symfony翻译模块非常困惑。 如何在配置文件中配置自定义转换加载器?

我有自定义加载程序,基于此示例: https://symfony.com/doc/current/components/translation/custom_formats.html

如果我把它放在控制器中,这是有效的

        $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' ) );

但我无法弄清楚如何将此注册为我的"默认"翻译装载机;因为这应该默认使用。

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 }

1 个答案:

答案 0 :(得分:0)

我做了一些测试,您的配置还可以。但是您必须遵守一些规则才能使其正确。 Symfony正在尝试从语言环境加载目录。因此,您必须将此语言环境放入文件名中:translations.de.csv

就像我在评论中说的那样,加载器只是加载数据,然后魔术就发生了,而symfony会小心地将消息放入目录中。正确的加载程序已由DelegatingLoader类解析和使用,因此必须在标记的服务中配置别名。

此处为演示:

Services.yaml

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 %}

messages.en.csv

symfony.great;Symfony is great

messages.fr.csv

symfony.great;Symfony est génial