Mojolicious路由(七)
一、命名空间namespace
我们可以使用stash关键字namespace的值来更改整个路由及其所有子路由的名称空间。
# /bye -> MyApp::MyController::Foo::Bar->bye
$r->get('/bye')->to(namespace => 'MyApp::MyController::Foo::Bar', action => 'bye');
controller总是通过Mojo::Util的”camelize”方法将蛇形命名转变为驼峰命名,然后加入到namespace中:
# /bye -> MyApp::MyController::Foo::Bar->bye
$r->get('/bye')->to('foo-bar#bye', namespace => 'MyApp::MyController');
# /hey -> MyApp::MyController::Foo::Bar->hey
$r->get('/hey')->to('Foo::Bar#hey', namespace => 'MyApp::MyController');
我们也可以在Mojolicious:: routes中使用router属性“namespaces”来更改应用程序中所有路由的默认命名空间,它通常会默认为一个基于应用程序类(MyApp::Controller)和应用程序类(MyApp)的命名空间。
$r->namespaces(['MyApp::MyController']);
二、route回调函数
stash关键字cb的值,可以保证不被嵌套路由继承,绕过controller控制器以直接执行callback回调函数:
$r->get('/bye')->to(cb => sub ($c) {
$c->render(text => 'Good bye.');
});
但就像在Mojolicious::Lite中一样,我们也可以直接传递回调函数,这样看起来更好。
$r->get('/bye' => sub ($c) {
$c->render(text => 'Good bye.');
});
三、命名路由
给我们的路由起一个名字,可以在我们的整个Mojo框架中的任何方法或helper中调用他。最常用的方法是通过Mojolicious::Controller”url_for”方法来生成url:
# /foo/marcus -> {controller => 'foo', action => 'bar', user => 'marcus'}
$r->get('/foo/:user')->to('foo#bar')->name('baz');
# Generate URL "/foo/marcus" for route "baz" (in previous request context)
my $url = $c->url_for('baz');
# Generate URL "/foo/jan" for route "baz"
my $url = $c->url_for('baz', user => 'jan');
# Generate URL "http://127.0.0.1:3000/foo/jan" for route "baz"
my $url = $c->url_for('baz', user => 'jan')->to_abs;
我们可以在Mojolicious::Routes::Route中指定一个带有”name”的名称,或者让路由器自动生成一个,它将不包含非单词字符,等于路由本身,但是自定义名称有更高的优先级。
# /foo/bar ("foobar")
$r->get('/foo/bar')->to('test#stuff');
# Generate URL "/foo/bar"
my $url = $c->url_for('foobar');
要引用当前路由,可以使用保留名称current或根本不使用名称。
# Generate URL for current route
my $url = $c->url_for('current');
my $url = $c->url_for;
要检查或获取当前路由的名称,我们可以使用Mojolicious::Plugin::DefaultHelpers中的助手“current_route”。
# Name for current route
my $name = $c->current_route;
# Check route name in code shared by multiple routes
$c->stash(button => 'green') if $c->current_route('login');