码神之路:Perl篇

Mojolicious::Plugin::PlainRoutes

2018-01-17  本文已影响8人  JSON_NULL

这个是我过了好久才找到的一个可以用配置文件来写Router的Mojolicious插件。

下面是部分源码(这个仅对我个人有用,记录在此)

my %grammar = (
    comment    => qr{ \# [^\n]* }x,
    verb       => qr{ ANY | DELETE | GET | PATCH | POST | PUT }x,
    path       => qr{ / [^#\s]* }x,
    arrow      => qr{ -> }x,
    scope      => qr( { | } )x,
    action     => qr{ [\w\-:]* \. \w* }x,
    name       => qr{ \( [^)]+ \) }x,
    eol        => qr{ \n }x,
    space      => qr{ [^\S\n]+ }x,
);

使用方式

加载插件的方式如下

$self->plugin('PlainRoutes', {
    # Specify the path of the routes file
    file => $self->home->rel_file('path/to/myapp.routes'),

    # Get automatic names for routes of the form "controller-action"
    autoname => 1,

    # or do it with a callback
    autoname => sub {
        my ($verb, $path, $controller, $action) = @_;
        return "$controller-$action";
    },
});

在你的app的主PM文件中加入以上代码,就可以使用配置文件来写Router了。

参数说明

file

file参数用来说明配置文件的位置。这个参数是可选的,默认情况下是从lib目录下读取名为 $app->moniker 扩展名为routes的文件。

$conf->{file} //= $app->home->rel_file("lib/".$app->moniker.".routes");

autoname

autoname 可以指定为布尔值,也可以指定为一个coderef。默认值为 undef。

如果其值为undef,则使用Mojolicious::Routes中的默认方式生成Route的name属性。
如果其值为布尔值的true,则会为Route生成格式为"controller-action"的name属性。
如果其值为一个coderef,则这个coderef需要返回一个字符串作为Route的name属性值。
也就是说你可以传一个coderef给autoname,定义自己的生成Route中name属性的方法。面这个coderef会接收到插件传给它的四个参数。它们分别是($verb, $path, $controller, $action) 。

配置文件格式

示例

ANY / -> Foo.do {
    GET /bar -> Foo.bar
    ANY /baz -> Foo.baz {
        GET /quux -> Foo.quux
    }
}

GET /foo/bar/baz/quux -> Foo::Bar::Baz.quux (fbb-quux)

每个Route由四部分组成,分别如下:

  1. verb、http词,也即http的方法。必须大写。
  2. path、路径,也即是http请求的路径。支持Route中所有类型的占位符。
  3. controller.action,用.分隔的控制器包名和方法名。其中controller中可以包含::
  4. Route的name属性值,也就是路径的名称。这个是可以选的,如果不写,则会自动生成。

其实在 1、2 与 3、4 之间还有一个可以省略 ->,在真正写配置文件时虽然可以省略,但强烈建议不要活力。因为带着它会使配置文件的结构更加清晰。

对注释的支持

在配置文件还支持注释,所有以#开始直到行尾的内容都会被当成注释。在解析时会被忽略掉。

对子路由的支持

在上面的配置文件示例代码中应该可以看到有{}两个字符。其实这个是对子路由的支持。
在一个路由定义结束后,可以在后面跟一个{表示这个路由是有子路由的。从{开始直到}结束,中间所有的内容被认为是对当前路由下子路由的定义。并且子路由是可以嵌套定义的。

上一篇下一篇

猜你喜欢

热点阅读