Mojolicious::Lite

Mojolicious::Lite  

转自【http://www.cnblogs.com/tjxwg/archive/2013/02/07/2908266.html】

Mojolicious::Lite 是由 Mojolicious 做的一个实时 web 框架。

春节几天把这个框架认真学习,整理一遍。

  • Hello World

    复制代码
    #!/usr/bin/env perl
    #任何一门语言都是先hello world…..
    #几行语句,就可以做web容器进行使用,感觉这个框架很容易使用…不过剩下来的学习不会像hello world 这么简单了。 use Mojolicious::Lite;  
    get '/' => sub { my $self = shift; $self->render(text => 'Hello World!');
    }; #命令启动千万不能少,否则会报错也没有端口启动了 app->start;
    复制代码

  • Generator

    #产生一个小型的项目,实际只是一个文件和自己写差不多 mojo generate lite_app #产生一个全目录结构的Mojolicious  mojo generate app <AppName>

    眨眼研究完lite之后,找时间认真研读一下Mojolicious

  • Commands

  • 这些标准的 Mojolicious::Commands 中会提供一些常用的命令行功能.注意 CGI 和 PSGI 的环境可以自动检查出来.可以不提供参数.

    复制代码
    $ ./myapp.pl daemon
      Server available at http://127.0.0.1:3000. $ ./myapp.pl daemon -l http://*:8080 Server available at http://127.0.0.1:8080. $ ./myapp.pl cgi ...CGI output... $ ./myapp.pl ...List of available commands (or automatically detected environment)...
    复制代码

    cgi 环境与psgi 环境目前因为psgi还没有具体理解,因此只能测试一下命令的执行情况了,

    目前担心这个启动是否稳定了,长时间。有时间压力测试一把尴尬,最好结合一个接口的访问数据库。

  • Start

  • 你可以在 app->start 的调用中加入参数,来替换掉标准的从 @ARGV 中接收参数.

    app->start('cgi');

  • Reloading

  • 如果你想你的应用在修改后能自动的 reload 的话,建议你使用 morbo 的开发用的 web 服务器,这样你就不用每次修改后重起.

    #默认3000端口 $ morbo myapp.pl
    Server available at http://127.0.0.1:3000.

    这个命令不需要每次重新启动很适合这种perl页面的修改开发了,dancer没有这个功能感觉很不爽了。Mojo这个感觉强大一些了。

    $ morbo myapp.pl-l http://*:8080
    可以指定端口太yummy了

    大笑

  • Routes

  • Routes 只是请求过来的基本的路径。可以在路径中包含不同的占位符。$self 是 Mojolicious::Controller 对象其中包含着 HTTP request 和 HTTP response。

    复制代码
     use Mojolicious::Lite; # /foo get '/foo' => sub { my $self = shift; $self->render(text => 'Hello World!');
      };
    
      app->start;
    复制代码

    Mojolicious::Controller 这个类的内容很多,包含req,res,ua等很多信息,lite之后把这部分自己看一下。要学习的东西太多呀。。悲伤

  • GET/POST parameters

  • 全部的 GET 和 POST 的参数只需要通过 “param” in Mojolicious::Controller 来访问.

    复制代码
    #/usr/bin/perl use Mojolicious::Lite; use 5.016; # /foo?user=david&pass=123 get '/foo' => sub { my $self = shift; my $user = $self->param('user'); my $pass = $self->param('pass'); $self->render(text => "Hello $user\t$pass");
    };
    app->start;
    复制代码

  • Stash and templates

  • 这个 “stash” in Mojolicious::Controller 是用来传一些数据给模板技术使用,在这我们使用的是 DATA 这个部分的模板.

    复制代码
    use Mojolicious::Lite; # /bar get '/bar' => sub { my $self = shift; $self->stash(one => 23); #存放模版变量 $self->render('baz', two => 24); #渲染到baz.html.ep  };
    
      app->start; __DATA__ @@ baz.html.ep
      The magic numbers are <%= $one %> and <%= $two %>.
    复制代码

    模板的信息可以看看 “Embedded Perl” in Mojolicious::Guides::Rendering,要看的东西好多呀。困惑

  • HTTP

  • “req” in Mojolicious::Controller 和 “res” in Mojolicious::Controller 提供了全功能的 HTTP 的支持.

    复制代码
    use Mojolicious::Lite; use 5.16.2; # /agent get '/agent' => sub { my $self = shift; $self->res->headers->header('X-Bender' => 'Bite my shiny metal ass!'); #响应的头信息添加富家子段 $self->render( text=> $self->req->headers->user_agent ); #useragnet  };
    
      app->start;
    复制代码

    可以记录客户端的request的所有信息,也可以返回response增加相应的响应信息大笑

  • Route names

  • 全部的 Routes 会关联到相关的名字,会自动的取得相关的名字的模板。另外 “url_for” in Mojolicious::Controller 和 “link_to” in Mojolicious::Plugin::TagHelpers 也能帮到你。

    复制代码
    use Mojolicious::Lite; # / get '/' => sub { my $self = shift; $self->render;
      } => 'index'; # /hello get '/hello';
    
      app->start; __DATA__ @@ index.html.ep <%= link_to Hello  => 'hello' %>.  <!-- <a href="hello">Hello</a> -->
      <%= link_to Reload => 'index' %>.<!-- <a href="">Reload</a> --> @@ hello.html.ep
      Hello World!
    复制代码

    link_to 等同于href 的功能,具体使用如果要开发页面查看相应的文档帮助了。

  • Layouts

  • 模板是可以分层的,你只需要选择 helper 中的 “layout” in Mojolicious::Plugin::DefaultHelpers。给当前结果放到模板中通过 “content” in Mojolicious::Plugin::DefaultHelpers.

    复制代码
     use Mojolicious::Lite;  #模版文件比较复杂可以放到templates目录中
      # /with_layout get '/with_layout' => sub { my $self = shift; $self->render('with_layout'); #也可以放到}=>'with_layout' 这样指定效果一样  };
    
      app->start; __DATA__ @@ with_layout.html.ep % title 'Green'; % layout 'green';
      Hello World! @@ layouts/green.html.ep <!DOCTYPE html>
      <html>
        <head><title><%= title %></title></head>
        <body><%= content %></body>
      </html>
    复制代码

  • Blocks

  • 模板可以使用标准的 Perl 的功能,只需要使用 begin 和 end 的关键字分隔.

    复制代码
     use Mojolicious::Lite; # /with_block get '/with_block' => 'block';
    
      app->start; __DATA__ @@ block.html.ep % my $link = begin % my ($url, $name) = @_;
        Try <%= link_to $url => begin %><%= $name %><% end %>.
      % end <!DOCTYPE html>
      <html>
        <head><title>Sebastians frameworks</title></head>
        <body>
          %= $link->('http://mojolicio.us', 'Mojolicious') %= $link->('http://catalystframework.org', 'Catalyst') </body>
      </html>
    复制代码

    具体如果写页面,再去仔细研究模版里面的功能,看起来有些繁琐。

  • Captured content

  • 在 helper 中可以使用 “content_for” in Mojolicious::Plugin::DefaultHelpers 来抓到包在一个块中的内容.

    复制代码
     use Mojolicious::Lite; # /captured get '/captured' => sub { my $self = shift; $self->render('captured');
      };
    
      app->start; __DATA__ @@ captured.html.ep % layout 'blue', title => 'Green'; % content_for header => begin <meta http-equiv="Pragma" content="no-cache">
      % end
      Hello World!
      % content_for header => begin <meta http-equiv="Expires" content="-1">
      % end
    
    @@ layouts/blue.html.ep <!DOCTYPE html>
      <html>
        <head>
          <title><%= title %></title>
          %= content_for 'header' </head>
        <body><%= content %></body>
      </html>
    复制代码

  • Helpers

  • 你可以扩展内置的 Mojolicious 的这个 helpers, 全部内置的所有的原生的可以在 Mojolicious::Plugin::DefaultHelpers 和 Mojolicious::Plugin::TagHelpers 中来查看.

    复制代码
     use Mojolicious::Lite; # 可以将一些常用的如数据库的操作,用扩展helper的功能来实现比较精妙
      # "whois" helper helper whois => sub { my $self = shift; my $agent = $self->req->headers->user_agent || 'Anonymous'; my $ip = $self->tx->remote_address; return "$agent ($ip)";
      }; # /secret get '/secret' => sub { my $self = shift; my $user = $self->whois; $self->app->log->debug("Request from $user.");
      };
    
      app->start; __DATA__ @@ secret.html.ep
      We know who you are <%= whois %>.
    复制代码

  • 占位符

  • 路径选择的占位符可以让你取得一些请求中的路径。结果会可以通过 “stash” in Mojolicious::Controller 和 “param” in Mojolicious::Controller 来访问.

    复制代码
     use Mojolicious::Lite; # /foo/test
      # /foo/test123 get '/foo/:bar' => sub { my $self = shift; my $bar = $self->stash('bar'); #stash方式 $self->render(text => "Our :bar placeholder matched $bar");
      }; # /testsomething/foo
      # /test123something/foo get '/(:bar)something/foo' => sub { my $self = shift; my $bar = $self->param('bar'); #param方式 $self->render(text => "Our :bar placeholder matched $bar");
      };
    
      app->start;
    复制代码

  • 松懈占位符

  • 松懈占位可以让你匹配直接到 /

    复制代码
     use Mojolicious::Lite; # /test/hello
      # /test123/hello
      # /test.123/hello get '/#you/hello' => 'groovy';
    
      app->start; __DATA__ @@ groovy.html.ep
      Your name is <%= $you %>.
    复制代码

  • 通配位符

  • 配位符可以匹配到任何东西,包括 / 和 ..

    复制代码
     use Mojolicious::Lite; # /hello/test
      # /hello/test123
      # /hello/test.123/test/123 get '/hello/*you' => 'groovy';
    
      app->start; __DATA__ @@ groovy.html.ep
      Your name is <%= $you %>.
    复制代码

  • HTTP methods

  • 路径选择的方法可以指定 HTTP 的方法

    复制代码
     use Mojolicious::Lite; # GET /hello get '/hello' => sub { my $self = shift; $self->render(text => 'Hello World!');
      }; # PUT /hello put '/hello' => sub { my $self = shift; my $size = length $self->req->body; $self->render(text => "You uploaded $size bytes to /hello.");
      }; # GET|POST|PATCH /bye any [qw(GET POST PATCH)] => '/bye' => sub { my $self = shift; $self->render(text => 'Bye World!');
      }; # * /whatever any '/whatever' => sub { my $self = shift; my $method = $self->req->method; $self->render(text => "You called /whatever with $method.");
      };
    
      app->start;
    复制代码

  • 选的占位符

  • 可选的占位符.

    复制代码
     use Mojolicious::Lite; # /hello
      # /hello/Sara get '/hello/:name' => {name => 'Sebastian'} => sub { my $self = shift; $self->render('groovy', format => 'txt');
      };
    
      app->start; __DATA__ @@ groovy.txt.ep My name is <%= $name %>.
    复制代码

  • 限制性占位符

  • 有个最简单的方法,让你的占位符有严格的范围,您只需写出可能值的列表。

    复制代码
     use Mojolicious::Lite; # /test
      # /123 any '/:foo' => [foo => [qw(test 123)]] => sub { my $self = shift; my $foo = $self->param('foo'); $self->render(text => "Our :foo placeholder matched $foo");
      };
    
      app->start;
    复制代码

    所有的占位符被编译到成正则表达式,所以在这也可以很容易地定制你的这个。

    复制代码
     use Mojolicious::Lite; # /1
      # /123 any '/:bar' => [bar => qr/\d+/] => sub { my $self = shift; my $bar = $self->param('bar'); $self->render(text => "Our :bar placeholder matched $bar");
      };
    
      app->start;
    复制代码

    只要确保不使用 ^ 和 $ 还有捕获组 (…), 因为这些占位符会和内置的组成一个更大的正则表达式.

  • Under


  • 认证并共享代码在多个路径之间很容易实现,只需要桥接生成的路由并使用 under 的声明。判断是认证还是路径显示只需要看看返回是否为 true 就知道了

    复制代码
     use Mojolicious::Lite; # Authenticate based on name parameter under sub { my $self = shift; # Authenticated my $name = $self->param('name') || ''; return 1 if $name eq 'Bender'; # Not authenticated $self->render('denied'); return undef;
      }; # / (with authentication) get '/' => 'index';
    
      app->start; __DATA__;
    
      @@ denied.html.ep
      You are not Bender, permission denied. @@ index.html.ep
      Hi Bender.
    复制代码

    要实现前缀的多个路径选择,也是一个使用的 under 的好理由。

    复制代码
     use Mojolicious::Lite; # /foo under '/foo'; # /foo/bar get '/bar' => {text => 'foo bar'}; # /foo/baz get '/baz' => {text => 'foo baz'}; # / under '/' => {message => 'whatever'}; # /bar get