1

可能重复:
基于原则的自定义 symfony 路由

我的项目中有几个与每种对象类型相关的 url。前任。

对于产品:

/product/product-1
/product/product-2

但现在我为一般信息管理创建了一个控制器。前任。使用条款,关于我们..等。

我想要只包含页面 slug 的 url。

/terms-use
/about-us

不是:

/page/terms-use
/page/about-us

如何在 routing.yml 中定义它?

4

1 回答 1

1

Venu 是对的,基于教义的自定义 symfony 路由提供了一种方法来做到这一点,如果你的 slug 参数是通过添加父页面的 slug 来构建的,这样孙子页面就有一个 slug,grandparent-slug/parent-slug/child-slug在这种情况下会抛出异常.

我们使用路由来匹配我给出的示例中的 slug,它需要在注释中使用一些正则表达式:

/**
 * @Route("{slug}", name="page_index", defaults={"slug" = false}, requirements={"slug" = "[0-9a-zA-Z\/\-]*"})
 * @Template()
 */
public function indexAction($slug)
{
    if ($slug !== false) {
        $page = $this->findPage($slug);

上述要求注释意味着 slug 可以是带有正斜杠和连字符的字母数字。然后,您需要实现一种方法findPage($slug),在正斜杠上分解 slug 并找到正确的子页面。

因为路由匹配很多其他路由,所以在 routing.yml 文件中最后包含这个控制器很重要,并且这个动作最后包含在控制器中的公共动作中,以便所有其他路由首先匹配。

编辑

这是我们为从上述 slug 中查找页面而编写的 findPage 方法:

protected function findPage($slug_string, $first_page = false)
{
    $slug_array = explode("/", $slug_string);
    $slug = array_shift($slug_array);
    $page = $this->em->getRepository("PagesBundle:Page")->getPageBySlug($slug, $this->site_id);
    if (!$page) {
        return false;
    }
    // if only the first matched page is required return it
    if ($first_page) {
        return $page;
    }
    // Otherwise loop through the slug array and match recursive 
    //children until slug array is empty or no match found
    while (!empty($slug_array)) {
        if ($page->getChildren()) {
            $slug = array_shift($slug_array);
            foreach ($page->getChildren() as $child_page) {
                if ($child_page->getSlug() == $slug) {
                    $page = $child_page;
                    break;
                }
            }
        } else {
            return false;
        }
    }

    return $page;
}
于 2013-01-18T06:17:10.253 回答