2

我想将请求转发给控制器以执行某些特定操作,而无需重定向到另一个 url。

因此,例如,以下网址:
/home/peter
应在内部变为
/home/people/peter

我知道我可以在“init”函数中捕获操作名称(“peter”),然后执行 Controller::redirect,但我想留在同一个 url,只需将请求在内部转发给“人” ' 行动。

2点需要注意:

  • 'peter' 是一个动态字符串,所以我不能为此硬编码一条路线
  • 控制器的任何其他操作仍然可以工作,因此只有几个字符串应该被转发(例如,'peter'、'ann' 被转发到 'people' 操作,而 'otherAction' 仍然是可调用的)

我已经在 Controller 类中找到了“handleAction”和“handleRequest”方法,但无法想象如何将它们用于我的任务。

SilverStripe 版本:3.0.3

4

2 回答 2

3

我建议使用static $url_handlersdescribe here,它允许您定义特定的操作路线。您的用例可以通过使用包罗万象的 url-handler 来实现。

但是因此我们必须注意每条路线的顺序。包罗万象的路线必须在最后定义。所有其他操作之前都需要一个单独的 url 处理程序:

public static $url_handlers = array(
    'otherAction' => 'otherAction',
    // ...
    'people/$Name' => 'people',
    '$Name' => 'people' // catch-all
);

这应该符合你的解释。最后一条路由捕获之前未处理的所有动态路由。

但正如 Ingo 所提到的,两条路线都将提供相同的内容,这可能对 SEO 不利。您可以将第二条路由定位people/$Name到不同的操作,该操作仅使用 301 重定向到 url $Name。如果您已经有公共内容并且想用短版本替换现有的 URL,我会推荐这个。

我希望这可以解决您的问题(暂时)。

于 2012-11-29T22:14:53.177 回答
1

首先,我假设您有充分的理由制作重复的 URL(对 SEO 不利):)

我已经尝试了一点Director::direct(),这将是最干净的,但没有得到任何结果。Director::test()重置大多数请求状态,因此也不符合条件。在一个新的控制器实例上调用handleRequest()或调用handleAction()是很棘手的,因为Director那时已经建立了很多状态(例如推送到控制器堆栈)。

因此,不幸的是,SilverStripe 路由不是那么灵活,您所做的任何事情都会深入到系统内部,并可能在下一个版本中中断。

于 2012-11-29T10:08:47.843 回答