【问题标题】:Symfony routing bundle - remove trailing slash from locale in URL: /en/ → /enSymfony 路由包 - 从 URL 中的语言环境中删除尾部斜杠:/en/ → /en
【发布时间】:2016-10-18 12:40:46
【问题描述】:

我有以下设置:

一切正常。但是有个小问题我想不通:

  • 路由被正确翻译并且路由结尾没有斜杠:
    test.com/en/contact
  • 不幸的是 homepage 路由尾部有一个斜杠:
    test.com/en/ 应该是 test.com/en
  • test.comtest.com/en 的调用也被重定向到test.com/en/

我怎样才能去掉这个斜杠?


这是我的配置:

我已经在 parameters.yml 中设置了语言环境:

parameters:
    locale: de
    locales: [de, en]

我已经在 config.yml 中配置了 JMS 路由包:

jms_i18n_routing:
    default_locale: "%locale%"
    locales: "%locales%"
    strategy: prefix

我在 routing.yml 中的路线:

app:
    prefix: /
    resource: '@AppBundle/Controller/AppController.php'
    type: annotation
    options: { i18n: true }

我的索引/默认操作是这样注释的:

/**
 * @Route("/", name="homepage")
 */
public function indexAction(Request $request) {}

/web 中的 .htaccess 文件是 Symfony 3.1 附带的样板文件


我已经尝试删除注释中的/ (@Route("", name="homepage")) 但没有任何运气。

【问题讨论】:

  • 您找到解决方法了吗?得出了同样的结论。在使用应用程序时是否使用斜线都可以,但在使用路由时,斜线将始终附加到主页。 (i18n 与否)

标签: symfony url-routing


【解决方案1】:

我认为这是由于使用时相对 URL 的工作方式:

<a href="{{ path('homepage') }}">Homepage<a>

生成的链接必须是“/”,否则它将不起作用,它会转到相同的实际页面而不是主页。

【讨论】:

    【解决方案2】:

    这是我的解决方案。首先,您必须将路线翻译定义为空字符串。我正在使用 yaml 配置。

    # AppBundle/Resources/config/routing.yml
    homepage:
      path:     /
      defaults: { _controller: AppController:Page:index }
    
    # AppBundle/Resources/translations/routes.de.yml
    # AppBundle/Resources/translations/routes.en.yml
    # and other routes translation files...
    homepage: ''
    

    现在尾部的斜杠被删除了,但是当我们尝试访问没有语言环境参数的页面 (www.mypage.com) 时,它首先被重定向到 www.mypage.com/en/,然后是 www.mypage.com/en。

    由JMS\I18nRoutingBundle\EventListener\LocaleChoosingListener引起,onKernelException方法最后一行: $event-&gt;setResponse(new RedirectResponse($request- &gt;getBaseUrl().'/'.$locale.'/'.($params ? '?'.http_build_query($params) : '')));这部分更准确地说:'$locale' . '/'

    我们可以做的是覆盖这个监听器。我是这样做的:

    # AppBundle/Resources/config/services.yml
    parameters:
      jms_i18n_routing.locale_choosing_listener.class: AppBundle\EventListener\LocaleChoosingListener
    
    # AppBundle/EventListener/LocaleChoosingListener
    <?php
    
    namespace AppBundle\EventListener;
    
    use JMS\I18nRoutingBundle\EventListener\LocaleChoosingListener as BaseListener;
    use JMS\I18nRoutingBundle\Router\LocaleResolverInterface;
    use Symfony\Component\HttpFoundation\RedirectResponse;
    use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
    use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
    use Symfony\Component\HttpKernel\HttpKernelInterface;
    use Symfony\Component\Routing\Exception\ResourceNotFoundException;
    
    /**
     * Removing trailing slash from homepage requests
     * {@inheritdoc}
     */
    class LocaleChoosingListener extends BaseListener
    {
        private $defaultLocale;
        private $locales;
        private $localeResolver;
    
        public function __construct($defaultLocale, array $locales, LocaleResolverInterface $localeResolver)
        {
            parent::__construct($defaultLocale, $locales, $localeResolver);
    
            // If these properties were protected, we could remove the constructor.
            $this->defaultLocale = $defaultLocale;
            $this->locales = $locales;
            $this->localeResolver = $localeResolver;
        }
    
         public function onKernelException(GetResponseForExceptionEvent $event)
        {
            if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
                return;
            }
    
            $request = $event->getRequest();
    
            if ('' !== rtrim($request->getPathInfo(), '/')) {
                return;
            }
    
            $ex = $event->getException();
    
            if (!$ex instanceof NotFoundHttpException || !$ex->getPrevious() instanceof ResourceNotFoundException) {
                return;
            }
    
            $locale = $this->localeResolver->resolveLocale($request, $this->locales) ?: $this->defaultLocale;
    
            $request->setLocale($locale);
    
            $params = $request->query->all();
            unset($params['hl']);
    
            $event->setResponse(new RedirectResponse($request->getBaseUrl().'/'.$locale.($params ? '?'.http_build_query($params) : '')));
        }
    }
    

    【讨论】:

    • 嗨 Mateusz Banaś 在集成 jms_i18n_routing.locale_choosing_listener.class 时:Services.yml 中的 CoreBundle\EventListener\LocaleChoosingListener *** 有这个错误=>(!)致命错误:未捕获的异常 'Symfony\Component\DependencyInjection \Exception\ServiceCircularReferenceException' 带有消息“检测到服务“jms_i18n_routing.locale_choosing_listener”的循环引用,路径:“jms_i18n_routing.locale_choosing_listener”。在 C:\wamp64\www\candidate\app\bootstrap.php.cache 第 2168 行
    • 你好。我没有遇到这个错误。我已经用 symfony 2.7 和 jms/i18n-routing-bundle v2.0.1 对其进行了测试。这个错误通常意味着两个服务相互依赖,symfony 不知道应该先加载哪个。您是否在 services.yml 中编辑了 jms_i18n_routing.locale_choosing_listener 的参数?或其他 jms_i18n_routing 服务,如 jms_i18n_routing.locale_resolver?如果是,请在此处粘贴服务定义。
    【解决方案3】:

    php bin/控制台调试:路由器

        ru__RG__main                   ANY      ANY      ANY    /                                  
        en__RG__main                   ANY      ANY      ANY    /en/                                
        ua__RG__main                   ANY      ANY      ANY    /ua/
    

    创建翻译文件

    routes.ru.yml
    routes.en.yml
    routes.ua.yml
    

    添加了这个('main' - 这是我的路线名称) main: ''

        php bin/console debug:router
        
        ru__RG__main                   ANY      ANY      ANY    /                                  
        en__RG__main                   ANY      ANY      ANY    /en                              
        ua__RG__main                   ANY      ANY      ANY    /ua
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-09
      相关资源
      最近更新 更多