可能重复:
基于原则的自定义 symfony 路由
我的项目中有几个与每种对象类型相关的 url。前任。
对于产品:
/product/product-1
/product/product-2
但现在我为一般信息管理创建了一个控制器。前任。使用条款,关于我们..等。
我想要只包含页面 slug 的 url。
/terms-use
/about-us
不是:
/page/terms-use
/page/about-us
如何在 routing.yml 中定义它?
可能重复:
基于原则的自定义 symfony 路由
我的项目中有几个与每种对象类型相关的 url。前任。
对于产品:
/product/product-1
/product/product-2
但现在我为一般信息管理创建了一个控制器。前任。使用条款,关于我们..等。
我想要只包含页面 slug 的 url。
/terms-use
/about-us
不是:
/page/terms-use
/page/about-us
如何在 routing.yml 中定义它?
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;
}