【问题标题】:Symfony 4 multilang routes with default fallback?Symfony 4 具有默认回退的多语言路由?
【发布时间】:2020-11-26 21:55:10
【问题描述】:

我正在尝试利用 Symfony 4 的多语言(或多语言环境)路由模式。

我的应用程序是真正的国际化应用程序,支持超过 25 种不同的语言,尽管翻译是渐进式的,而且许多路线还没有翻译成某些语言。

在这种情况下,我希望他们恢复为默认英语。

我的config/packages/translation.yaml 看起来像这样:

framework:
    default_locale: en
    translator:
        default_path: '%kernel.project_dir%/translations'
        fallbacks:
            - en

我的路线在routes.yaml 文件中定义。例如:

about_index:
    path:
        en: /about-us
        pl: /o-nas
    controller: Symfony\Bundle\FrameworkBundle\Controller\TemplateController
    defaults:
        template: About/index.html.twig

现在,每当我使用 plen 语言环境打开网站时 - 一切都按预期工作,但是当我将其设置为 de 时,我会收到 "Unable to generate a URL for the named route "about_index" as such route does not exist." 错误。

当所需区域设置中的路由尚不存在时,我如何强制 Symfony 回退到 en 路径?

【问题讨论】:

    标签: php symfony localization yaml url-routing


    【解决方案1】:

    所以,经过相当多的调查,似乎没有办法让它像 Symfony 的默认方法那样工作。

    我采用了“解决方法”方法,并使用我自己的 Twig 函数 autopath() 扩展了 Symfony 的 Twig Bridge 的路由扩展:

    namespace App\Twig;
    
    use Symfony\Bridge\Twig\Extension\RoutingExtension;
    use Twig\TwigFunction;
    
    // auto-wired services
    use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
    use Symfony\Component\HttpFoundation\RequestStack;
    
    /**
     * Extends Symfony's Twig Bridge's routing extension providing more flexible localization.
     *
     * @author Kyeno
     */
    class KyAutoPathExtension extends RoutingExtension
    {
        private $router;
        private $request;
    
        public function __construct(UrlGeneratorInterface $router, RequestStack $requestStack)
        {
            $this->router = $router;
            $this->request = $requestStack->getCurrentRequest();
    
            parent::__construct($router);
        }
    
        /**
         * {@inheritdoc}
         *
         * @return TwigFunction[]
         */
        public function getFunctions()
        {
            return [
                new TwigFunction('autopath', [$this, 'getPathAuto'], ['is_safe_callback' => [$this, 'isUrlGenerationSafe']])
            ];
        }
    
        /**
         * @param string $name
         * @param array  $parameters
         * @param bool   $relative
         *
         * @return string
         */
        public function getPathAuto($name, $parameters = [], $relative = false)
        {
            // obtain current and default locales from request object
            $localeRequested = $this->request->getLocale();
            $localeDefault = $this->request->getDefaultLocale();
    
            // build localized route name
            // NOTE: Symfony does NOT RECOMMEND this way in their docs, but it's the fastest that popped in my mind
            foreach([sprintf('%s.%s', $name, $localeRequested), sprintf('%s.%s', $name, $localeDefault)] as $nameLocalized) {
    
                // if such route exists, link to it and break the loop
                if($this->router->getRouteCollection()->get($nameLocalized)) {
    
                    return $this->router->generate($nameLocalized, $parameters, $relative ? UrlGeneratorInterface::RELATIVE_PATH : UrlGeneratorInterface::ABSOLUTE_PATH);
                }
            }
    
            // when no matches found, attempt relying on Symfony Twig Bridge's original path() function
            // (and likely fail with exception, unless they fix/allow it)
            return parent::getPath($name, $parameters, $relative);
        }
    }
    

    【讨论】:

      【解决方案2】:

      在 SF 4.4 上工作,使用注解:您可以声明双 @Route 注解,一个带有本地化路由,另一个没有本地化。如果不匹配第一个注释,将使用非本地化路由。

       * @Route({
       *      "fr": "/bonjour",
       *      "de": "/guten-tag"
       * }, name="hello_path")
       * @Route("/hello", name="hello_path")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-02
        • 1970-01-01
        • 2013-09-13
        • 1970-01-01
        • 2017-10-23
        • 1970-01-01
        • 1970-01-01
        • 2012-04-09
        相关资源
        最近更新 更多