Mojolicious路由(十六)
一、条件插件——condition plugins
我们还可以将条件打包为可重用的插件。
# Plugin
package Mojolicious::Plugin::WerewolfCondition;
use Mojo::Base 'Mojolicious::Plugin', -signatures;
use Astro::MoonPhase;
sub register ($self, $app, $conf) {
# Add "werewolf" condition
$app->routes->add_condition(werewolf => sub ($route, $c, $captures, $days) {
# Keep the werewolves out!
return undef if abs(14 - (phase(time))[2]) > ($days / 2);
# It's ok, no werewolf
return 1;
});
}
1;
现在只需加载插件,就可以在所有应用程序中使用该条件了。
# Application
package MyApp;
use Mojo::Base 'Mojolicious', -signatures;
sub startup ($self) {
# Plugin
$self->plugin('WerewolfCondition');
# /hideout (keep them out for 4 days after full moon)
$self->routes->get('/hideout')->requires(werewolf => 4)->to(controller => 'foo', action => 'bar');
}
1;
二、Mount applications
将一个应用程序嵌入到另一个应用程序中最简单的方法是Mojolicious::Plugin::Mount,它允许我们在域and/or前缀下挂载整个自包含的应用程序。
use Mojolicious::Lite -signatures;
# Whole application mounted under "/prefix"
plugin Mount => {'/prefix' => '/home/sri/myapp/script/myapp'};
# Mount application with subdomain
plugin Mount => {'test.example.com' => '/home/sri/myapp2.pl'};
# Normal route
get '/' => sub ($c) {
$c->render(text => 'Hello World!');
};
app->start;
三、嵌入式应用
为了获得更强大的功能,我们还可以通过使用应用程序而不是控制器来嵌入应用程序。例如,这允许在正常的Mojolicious控制器中使用Mojolicious::Lite域特定语言。
# Controller
package MyApp::Controller::Bar;
use Mojolicious::Lite -signatures;
# /hello
get '/hello' => sub ($c) {
my $name = $c->param('name');
$c->render(text => "Hello $name.");
};
1;
通过Mojolicious::Routes::Route中的属性“partial”,我们可以允许路由部分匹配,并在嵌入式应用程序中只使用剩余的路径,基路径将在path stash值中传递。
# /foo/*
$r->any('/foo')->partial(1)->to('bar#', name => 'Mojo');
一个最小的可嵌入应用程序只不过是Mojolicious的一个子类,它包含一个接受Mojolicious::Controller对象的处理程序方法。
package MyApp::Controller::Bar;
use Mojo::Base 'Mojolicious', -signatures;
sub handler ($self, $c) {
$c->res->code(200);
my $name = $c->param('name');
$c->res->body("Hello $name.");
}
1;
宿主应用程序仅通过stash与嵌入式应用程序共享很少的信息。因此,目前不能在通往嵌入式应用程序的路由中使用路由占位符,因为这会导致Mojolicious::Controller中的”url_for”出现问题。
四、应用程序插件
我们甚至可以将应用程序打包为自包含的可重用插件。
# Plugin
package Mojolicious::Plugin::MyEmbeddedApp;
use Mojo::Base 'Mojolicious::Plugin', -signatures;
sub register ($self, $app, $conf) {
# Automatically add route
$app->routes->any('/foo')->partial(1)->to(app => EmbeddedApp::app());
}
package EmbeddedApp;
use Mojolicious::Lite;
get '/bar' => 'bar';
1;
__DATA__
@@ bar.html.ep
Hello World!
app stash的值不会被嵌套路由继承,可以用于已经实例化的应用程序。现在只要加载插件就完成了。
# Application
package MyApp;
use Mojo::Base 'Mojolicious', -signatures;
sub startup ($self) {
# Plugin
$self->plugin('MyEmbeddedApp');
}
1;