当前位置: 首页 > 知识库问答 >
问题:

Symfony路由:类前缀注释中的可选区域设置目录

百里沛
2023-03-14

我需要能够定义/{_locale}部分是可选的路由。这意味着我需要这些URL使用相同的控制器:

  1. 我的域名。com/(语言环境将由请求侦听器设置)

这同样适用于:

问题是我不能定义两个class@Route注释,因为这是无效的/Symfony不接受的;我不能在我的控制器类中复制每一条路由,因为会有大量的路由,这将非常糟糕!

我尝试过只使用一个类注释,但无法使其正常工作。以下是我的尝试:

/**
 * @Route("/{_locale}", requirements={"_locale": "(\w{2,3})?"})
 */
class DefaultController extends Controller {

    /**
     * @Route("/")
     * @param Request $request
     * @return Response
     */
    public function indexAction(Request $request) {
        return new Response('index '.$request->getLocale());
    }

    /**
     * @Route("/my-page")
     * @param Request $request
     * @return Response
     */
    public function testAction(Request $request) {
        return new Response('test '.$request->getLocale());
    }

}

结论:

  1. 作品
  2. 作品
  3. 失败(因为只有my domain.com//my page可以工作)
  4. 工作

我以为问题出在前导斜杠上,所以我试了一下:

/**
 * @Route("{slash_and_locale}", requirements={"slash_and_locale": "\/?(\w{2,3})?"}, defaults={"slash_and_locale": ""})
 */
class DefaultController extends Controller { // ...

结论:

  1. 作品

我见过这个(旧)问题,但还没有给出正确的答案:(

有人有建议吗?会很有帮助的,谢谢!

共有3个答案

国胤
2023-03-14

我通过扩展routingComponent找到了一种定制routingComponent的方法。这样,将重试每个不匹配路由的url,并使用默认区域设置作为url前缀

<?php

namespace App\Component;

use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Matcher\UrlMatcher as BaseUrlMatcher;

class UrlMatcher extends BaseUrlMatcher
{
    public function match($pathinfo)
    {
        try {
            return parent::match($pathinfo);
        } catch (ResourceNotFoundException $exception) {
            $url = sprintf('/%s%s', 'en', $pathinfo);

            return parent::match($url);
        }
    }
}

在参数中设置新的urlMatcher:

parameters:
        # UrlMatcher
        router.options.matcher.cache_class: ~
        router.options.matcher_class: App\Component\UrlMatcher
池庆
2023-03-14

我在我的项目(yml)中这样做

language_selection:
    path: /{locale}/{path}
    defaults: { _controller: PurchaserBundle:Home:langSelection, path: "" }
    requirements:
        path:  .+
        locale: es|ca|en

在控制器中:

public function langSelectionAction($locale, $path)
{
    if (in_array($locale, array('es', 'en', 'ca'))) {
        return $this->redirect('/' . $path);
    }

    $this->create404NotFound();
}

这也许是解决问题的基本方法,但确实有效。所有“默认”路由都有效,如果您使用任何区域设置前缀访问站点,您的侦听器将更改语言,并且此控制器将重定向到当前语言中的正确路由。

我希望它能有所帮助。

刁浩言
2023-03-14

以下是我最终决定要做的:

  1. 不管我想要什么,我为每个控制器操作定义了两条路由(参见下面的示例)
  2. 我扩展Symfony的RoutingExtension以在使用pathurl方法时自动选择正确的路由

下面是我的双路由配置(注意双路由,第二个有locale后缀):

<?php

// src\AppBundle\Controller\DefaultController.php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;

class DefaultController extends Controller {

    /**
     * @Route("/", name="front_index")
     * @Route("/{_locale}/", name="front_index+locale", requirements={"_locale": "\w{2,3}"})
     * @return Response
     */
    public function indexAction() {
        return $this->render('test/domain-translation.html.twig');
    }

}

这是我的RoutingExtension重载:

<?php

// src\AppBundle\Twig\LocaleRoutingExtension.php

namespace AppBundle\Twig;

use AppBundle\Document\Domain;
use Symfony\Bridge\Twig\Extension\RoutingExtension;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;

class LocaleRoutingExtension extends RoutingExtension {

    /** @var ContainerInterface */
    protected $container;

    /** @var Domain */
    protected $domain;

    /** @var Request */
    protected $request;

    public function setContainer(ContainerInterface $container) {
        $this->container = $container;
        $this->domain = $this->container->get('app.domain_service')->getDomain();
        $this->request = $this->container->get('request_stack')->getMasterRequest();
    }

    protected function processNameAndParameters($name, $parameters) {

        $nameWithLocale = $name . '+locale';
        $routes = $this->container->get('router')->getRouteCollection();
        $route = $routes->get($nameWithLocale);

        if (array_key_exists('no-locale-filter', $parameters) && $parameters['no-locale-filter']) {
            unset($parameters['no-locale-filter']);
            return array('name' => $name, 'parameters' => $parameters);
        }

        if (isset($this->domain) && $this->domain->hasMultipleLocales() && isset($route)) {
            $name = $nameWithLocale;

            $locale = null;
            if (!array_key_exists('_locale', $parameters)) {
                if (isset($this->request)) {
                    $locale = $this->request->getLocale();
                } else {
                    $locale = $this->domain->getDefaultLocale();
                }
            }

            $parameters['_locale'] = $locale;
        }

        return array('name' => $name, 'parameters' => $parameters);
    }

    public function getPath($name, $parameters = array(), $relative = false) {
        $processed = $this->processNameAndParameters($name, $parameters);
        return parent::getPath($processed['name'], $processed['parameters'], $relative);
    }

    public function getUrl($name, $parameters = array(), $schemeRelative = false) {
        $processed = $this->processNameAndParameters($name, $parameters);
        return parent::getUrl($processed['name'], $processed['parameters'], $schemeRelative);
    }

}

我希望这有帮助!

 类似资料:
  • 我在我的注解里有。yaml使用注释管线设置的以下设置: 我这里的问题是,我可以创建一个像是否不带区域设置前缀? 这是保护区,我可以使用用户语言。我尝试使用这个symfony路由文档,但我希望保留注释。 目前它看起来像,但我希望。

  • 我只在个人项目中使用symfony路由组件(没有完整的symfony框架)。我的方法是:在文件如下: 我的路由工作正常,但我需要添加自动区域设置前缀uri/路由多语言系统像这样: 如何在文件并删除默认的区域设置前缀语言?!

  • 我有一个i18n项目在Symfony 4.1上运行。 我想实现一些路由,如: /= 在本文之后,我将使用注释处理路由,并为注释路由设置全局前缀: 这样,从'.../src/Controller/'注释中定义的所有路由都带有前缀,这导致我的“选择语言”页面和主页之间的冲突。 我想从i18n前缀中排除“选择语言”页面,这样当主页可以停留在 /fr或 /en.时,我就可以使用“/”了 有什么办法可以做到

  • 我在Symfony 4应用程序中找不到有关全局路由前缀的任何信息。我唯一发现的是用注释控制器。但我不使用注释,我需要所有控制器都具有相同的前缀。 现在我可以在S3中这样在文件: 但是S4是没有捆绑的,我不能做同样的事情——我必须创建一个我不需要的捆绑。 是否可以在Symfony 4中定义一个全局路由前缀,或者我将在每个根目录前添加前缀/创建一个自定义路由加载器,尤其是在YAML中配置路由时?

  • 我在symfony 2.5中的区域设置路由遇到问题。假设我的默认语言是英语。我的示例路由是/user/register/。如果我要求它没有任何语言环境,它应该出现在英文翻译。如果我使用区域设置(例如/fr/user/register/)请求它,它应该与它一起出现。这可以通过以下方式完成: 现在我必须回答以下问题: 我如何简单地避免用户可以使用默认语言作为区域设置来调用路由?在我的示例中,英语是默认

  • 我安装了三个区域设置捆绑包: JMSi18nRoutingBundle 我的如下所示: 一切都按我的喜好工作,除了我在日志中发现了一个错误: 在堆栈中我发现:的区域设置,但是,我不明白如何将区域设置设置为“en_US”。 我想它来自于对Lunetics的猜测,但是有“en_US”的人应该匹配“en”,而不是“en_US”。 我的主要问题是,我不知道如何跟踪这一点。当我用自己的设置连接到主页时,首先