【问题标题】:Specify route rules, and route to different components指定路由规则,路由到不同的组件
【发布时间】:2015-09-02 13:04:43
【问题描述】:

我知道如何使用Mason::Plugin::RouterSimple 为页面组件指定路由,例如给定一个 url:

/archives/2015/07

我可以像这样创建一个组件archives.mc

<%class>
  route "{year:[0-9]{4}}/{month:[0-9]{2}}";
</%class>
Archives for the month of <% $.month %>/<% $.year %>

同样,我可以创建一个news.mc 组件来处理以下网址:

/news/2012/04

这很好(而且非常优雅!)但现在我想要的是能够处理以下网址:

/john/archives/2014/12
/john/news/2014/03
/peter/news/2015/09
/bill/archives/2012/06

等等。我知道我可以将路由规则写成:

<%class>
  route "{user:[a-z]+}/archives/{year:[0-9]{4}}/{month:[0-9]{2}}", { action=> 'archives' };
  route "{user:[a-z]+}/news/{year:[0-9]{4}}/{month:[0-9]{2}}", { action=> 'news' };
</%class>

但是请求必须由两个不同的组件处理。如何将请求路由到不同的组件? archives.mcnews.mc 不会被 Mason 匹配,因为在组件名称之前有一个用户名。

【问题讨论】:

    标签: mason poet


    【解决方案1】:

    问题在于,虽然 /archives/2014/12 之类的 urs 可以通过 /archives.mc 组件轻松处理,但对于 /john/archives/2014/12/bill/archives/2012/06 之类的 url,尚不清楚将档案组件放在哪里。

    Mason 将尝试匹配以下组件(这是一个简化列表,请参阅Mason::Manual::RequestDispatch):

    ...
    /john/archives.{mp,mc}
    /john/dhandler.{mp,mc}
    /john.{mp,mc}
    

    但最后...

    /dhandler.{mp,mc}
    

    所以我的想法是在根目录下放一个dhandler.mc组件:

    <%class>
      route "{user:[a-z]+}/archives/{year:[0-9]{4}}/{month:[0-9]{2}}", { action=> 'archives' };
      route "{user:[a-z]+}/news/{year:[0-9]{4}}/{month:[0-9]{2}}", { action=> 'news' };
    </%class>
    <%init>
      $m->comp($.action.'.mi', user=>$.user, year=>$.year, month=>$.month);
    </%init>
    

    如果url匹配第一条路由,就会调用archives.mi组件:

    <%class>
      has 'user';
      has 'year';
      has 'month';
    </%class>
    <% $.user %>'s archives for the month of <% $.month %>/<% $.year %>
    

    (我使用了.mi 组件,因此只能在内部访问)。

    dhandler 可以改进(更好的正则表达式,可以从数据库表中检查用户并拒绝请求等)

    由于我的档案和新闻组件可以接受 POST/GET 数据,而且我想接受任何数据,我可以通过以下方式传递所有内容:

     $m->comp($._action.'.mi', %{$.args});
    

    不太优雅,但它看起来很有效。

    【讨论】:

    • 将“应用程序逻辑”从/user/action/... 切换到/action/user 会不会更容易(更简洁)? (在这种情况下,您将同时匹配 /archives.mc/news.mc。)这可以使用一些重写中间件来完成,例如在 URL 到达 Mason 之前。
    • @jm666 是的,从/user/action/... 切换到/action/user/... 会更容易、更干净。但是在这个特定的上下文中,我真的需要首先让用户保持 URL 的一致性......我正在考虑在它们到达 Mason 之前重写 url,但我不知道从哪里开始 :)
    猜你喜欢
    • 2018-10-23
    • 2018-10-20
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    • 2019-12-10
    相关资源
    最近更新 更多