【问题标题】:Translating navigation breadcrumbs翻译导航面包屑
【发布时间】:2017-10-05 16:06:21
【问题描述】:

我正在尝试翻译 module/Application/config/module.config.php 配置文件中的面包屑,例如:

'navigation' => array(
    'default' => array(
        array(
            'label' => \Application\Util\Translator::translate('Home'),
            'route' => 'home',
            'resource' => 'route/home',
            'pages' => array(
            ),
        ),

面包屑Home 应该在法语中显示为Accueil

翻译器适用于应用程序的其余部分。但是没有一个面包屑被翻译。语言资源文件已经过一遍又一遍的验证和poedited。

在同一个配置文件中,是翻译器

configuration:
    'service_manager' => array(
        'factories' => array(
            'account_navigation' => 'Application\Navigation\Service\AccountNavigationFactory',
            'navigation' => 'Zend\Navigation\Service\DefaultNavigationFactory',
            'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
            'Application\Collector\RouteCollector'  => 'Application\Service\RouteCollectorServiceFactory',
        ),
    ),
    'translator' => array(
        'locale' => 'fr_FR',  // langue par défaut
        'translation_file_patterns' => array(
            array(
                'type'     => 'gettext',
                'base_dir' => __DIR__ . '/../language',
                'pattern'  => '%s.mo',
            ),
        ),
        'translation_files' => array(
            array(
                'type'     => 'phpArray',
                'filename' => __DIR__ . '/../../../vendor/zendframework/zendframework/resources/languages/fr/Zend_Validate.php',
                'locale'   => 'fr_FR'
            ),
            array(
                'type'     => 'gettext',
                'filename' => __DIR__ . '/../../../vendor/zf-commons/zfc-user/src/ZfcUser/language/fr_FR.mo',
                'locale'   => 'fr_FR'
            ),
            array(
                'type'     => 'phpArray',
                'filename' => __DIR__ . '/../language/fr_FR.php',
                'locale'   => 'fr_FR'
            )
        )
    ),

我的应用程序引导程序如下所示:

class Module
{

    public function onBootstrap(MvcEvent $e)
    {
        $eventManager = $e->getApplication()->getEventManager();
        $moduleRouteListener = new ModuleRouteListener();

        $sm = $e->getParam('application')->getServiceManager();

        // Add ACL information to the Navigation view helper
        $authorize = $sm->get('BjyAuthorize\Service\Authorize');
        $acl = $authorize->getAcl();
        $role = $authorize->getIdentity();
        \Zend\View\Helper\Navigation::setDefaultAcl($acl);
        \Zend\View\Helper\Navigation::setDefaultRole($role);

        $id = $sm->get('zfcuser_auth_service')->getIdentity();
        if (! is_null($id)) {
            $em = $sm->get('Doctrine\ORM\EntityManager');
            $usr = $em->find('Application\Entity\User', $id->getId());

            $blameableListener = new \Gedmo\Blameable\BlameableListener();
            $blameableListener->setUserValue($usr);
            $em->getEventManager()->addEventSubscriber($blameableListener);
        } else {
            // redirection
            if (isset($_SERVER['SERVER_NAME']) && preg_match('/monxxxxx/', $_SERVER['SERVER_NAME'])) {
                $strategy = new RedirectionStrategy();
                $strategy->setRedirectRoute('driver/login');
                $eventManager->attach($strategy);
            }
        }
        if ($sm->has('MvcTranslator')) {
            \Zend\Validator\AbstractValidator::setDefaultTranslator($sm->get('MvcTranslator'));
        }

        Locale::setDefault('fr_FR');

        // custom layout
        $e->getApplication()->getEventManager()->getSharedManager()->attach('Zend\Mvc\Controller\AbstractController', 'dispatch', function($e) {
            $route = $e->getRouteMatch();
            $controller = $e->getTarget();
            // change layout for login
            if($route->getParam('controller') == 'zfcuser' && $route->getParam('action') == 'login'){
                $controller->layout('layout/login');
            }
        }, 100);

        // Log the exceptions
        $application   = $e->getApplication();
        $sm = $application->getServiceManager();
        $sharedManager = $application->getEventManager()->getSharedManager();
        $sharedManager->attach('Zend\Mvc\Application', 'dispatch.error',
          function($e) use ($sm) {
            if ($e->getParam('exception') && strpos($e->getParam('exception'), 'are not authorized') === false) {  
              $sm->get('Zend\Log\Logger')->crit($e->getParam('exception'));

              $toEmail = "xxxxx@xxxxx.com";
              $toName = "Service IT";
              $subject = "Exception error";
              $body = $e->getParam('exception');
              \Application\Util\Common::sendMail($toEmail, $toName, $subject, $body);
            }
          }
        );
    }

    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }

    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__
                )
            )
        );
    }

    public function init($moduleManager)
    {
         $moduleManager->loadModule('ZfcUser');
    }
}

我在 ZF2 2.2.5

【问题讨论】:

    标签: zend-framework2


    【解决方案1】:

    可能是一个愚蠢的问题,但是您有 PHP gettext 模块(通过您的phpinfo() 验证)吗?如果是,您可以更轻松地将_('Translatable string') 用于需要翻译的字符串。在language 文件夹(在srcpublic 等旁边)中有一个.mo.po 文件。

    (询问上述问题是因为您似乎为此付出了很多努力,即使您的代码显示您使用gettext 作为翻译器,这应该允许您已经翻译静态字符串,例如home in配置文件)

    以下图为例,这是我自己的 ZF2 供应商模块之一的基本设置:

    接下来,您需要Poedit(免费版应该很多。)。

    注意:确保始终使用 Poedit 编辑 .mo/.po 文件。

    使用 Poedit 打开 language 文件夹中的文件,无需“翻译”与应为语言相同的字符串,除非您使用字符串的快捷方式(即“索引”字符串应该显示“显示概览”,但请不要:p)

    在 Poedit 中,您有几个选项可以添加它在文件中搜索的其他字符串,您还可以添加其他文件扩展名。我建议你让它寻找这些字符串:

    • $this->translate()
    • _()

    以及这些文件扩展名:

    • .php
    • .phtml

    这样您就掌握了基础知识。当然,您的设置可能会有所不同,因此请根据需要进行修改。

    最后,您需要在模块配置中注册gettext PHP 扩展的使用。您需要为每个模块执行此操作,因为您需要提供语言文件夹路径,因为这是您的模块“应该”翻译的地方(尽管如果必须,可以随意将其设为全局并拥有一个巨大的翻译文件,不推荐)。

    将以下位添加到您的 module.config.php 文件中:

    'translator' => [
        'locale' => 'en_US', // This line needs to be in the "root" config, feel free to override with/per module settings and/or user settings
        'translation_file_patterns' => [
            [
                'type'     => 'gettext',
                'base_dir' => __DIR__ . '/../language',
                'pattern'  => '%s.mo',
            ],
        ],
    ],
    

    有了以上所有,翻译你的面包屑应该像这样完成:

    'navigation' => array(
        'default' => array(
            array(
                'label' => _('Home'),
                'route' => 'home',
                'resource' => 'route/home',
                'pages' => array(
                ),
            ),
    

    【讨论】:

    • 我总是在 .po 文件中写入,然后用 poedit 打开它并保存。翻译在应用程序的所有页面上都可以正常工作,除了未翻译的面包屑。这似乎是翻译器加载不够快的问题。
    • 你用_('The string')试过了吗?由于gettext 是一个PHP 模块,它与PHP 一起加载,因此始终可用。您使用的函数\Application\Util\Translator::translate('Home') 确实可以在Util\Translator 加载后 被翻译,因此不会翻译字符串。
    • 我可以在 phpinfo 输出中看到 Alex Plotnick 的模块 GetText,当我在我的资源 module/Application/language/fr_FR.po 文件上打开 poedit 时,它会在目录属性中列出一些关键字:translate, setLabel, addSuccessMessage, addMessage, addErrorMessage, addInfoMessage, sprintf但在未定义函数的面包屑错误中使用 _('Home')。
    • 嗯,您正在使用的操作系统可能会导致其他问题,因为正常的_('something') 应该可以工作。看看这些关于 SO 的问答:thisthis。它们可能包含指向正确方向的提示,所有关于在您使用/使用的机器上处理语言环境(即 Docker 设置)以及将 PHP 与语言环境安装设置等相结合。
    • gettext 模块实际上没有安装在我的 php 服务器上。我重建了它,它现在已安装并接受 _('...') 构造。但它仍然显示位于结构内的语言键而不是其翻译。例如,它在'label' => _('Home'), 语句上显示Home 而不是Accueil
    【解决方案2】:

    似乎命名空间Zend\View\Helper\Navigation\Breadcrumbs;在您的服务管理器中未正确实例化。因此,翻译器将无法工作,因为它也是由服务管理器作为依赖项提供的

    你应该做的是验证Zend\View\Helper\Navigation\Breadcrumbs::line#113 在你加载你的面包屑时是否真的被解析了。至少这个。

    您也可以查看AbstractHelper的方法htmlify来测试是否启用了翻译器。

    【讨论】:

    • 这里是vendor/zendframework/zendframework/library/Zend/View/Helper/Navigation/Breadcrumbs.php文件的第113行的内容:$html = $translator->translate($html, $this->getTranslatorTextDomain());。请问您验证它是否已解析是什么意思?干杯。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多