简体   繁体   English

Symfony2 - 2路由到同一个bundle(可选参数)

[英]Symfony2 - 2 routes to same bundle (optional parameter)

I need my website to be accessible with 2 different URL, for example: 我需要使用2个不同的URL访问我的网站,例如:

/blog => Homepage / blog =>主页
/blog/article/1 => Article page (etc.) / blog / article / 1 =>文章页面(等)
/abcde/blog => Homepage / abcde / blog =>主页
/abcde/blog/article/1 => Article page (etc.) / abcde / blog / article / 1 =>文章页面(等)

When "abcde" is in my URL, I need to have the same controller/action running, but being able to get this "abcde" value (a few changes will result from this parameter). 当“abcde”在我的URL中时,我需要运行相同的控制器/操作,但能够获得此“abcde”值(此参数将导致一些更改)。

I have found many similar questions but never exactly what I am looking for: 我发现了许多类似的问题,但从来没有找到我想要的东西:

  • I am not looking for a language/translation routing bundle 我不是在寻找语言/翻译路由包
  • "abcde" parameter must be optional “abcde”参数必须是可选的
  • My bundle has several controllers and actions, I don't want to write 2 routes for each. 我的捆绑包有几个控制器和操作,我不想为每个编写2个路由。 (Neither do I want to have to update anything each time I add a new controller/action.) (每次添加新控制器/操作时,我都不想更新任何内容。)

  • Initial app/config/routing.yml 初始app / config / routing.yml

     mywebsite_blog: resource: "@MywebsiteBlogBundle/Resources/config/routing.yml" prefix: /blog/ 
  • If I simply add a second route, as resource is the same, it overwrites the first one. 如果我只是添加第二条路线,因为resource是相同的,它会覆盖第一条路线。

  • I tried to add an optional parameter on the initial route: 我试图在初始路线上添加一个可选参数:

     mywebsite_blog: resource: "@MywebsiteBlogBundle/Resources/config/routing.yml" prefix: /{_label}/blog/ defaults: {_label: mylabel} requirements: _label: .* 

That way I can access /abcde/blog , //blog , but not /blog (404). 这样我就可以访问/abcde/blog//blog ,但不能访问/blog (404)。


Not finding how to resolve my issue simply with using routing.yml (if it is possible I will be happy to learn how and stop there) , I read How to Create a custom Route Loader on Symfony doc. 没有找到如何使用routing.yml解决我的问题(如果有可能我会很高兴学习如何并停在那里) ,我阅读了如何在Symfony doc上创建自定义Route Loader I am not sure I'm going to the right direction but I tried it and manage to do a few things, still not exactly what I want. 我不确定我是否会朝着正确的方向努力,但我尝试了它并设法做了一些事情,但仍然不是我想要的。

LabelLoader.php LabelLoader.php

class LabelLoader extends Loader {
    private $loaded = false;

    public function load($resource, $type = null) {
        if (true === $this->loaded) {
            throw new \RuntimeException('Do not add the "label" loader twice');
        }

        $routes = new RouteCollection();

        // Prepare a new route (this is were I tried to play with it)
        $path = '/{_label}/blog/';
        $defaults = array(
            '_controller' => 'MywebsiteBlogBundle:Index:home',
        );
        $route = new Route($path, $defaults);

        // Add the new route to the route collection
        $routeName = 'labelRoute';
        $routes->add($routeName, $route);

        $this->loaded = true;

        return $routes;
    }

    public function supports($resource, $type = null) {
        return 'label' === $type;
    }
}

That way, /blog and /abcde/blog works the way I want to. 这样, /blog/abcde/blog按照我想要的方式工作。 I can access the _label variable in my _init() function (I'm using listeners and InitializableControllerInterface, in case it is important to know here) , checking if empty or not, etc. But obviously it works for only one controller/action ( Index:home ). 我可以在我的_init()函数中访问_label变量(我正在使用listeners和InitializableControllerInterface,以防这里知道很重要) ,检查是否为空等等。但显然它只适用于一个控制器/动作( Index:home )。 I would like to change this so that it can works for my whole MywebsiteBlogBundle. 我想改变它,以便它可以适用于我的整个MywebsiteBlogBu​​ndle。


In my custom Loader, I wanted to test something like: 在我的自定义Loader中,我想测试类似于:

$routes = new RouteCollection();

// Hypotetical function returning all the routes I want to have twice.
// Methods getPath() and getController() called below are hypotetical too.
$mywebsiteBlogRoutes = getExisitingMywebsiteBlogBundleRoutes(); 

foreach($mywebsiteBlogRoutes as $blogRoute) {

    // Prepare a new route
    $path = '/{_label}/blog/'.$blogRoute->getPath();
    $defaults = array(
        '_controller' => $blogRoute->getController(),
    );
    $route = new Route($path, $defaults);

    // Add the new route to the route collection
    $routeName = 'labelRoute';
    $routes->add($routeName, $route);
}

But: 但:

  • It does not seem very clean (but if that's the only way I find to do it for now, I'll try it) 它似乎不是很干净(但如果这是我现在发现它的唯一方法,我会试试)

  • I tried to get all my routes reading this answer and as soon as I try $collection = $router->getRouteCollection(); 我试着让我所有的路线都读到这个答案 ,一旦我尝试$collection = $router->getRouteCollection(); I have a "Circular reference detected" error that I don't manage to fix. 我有一个“检测到循环引用”错误,我无法修复。 I'm trying to understand what's happening here. 我想知道这里发生了什么。 Edit: I fixed it. 编辑: 我修好了。 Still, I don't think it's a very clean solution. 不过,我认为这不是一个非常干净的解决方案。


Should I go back to routing.yml or is it possible to do something here with the custom Routing Loader? 我应该回到routing.yml还是可以使用自定义路由加载器做一些事情?

You should try this in your routing.yml : 你应该在routing.yml尝试这个:

mywebsite_blog:
    resource: "@MywebsiteBlogBundle/Resources/config/routing.yml"
    prefix:   /{_label}blog/
    defaults: {_label: mylabel/}
    requirements:
        _label: ([\w\d]+/)?

Results: 结果:

app/console router:match /mylabel/blog/  # OK
app/console router:match /blog/          # OK

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM