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;

标签