【问题标题】:forward request to controller action将请求转发到控制器操作
【发布时间】:2012-11-28 16:58:44
【问题描述】:

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

例如,以下网址:
/home/peter
内部应该变成
/home/people/peter

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

需要注意的两件事:

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

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

SilverStripe 版本:3.0.3

【问题讨论】:

    标签: silverstripe


    【解决方案1】:

    我建议使用static $url_handlers 描述的here,它允许您定义具体的动作路线。您的用例可以通过使用包罗万象的 url-handler 来实现。

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

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

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

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

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 感谢您在这里分享一些见解,幸运的是 Stefan 的“包罗万象”的方法对我有用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多