SlideShare una empresa de Scribd logo
1 de 256
Descargar para leer sin conexión
Mojolicious.
Веб в коробке!

Анатолий Шарифулин
Sebastian Riedel
 автор Catalyst и Mojolicious
    http://twitter.com/kraih
Что такое
Mojolicious?
Что такое Mojolicious?
• Pure Perl веб-фреймворк
• Без зависимостей (с версии Perl 5.8.1)
• Объектно-ориентированное API (без скрытой магии)
• Поддержка HTTP 1.1, WebSocket, IPv6, SSL, IDNA
• Поддержка CGI, FastCGI, PSGI, Daemon и Prefork
• Веб-фреймворки: Mojo, Mojolicious и Mojolicious::Lite
«Fresh code,
based upon years of
expirience developing
       Catalyst»
Pure Perl
веб-фреймворк
• Mojo::Base
• Mojo::ByteStream
• Mojo::Template, Mojo::JSON
• Mojo::Loader, Mojo::Log, Mojo::Path
• Mojo::URL, Mojo::Parameters, Mojo::Content
• Mojo::Message::Request,
  Mojo::Message::Response,
  Mojo::Headers, Mojo::Cookie, Mojo::Date
• Mojo::Base
• Mojo::ByteStream
• Mojo::Template, Mojo::JSON
• Mojo::Loader, Mojo::Log, Mojo::Path
• Mojo::URL, Mojo::Parameters, Mojo::Content
• Mojo::Message::Request,
  Mojo::Message::Response,
  Mojo::Headers, Mojo::Cookie, Mojo::Date
Mojo::Base
Minimal Base Class For Mojo Projects
package App;
use base ‘Mojo::Base’;

__PACKAGE__->attr(conf => sub {
	

 return do ‘conf/app.conf’;
});
__PACKAGE__->attr(db => sub {
	

 my $self = shift;
	

 return Util->db($self->conf->{'db'});
});

sub dispatch { ... }
package App;
use base ‘Mojo::Base’;

__PACKAGE__->attr(conf => sub {
	

 return do ‘conf/app.conf’;
});
__PACKAGE__->attr(db => sub {
	

 my $self = shift;
	

 return Util->db($self->conf->{'db'});
});

sub dispatch { ... }
package App;
use base ‘Mojo::Base’;

__PACKAGE__->attr(conf => sub {
	

 return do ‘conf/app.conf’;
});
__PACKAGE__->attr(db => sub {
	

 my $self = shift;
	

 return Util->db($self->conf->{'db'});
});

sub dispatch { ... }
• Mojo::Base
• Mojo::ByteStream
• Mojo::Template, Mojo::JSON
• Mojo::Loader, Mojo::Log, Mojo::Path
• Mojo::URL, Mojo::Parameters, Mojo::Content
• Mojo::Message::Request,
  Mojo::Message::Response,
  Mojo::Headers, Mojo::Cookie, Mojo::Date
Mojo::ByteStream
     ByteStream
use Mojo::ByteStream;
my $s = Mojo::ByteStream->new('foo_bar');

$s->camelize; $s->decamelize;
$s->b64_encode; $s->b64_decode;
$s->encode('utf8'); $s->decode('utf8');
$s->html_escape; $s->html_unescape;
$s->qp_encode; $s->qp_decode;
$s->quote; $stream->unquote;
$s->url_escape; $s->url_unescape;
$s->xml_escape;
$s->punycode_encode; $s->punycode_decode;
use Mojo::ByteStream 'b';
my $s = b('foo_bar');

$s->camelize; $s->decamelize;
$s->b64_encode; $s->b64_decode;
$s->encode('utf8'); $s->decode('utf8');
$s->html_escape; $s->html_unescape;
$s->qp_encode; $s->qp_decode;
$s->quote; $stream->unquote;
$s->url_escape; $s->url_unescape;
$s->xml_escape;
$s->punycode_encode; $s->punycode_decode;
use Mojo::ByteStream;
my $s = Mojo::ByteStream->new('foo_bar');

$s->camelize; $s->decamelize;
$s->b64_encode; $s->b64_decode;
$s->encode('utf8'); $s->decode('utf8');
$s->html_escape; $s->html_unescape;
$s->qp_encode; $s->qp_decode;
$s->quote; $stream->unquote;
$s->url_escape; $s->url_unescape;
$s->xml_escape;
$s->punycode_encode; $s->punycode_decode;
use Mojo::ByteStream;
my $s = Mojo::ByteStream->new('foo_bar');

$s->camelize; $s->decamelize;
$s->b64_encode; $s->b64_decode;
$s->encode('utf8'); $s->decode('utf8');
$s->html_escape; $s->html_unescape;
$s->qp_encode; $s->qp_decode;
$s->quote; $stream->unquote;
$s->url_escape; $s->url_unescape;
$s->xml_escape;
$s->punycode_encode; $s->punycode_decode;
use Mojo::ByteStream;
my $s = Mojo::ByteStream->new('foo_bar');

$s->camelize; $s->decamelize;
$s->b64_encode; $s->b64_decode;
$s->encode('utf8'); $s->decode('utf8');
$s->html_escape; $s->html_unescape;
$s->qp_encode; $s->qp_decode;
$s->quote; $stream->unquote;
$s->url_escape; $s->url_unescape;
$s->xml_escape;
$s->punycode_encode; $s->punycode_decode;
use Mojo::ByteStream;
my $s = Mojo::ByteStream->new('foo_bar');

$s->camelize; $s->decamelize;
$s->b64_encode; $s->b64_decode;
$s->encode('utf8'); $s->decode('utf8');
$s->html_escape; $s->html_unescape;
$s->qp_encode; $s->qp_decode;
$s->quote; $stream->unquote;
$s->url_escape; $s->url_unescape;
$s->xml_escape;
$s->punycode_encode; $s->punycode_decode;
use Mojo::ByteStream;
my $s = Mojo::ByteStream->new('foo_bar');

$s->camelize; $s->decamelize;
$s->b64_encode; $s->b64_decode;
$s->encode('utf8'); $s->decode('utf8');
$s->html_escape; $s->html_unescape;
$s->qp_encode; $s->qp_decode;
$s->quote; $stream->unquote;
$s->url_escape; $s->url_unescape;
$s->xml_escape;
$s->punycode_encode; $s->punycode_decode;
use Mojo::ByteStream;
my $s = Mojo::ByteStream->new('foo_bar');

$s->camelize; $s->decamelize;
$s->b64_encode; $s->b64_decode;
$s->encode('utf8'); $s->decode('utf8');
$s->html_escape; $s->html_unescape;
$s->qp_encode; $s->qp_decode;
$s->quote; $stream->unquote;
$s->url_escape; $s->url_unescape;
$s->xml_escape;
$s->punycode_encode; $s->punycode_decode;
use Mojo::ByteStream;
my $s = Mojo::ByteStream->new('foo_bar');

$s->camelize; $s->decamelize;
$s->b64_encode; $s->b64_decode;
$s->encode('utf8'); $s->decode('utf8');
$s->html_escape; $s->html_unescape;
$s->qp_encode; $s->qp_decode;
$s->quote; $stream->unquote;
$s->url_escape; $s->url_unescape;
$s->xml_escape;
$s->punycode_encode; $s->punycode_decode;
use Mojo::ByteStream;
my $s = Mojo::ByteStream->new('foo_bar');

$s->camelize; $s->decamelize;
$s->b64_encode; $s->b64_decode;
$s->encode('utf8'); $s->decode('utf8');
$s->html_escape; $s->html_unescape;
$s->qp_encode; $s->qp_decode;
$s->quote; $stream->unquote;
$s->url_escape; $s->url_unescape;
$s->xml_escape;
$s->punycode_encode; $s->punycode_decode;
use Mojo::ByteStream;
my $s = Mojo::ByteStream->new('foo_bar');

$s->camelize; $s->decamelize;
$s->b64_encode; $s->b64_decode;
$s->encode('utf8'); $s->decode('utf8');
$s->html_escape; $s->html_unescape;
$s->qp_encode; $s->qp_decode;
$s->quote; $stream->unquote;
$s->url_escape; $s->url_unescape;
$s->xml_escape;
$s->punycode_encode; $s->punycode_decode;
• Mojo::Base
• Mojo::ByteStream
• Mojo::Template, Mojo::JSON
• Mojo::Loader, Mojo::Log, Mojo::Path
• Mojo::URL, Mojo::Parameters, Mojo::Content
• Mojo::Message::Request,
  Mojo::Message::Response,
  Mojo::Headers, Mojo::Cookie, Mojo::Date
Mojo::Template
   Perlish Templates!
% my $list = $self->stash(‘list’);

<ul>
% for (@$list) {
	

 <li>
	

 	

 <%= $_->{title} %>
	

 </li>
%}
</ul>

<p><%# comment %></p>
% my $list = $self->stash(‘list’);

<ul>
% for (@$list) {
	

 <li>
	

 	

 <%= $_->{title} %>
	

 </li>
%}
</ul>

<p><%# comment %></p>
% my $list = $self->stash(‘list’);

<ul>
% for (@$list) {
	

 <li>
	

 	

 <%= $_->{title} %>
	

 </li>
%}
</ul>

<p><%# comment %></p>
% my $count = 10 * 5;

<ul>
% for (@$list) {
	

 <li>
	

 	

 <%= $_->{title} %>
	

 </li>
%}
</ul>

<p><%# comment %></p>
% use Foo::Bar;

<ul>
% for (@$list) {
	

 <li>
	

 	

 <%= $_->{title} %>
	

 </li>
%}
</ul>

<p><%# comment %></p>
% my $list = $self->stash(‘list’);

<ul>
% for (@$list) {
	

 <li>
	

 	

 <%= $_->{title} %>
	

 </li>
%}
</ul>

<p><%# comment %></p>
% my $list = $self->stash(‘list’);

<ul>
% if (@$list) {
	

 <li>
	

 	

 <%= $_->{title} %>
	

 </li>
%}
</ul>

<p><%# comment %></p>
% my $list = $self->stash(‘list’);

<ul>
% for (@$list) {
	

 <li>
	

 	

 <%= $_->{title} %>
	

 </li>
%}
</ul>

<p><%# comment %></p>
% my $list = $self->stash(‘list’);

<ul>
% for (@$list) {
	

 <li>
	

 	

 <%= $_->{title} %>
	

 </li>
%}
</ul>

<p><%# comment %></p>
% my $list = $self->stash(‘list’);

<ul>
% for (@$list) {
	

 <li>
	

 	

 <%== $_->{title} %>
	

 </li>
%}
</ul>

<p><%# comment %></p>
% my $list = $self->stash(‘list’);

<ul>
% for (@$list) {
	

 <li>
	

 	

 <%= ucfirst $_->{title} %>
	

 </li>
%}
</ul>

<p><%# comment %></p>
% my $list = $self->stash(‘list’);

<ul>
% for (@$list) {
	

 <li>
	

 	

 <%= $_->{title} %>
	

 </li>
%}
</ul>

<p><%# comment %></p>
% my $list = $self->stash(‘list’);

<ul>
% for (@$list) {
	

 <li>
	

 	

 <%= $_->{title} %>
	

 </li>
%}
</ul>

<p><%# comment %></p>
1   % my $list = $self->stash(‘list’);
 2
 3   <ul>
 4   % for (@$list) {
 5   	

 <li>
 6   	

 	

 <%= $_->{title} xx %>
 7   	

 </li>
 8   %}
 9   </ul>
10
11   <p><%# comment %></p>
Сообщение об ошибке
  Bareword "xx" not allowed while "strict
      subs" in use at template line 6.
Простота PHP,
 мощь Perl
• Mojo::Base
• Mojo::ByteStream
• Mojo::Template, Mojo::JSON
• Mojo::Loader, Mojo::Log, Mojo::Path
• Mojo::URL, Mojo::Parameters, Mojo::Content
• Mojo::Message::Request,
  Mojo::Message::Response,
  Mojo::Headers, Mojo::Cookie, Mojo::Date
Mojo::JSON
 Minimalistic JSON
my $json = Mojo::JSON->new;

my $string = $json->encode({foo => ‘bar’});

my $hash = $json->decode(‘{"foo":"bar"}’);
my $json = Mojo::JSON->new;

my $string = $json->encode({foo => ‘bar’});

my $hash = $json->decode(‘{"foo":"bar"}’);
• Mojo::Base
• Mojo::ByteStream
• Mojo::Template, Mojo::JSON
• Mojo::Loader, Mojo::Log, Mojo::Path
• Mojo::URL, Mojo::Parameters, Mojo::Content
• Mojo::Message::Request,
  Mojo::Message::Response,
  Mojo::Headers, Mojo::Cookie, Mojo::Date
Mojo::Loader
Class loader: load, reload, search
• Mojo::Base
• Mojo::ByteStream
• Mojo::Template, Mojo::JSON
• Mojo::Loader, Mojo::Log, Mojo::Path
• Mojo::URL, Mojo::Parameters, Mojo::Content
• Mojo::Message::Request,
  Mojo::Message::Response,
  Mojo::Headers, Mojo::Cookie, Mojo::Date
• Mojo::Base
• Mojo::ByteStream
• Mojo::Template, Mojo::JSON
• Mojo::Loader, Mojo::Log, Mojo::Path
• Mojo::URL, Mojo::Parameters, Mojo::Content
• Mojo::Message::Request,
  Mojo::Message::Response,
  Mojo::Headers, Mojo::Cookie, Mojo::Date
• Mojo::Base
• Mojo::ByteStream
• Mojo::Template, Mojo::JSON
• Mojo::Loader, Mojo::Log, Mojo::Path
• Mojo::URL, Mojo::Parameters, Mojo::Content
• Mojo::Message::Request,
  Mojo::Message::Response,
  Mojo::Headers, Mojo::Cookie, Mojo::Date
•   Mojo::Trasaction

•   Mojo::IOLoop

•   Mojo::Client, Mojo::Server

    •   Mojo::Server::CGI, Mojo::Server::FastCGI

    •   Mojo::Server::PSGI

    •   Mojo::Server::Daemon и ::Prefork

•   Mojo::Command

    •   Mojo::Command::Generate и ~ Server
•   Mojo::Trasaction

•   Mojo::IOLoop

•   Mojo::Client, Mojo::Server

    •   Mojo::Server::CGI, Mojo::Server::FastCGI

    •   Mojo::Server::PSGI

    •   Mojo::Server::Daemon и ::Prefork

•   Mojo::Command

    •   Mojo::Command::Generate и ~ Server
•   Mojo::Trasaction

•   Mojo::IOLoop

•   Mojo::Client, Mojo::Server

    •   Mojo::Server::CGI, Mojo::Server::FastCGI

    •   Mojo::Server::PSGI

    •   Mojo::Server::Daemon и ::Prefork

•   Mojo::Command

    •   Mojo::Command::Generate и ~ Server
Mojo::IOLoop
Minimalistic Reactor For TCP Clients And Servers
Mojo::IOLoop
Поддержка IO::KQueue, IO::Epoll,
IO::Socket::INET6 и IO::Socket::SSL
my $loop = Mojo::IOLoop->new;
$loop->listen(port => 3000, cb => sub {
   my ($self, $id) = @_;

     $self->read_cb ($id => sub { ... });

     $self->write_cb($id => sub { ... });
);
my $id = $loop->connect(port => 3000, ...);
$loop->start; $loop->stop;
my $loop = Mojo::IOLoop->new;
$loop->listen(port => 3000, cb => sub {
   my ($self, $id) = @_;

     $self->read_cb ($id => sub { ... });

     $self->write_cb($id => sub { ... });
);
my $id = $loop->connect(port => 3000, ...);
$loop->start; $loop->stop;
my $loop = Mojo::IOLoop->new;
$loop->listen(port => 3000, cb => sub {
   my ($self, $id) = @_;

     $self->read_cb ($id => sub { ... });

     $self->write_cb($id => sub { ... });
);
my $id = $loop->connect(port => 3000, ...);
$loop->start; $loop->stop;
my $loop = Mojo::IOLoop->new;
$loop->listen(port => 3000, cb => sub {
   my ($self, $id) = @_;

     $self->read_cb ($id => sub { ... });

     $self->write_cb($id => sub { ... });
);
my $id = $loop->connect(port => 3000, ...);
$loop->start; $loop->stop;
•   Mojo::Trasaction

•   Mojo::IOLoop

•   Mojo::Client, Mojo::Server

    •   Mojo::Server::CGI, Mojo::Server::FastCGI

    •   Mojo::Server::PSGI

    •   Mojo::Server::Daemon и ::Prefork

•   Mojo::Command

    •   Mojo::Command::Generate и ~ Server
Mojo::Client
Async IO HTTP 1.1 And WebSocket Client
my $client = Mojo::Client->new;

$client->get(
	

 ‘http://goo.gl’ => sub {
	

 	

 my ($self, $tx) = @_;
	

 	

 say $tx->res;
	

 }
)->process;
my $client = Mojo::Client->new;

$self->client->get(
	

 ‘http://goo.gl’ => sub {
	

 	

 my ($self, $tx) = @_;
	

 	

 say $tx->res;
	

 }
)->process;
my $client = Mojo::Client->new;

$client->get(
	

 ‘http://goo.gl’ => sub {
	

 	

 my ($self, $tx) = @_;
	

 	

 say $tx->res;
	

 }
)->process;
my $client = Mojo::Client->new;

$client->head(
	

 ‘http://goo.gl’ => sub {
	

 	

 my ($self, $tx) = @_;
	

 	

 say $tx->res;
	

 }
)->process;
my $client = Mojo::Client->new;

$client->post(
	

 ‘http://goo.gl’ => sub {
	

 	

 my ($self, $tx) = @_;
	

 	

 say $tx->res;
	

 }
)->process;
my $client = Mojo::Client->new;

$client->put(
	

 ‘http://goo.gl’ => sub {
	

 	

 my ($self, $tx) = @_;
	

 	

 say $tx->res;
	

 }
)->process;
my $client = Mojo::Client->new;

$client->async->get(
	

 ‘http://goo.gl’ => sub {
	

 	

 my ($self, $tx) = @_;
	

 	

 say $tx->res;
	

 }
)->process;
my $client = Mojo::Client->new;

$client->get(
	

 ‘http://goo.gl’ => sub {
	

 	

 my ($self, $tx) = @_;
	

 	

 say $tx->res;
	

 }
)->process;
my $client = Mojo::Client->new;

$client->get(
	

 ‘http://goo.gl’ => sub {
	

 	

 my ($self, $tx) = @_;
	

 	

 say $tx->res;
	

 }
)->process;
my $client = Mojo::Client->new;

$client->get(
	

 ‘http://goo.gl’ => sub {
	

 	

 my ($self, $tx) = @_;
	

 	

 say $tx->res;
	

 }
)->process;
my $client = Mojo::Client->new;

$client->get(‘http://goo.gl’)->res->code;

$client->get(
  'http://search.twitter.com/trends.json'
)->success->json->{trends}->[0]->{name}
my $client = Mojo::Client->new;

$client->get(‘http://goo.gl’)->res->code;

$client->get(
  'http://search.twitter.com/trends.json'
)->success->json->{trends}->[0]->{name}
script/mojolicious
 get 'http://goo.gl'
•   Mojo::Trasaction

•   Mojo::IOLoop

•   Mojo::Client, Mojo::Server

    •   Mojo::Server::CGI, Mojo::Server::FastCGI

    •   Mojo::Server::PSGI

    •   Mojo::Server::Daemon и ::Prefork

•   Mojo::Command

    •   Mojo::Command::Generate и ~ Server
•   Mojo::Trasaction

•   Mojo::IOLoop

•   Mojo::Client, Mojo::Server

    •   Mojo::Server::CGI, Mojo::Server::FastCGI

    •   Mojo::Server::PSGI

    •   Mojo::Server::Daemon и ::Prefork

•   Mojo::Command

    •   Mojo::Command::Generate и ~ Server
•   Mojo::Trasaction

•   Mojo::IOLoop

•   Mojo::Client, Mojo::Server

    •   Mojo::Server::CGI, Mojo::Server::FastCGI

    •   Mojo::Server::PSGI

    •   Mojo::Server::Daemon и ::Prefork

•   Mojo::Command

    •   Mojo::Command::Generate и ~ Server
Всё, что нужно – есть
    Mojolicious – веб в коробке!
Без зависимостей
    с версии Perl 5.8.1
Mojo runtime
Perl 5.005
Perl 5.006002
Perl 5.008001
Perl 5.010
Объектно-
ориентированное
      API
package App;
use base 'Mojo';
sub handler {
    my ($self, $tx) = @_;
	

	

 warn $tx->req; warn $tx->req->url;
	

    $tx->res->headers
             ->content_type('text/plain');
    $tx->res->body('РИТ++ 2010');
}
1;
package App;
use base 'Mojo';
sub handler {
    my ($self, $tx) = @_;
	

	

 warn $tx->req; warn $tx->req->url;
	

    $tx->res->headers
             ->content_type('text/plain');
    $tx->res->body('РИТ++ 2010');
}
1;
package App;
use base 'Mojo';
sub handler {
    my ($self, $tx) = @_;
	

	

 warn $tx->req; warn $tx->req->url;
	

    $tx->res->headers
             ->content_type('text/plain');
    $tx->res->body('РИТ++ 2010');
}
1;
package App;
use base 'Mojo';
sub handler {
    my ($self, $tx) = @_;
	

	

 warn $tx->req; warn $tx->req->url;
	

    $tx->res->headers
             ->content_type('text/plain');
    $tx->res->body('РИТ++ 2010');
}
1;
package App;
use base 'Mojo';
sub handler {
    my ($self, $tx) = @_;
	

	

 warn $tx->req; warn $tx->req->url;
	

    $tx->res->headers
             ->content_type('text/plain');
    $tx->res->body('РИТ++ 2010');
}
1;
package App;
use base 'Mojo';
sub handler {
    my ($self, $tx) = @_;
	

	

 warn $tx->req; warn $tx->req->url;
	

    $tx->res->headers
             ->content_type('text/plain');
    $tx->res->body('РИТ++ 2010');
}
1;
use overload '""' => sub
  { shift->to_string },
     fallback => 1;
GET / HTTP/1.1
Connection: keep-alive
Accept: text/html, application/xhtml, ....
Accept-Charset: windows-1251, utf-8; ...
Accept-Encoding: gzip,deflate
Accept-Language: ru,en-us;q=0.7,en;q=0.3
Host: localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; ...
Content-Length: 0
Keep-Alive: 300
Поддержка HTTP 1.1
      клиент-сервер
Google Summer of Code 2009
          Pascal Gaudette
         MojoX::UserAgent
Поддержка WebSocket
      клиент-сервер
Протокол WebSocket
         Google, Inc
    16 декабря 2009 года
use Mojolicious::Lite;

websocket ‘/echo’ => sub {
	

 my $self = shift;
	

 $self->receive_message(sub {
	

 	

 my ($self, $msg) = @_;
	

 	

 $self->send_massage("echo: $msg");
	

 });
};

app->start;
use Mojolicious::Lite;

websocket ‘/echo’ => sub {
	

 my $self = shift;
	

 $self->receive_message(sub {
	

 	

 my ($self, $msg) = @_;
	

 	

 $self->send_massage("echo: $msg");
	

 });
};

app->start;
Mojolicious WebSocket Examples
       Интересный пример IRC-клиент
            Github.com @xantus
Google Summer of Code 2010
             Performance tuning
     the http/websocket implementation
Поддержка CGI,
 FastCGI, PSGI,
Daemon и Prefork
script/mojolicious
COMMAND [OPTIONS]
script/mojolicious cgi
script/mojolicious fastcgi
script/mojolicious psgi
script/mojolicious daemon
script/mojolicious daemon_prefork
script/mojolicious
COMMAND [OPTIONS]
script/mojolicious cgi
script/mojolicious fastcgi
script/mojolicious psgi
script/mojolicious daemon
script/mojolicious daemon_prefork
PATH_INFO='/foo/bar'
   script/mojolicious cgi
             Легко тестировать
Можно профилировать код, используя Devel::NYTProf
script/mojolicious
COMMAND [OPTIONS]
script/mojolicious cgi
script/mojolicious fastcgi
script/mojolicious psgi
script/mojolicious daemon
script/mojolicious daemon_prefork
Mojo::Server::FCGI
script/mojolicious fcgi
script/mojolicious fcgi_prefork
script/mojolicious
COMMAND [OPTIONS]
script/mojolicious cgi
script/mojolicious fastcgi
script/mojolicious psgi
script/mojolicious daemon
script/mojolicious daemon_prefork
script/mojolicious
COMMAND [OPTIONS]
script/mojolicious cgi
script/mojolicious fastcgi
script/mojolicious psgi
script/mojolicious daemon
script/mojolicious daemon_prefork
script/mojolicious
      daemon --reload
Приложение перезагружается перед запросом,
          если код был изменен
Обработка сигнала USR1
   Для обновления кода приложения
script/mojolicious
COMMAND [OPTIONS]
script/mojolicious cgi
script/mojolicious fastcgi
script/mojolicious psgi
script/mojolicious daemon
script/mojolicious daemon_prefork
Веб-фреймворки
Mojo
Base framework
package App;
use base 'Mojo';
sub handler {
    my ($self, $tx) = @_;
	

	

 warn $tx->req; warn $tx->req->url;
	

    $tx->res->headers
             ->content_type('text/plain');
    $tx->res->body('РИТ++ 2010');
}
1;
package App;
use base 'Mojo';
sub handler {
    my ($self, $tx) = @_;
	

	

 warn $tx->req; warn $tx->req->url;
	

    $tx->res->headers
             ->content_type('text/plain');
    $tx->res->body('РИТ++ 2010');
}
1;
Генерация
mojo-приложения
script/mojo generate
       app App
[write ] app/script/app
[chmod] app/script/app 744
[write ] app/lib/App.pm
[write ] app/t/basic.t
[mkdir ] app/log
script/app COMMAND
      [OPTIONS]
    script/app cgi
    script/app fastcgi
    script/app psgi
    script/app daemon
    script/app daemon_prefork
script/app COMMAND
      [OPTIONS]
    script/app get
    script/app test
MVC веб-фреймворки
Mojolicious
 use base 'Mojo';
•   Mojolicous::Controller

•   Mojolicious::Plugins

•   Mojolicious::Commands

•   MojoX::Types

•   MojoX::Session

•   MojoX::Dispatcher, MojoX::Routes
•   Mojolicous::Controller

•   Mojolicious::Plugins

•   Mojolicious::Commands

•   MojoX::Types

•   MojoX::Session

•   MojoX::Dispatcher, MojoX::Routes
Mojolicious::Controller
      Controller Base Class
•   render

•   render_text

•   render_data

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render(controller => 'foo', action => 'bar')

•   render_text

•   render_data

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render(template => 'foo/bar')

•   render_text

•   render_data

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render('foo#bar')

•   render_text

•   render_data

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render('foo#bar', format => 'html')

•   render_text

•   render_data

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render

•   render_text

•   render_data

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render

•   render_text('РИТ++ 2010')

•   render_data

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render

•   render(text => 'РИТ++ 2010')

•   render_data

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render

•   render_text

•   render_data

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render

•   render_text

•   render_data('binary data')

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render

•   render_text

•   render(data => 'binary data')

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render

•   render_text

•   render_data

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render

•   render_text

•   render_data

•   render_json({foo => 'bar'})

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render

•   render_text

•   render_data

•   render(json => {foo => 'bar'})

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render

•   render_text

•   render_data

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render

•   render_text

•   render_data

•   render_json

•   render_static('img/logo.png')

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render

•   render_text

•   render_data

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render

•   render_text

•   render_data

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   render

•   render_text

•   render_data

•   render_json

•   render_static

•   render_not_found / render_exception

•   send_message / receive_message

•   url_for / redirect_to
•   Mojolicous::Controller

•   Mojolicious::Plugins

•   Mojolicious::Commands

•   MojoX::Types

•   MojoX::Session

•   MojoX::Dispatcher, MojoX::Routes
Mojolicious::Plugins
        Plugins
•   AgentCondition

•   Charset

•   DefaultHelpers

•   EplRenderer

•   EpRenderer

•   HeaderCondition

•   I18n, JsonConfig, PoweredBy

•   PodRenderer, RequestTimer
•   AgentCondition

•   Charset

•   DefaultHelpers

•   EplRenderer

•   EpRenderer

•   HeaderCondition

•   I18n, JsonConfig, PoweredBy

•   PodRenderer, RequestTimer
•   dumper

•   param

•   stash

•   layout

•   include

•   content

•   extends

•   url_for
•   Data::Dumper (Maxdepth: 2, Indent: 1, Terse: 1)

•   param

•   stash

•   layout

•   include

•   content

•   extends

•   url_for
•   dumper

•   param

•   stash

•   layout

•   include

•   content

•   extends

•   url_for
•   dumper

•   $self->req->param( ... )

•   stash

•   layout

•   include

•   content

•   extends

•   url_for
•   dumper

•   param

•   stash

•   layout

•   include

•   content

•   extends

•   url_for
•   dumper

•   param

•   $self->stash( ... )

•   layout

•   include

•   content

•   extends

•   url_for
•   dumper

•   param

•   stash

•   layout

•   include

•   content

•   extends

•   url_for
•   dumper

•   param

•   stash

•   layout

•   include

•   content

•   extends

•   url_for
•   dumper

•   param

•   stash

•   layout

•   include

•   content

•   extends

•   url_for
•   dumper

•   param

•   stash

•   layout

•   include

•   content

•   extends

•   url_for
•   dumper

•   param

•   stash

•   layout

•   include

•   content

•   extends

•   url_for
•   dumper

•   param

•   stash

•   layout

•   include

•   content

•   extends

•   $self->url_for
•   AgentCondition

•   Charset

•   DefaultHelpers

•   EplRenderer

•   EpRenderer

•   HeaderCondition

•   I18n, JsonConfig, PoweredBy

•   PodRenderer, RequestTimer
EplRenderer
  Embed Perl Lite
•   расширение шаблонов .epl

•   в начале каждого шаблона:
    % my $self = shift;

•   $self->stash('foo')
•   AgentCondition

•   Charset

•   DefaultHelpers

•   EplRenderer

•   EpRenderer

•   HeaderCondition

•   I18n, JsonConfig, PoweredBy

•   PodRenderer, RequestTimer
EpRenderer
  Embed Perl
•   расширение шаблонов .ep

•   кеширование шаблонов со stash-параметрами

•   вместо $self->stash('foo') – $foo

•   доступны все helpers:
    % layout 'default';
    % warn dumper $list;

•   обработчик по умолчанию в mojolicious
•   Mojolicous::Controller

•   Mojolicious::Plugins

•   Mojolicious::Commands

•   MojoX::Types

•   MojoX::Session

•   MojoX::Dispatcher, MojoX::Routes
•   Mojolicous::Controller

•   Mojolicious::Plugins

•   Mojolicious::Commands

•   MojoX::Types

•   MojoX::Session

•   MojoX::Dispatcher, MojoX::Routes
•   Mojolicous::Controller

•   Mojolicious::Plugins

•   Mojolicious::Commands

•   MojoX::Types

•   MojoX::Session

•   MojoX::Dispatcher, MojoX::Routes
•   Mojolicous::Controller

•   Mojolicious::Plugins

•   Mojolicious::Commands

•   MojoX::Types

•   MojoX::Session

•   MojoX::Dispatcher, MojoX::Routes
Генерация
mojolicious-приложения
script/mojolicious generate
         app App
    [write ] app/script/app
    [chmod] app/script/app 744
    [write ] app/lib/App.pm
    [write ] app/lib/App/Example.pm
    [write ] app/t/basic.t
    [mkdir ] app/log
package App;
use base 'Mojolicious';

sub startup {
  my $self = shift;

     my $r = $self->routes;
     $r->route('/:controller/:action/:id')
       ->to('example#welcome', id => 1);
}

1;
package App;
use base 'Mojolicious';

sub startup {
  my $self = shift;

     my $r = $self->routes;
     $r->route('/:controller/:action/:id')
       ->to('example#welcome', id => 1);
}

1;
package App;
use base 'Mojolicious';

sub startup {
  my $self = shift;

     my $r = $self->routes;
     $r->route('/:controller/:action/:id')
       ->to('example#welcome', id => 1);
}

1;
package App;
use base 'Mojolicious';

sub startup {
  my $self = shift;

     my $r = $self->routes;
     $r->route('/:controller/:action/:id')
       ->to('example#welcome', id => 1);
}

1;
package App;
use base 'Mojolicious';

sub startup {
  my $self = shift;

     my $r = $self->routes;
     $r->route('/:controller/:action/:id')
       ->to('example#welcome', id => 1);
}

1;
package App;
use base 'Mojolicious';

sub startup {
  my $self = shift;

     my $r = $self->routes;
     $r->route('/:id', id => qr/d+/)
       ->to('example#welcome');
}

1;
package App;
use base 'Mojolicious';

sub startup {
  my $self = shift;

    my $r = $self->routes;
    for ($r->bridge->to('auth#check) {
         $_->route('/admin')->to('admin#welcome');
    }
}
package App;
use base 'Mojolicious';

sub startup {
  my $self = shift;

    my $r = $self->routes;
    for ($r->bridge->to('auth#check) {
         $_->route('/admin')->to('admin#welcome');
    }
}
package App;
use base 'Mojolicious';

sub startup {
  my $self = shift;

     my $r = $self->routes;
     $r->route('/:controller/:action/:id')
       ->to('example#welcome', id => 1);
}

1;
script/mojolicious generate
         app App
    [write ] app/script/app
    [chmod] app/script/app 744
    [write ] app/lib/App.pm
    [write ] app/lib/App/Example.pm
    [write ] app/t/basic.t
    [mkdir ] app/log
package App::Example;
use base 'Mojolicious::Controller';

sub welcome {
    my $self = shift;
	

 warn $self->stash(‘id’);
    $self->render(message => 'РИТ++ 2010');
}

1;
package App::Example;
use base 'Mojolicious::Controller';

sub welcome {
    my $self = shift;
	

 warn $self->stash(‘id’);
    $self->render(message => 'РИТ++ 2010');
}

1;
package App::Example;
use base 'Mojolicious::Controller';

sub welcome {
    my $self = shift;
	

 warn $self->stash(‘id’);
    $self->render(message => 'РИТ++ 2010');
}

1;
script/mojolicious generate
         app App
[mkdir] app/public
[write ] app/templates/not_found.html.ep
[write ] app/templates/exception.html.ep
[write ] app/templates/layouts/default.html.ep
[write ] app/templates/example/welcome.html.ep
script/mojolicious generate
         app App
[mkdir] app/public
[write ] app/templates/not_found.html.ep
[write ] app/templates/exception.html.ep
[write ] app/templates/layouts/default.html.ep
[write ] app/templates/example/welcome.html.ep
script/mojolicious generate
         app App
[mkdir] app/public
[write ] app/templates/not_found.html.ep
[write ] app/templates/exception.html.ep
[write ] app/templates/layouts/default.html.ep
[write ] app/templates/example/welcome.html.ep
% layout 'default';

<h2><%= $message %></h2>

<a href="<%== url_for %>">click here</a>
% layout 'default';

<h2><%= $message %></h2>

<a href="<%== url_for %>">click here</a>
% layout 'default';

<h2><%= $self->stash('message') %></h2>

<a href="<%== url_for %>">click here</a>
% layout 'default';

<h2><%= $message %></h2>

<a href="<%== url_for %>">click here</a>
% layout 'default';

<h2><%= stash 'message' %></h2>

<a href="<%== url_for %>">click here</a>
% layout 'default';

<h2><%= $message %></h2>

<a href="<%== url_for %>">click here</a>
script/mojolicious generate
         app App
[mkdir] app/public
[write ] app/templates/not_found.html.ep
[write ] app/templates/exception.html.ep
[write ] app/templates/layouts/default.html.ep
[write ] app/templates/example/welcome.html.ep
<!doctype html>
<html>
   <head><title>Welcome</title></head>
   <body>
     <%== content %>
   </body>
</html>
<!doctype html>
<html>
   <head><title>Welcome</title></head>
   <body>
     <%== content %>
   </body>
</html>
script/mojolicious generate
         app App
[mkdir] app/public
[write ] app/templates/not_found.html.ep
[write ] app/templates/exception.html.ep
[write ] app/templates/layouts/default.html.ep
[write ] app/templates/example/welcome.html.ep
script/mojolicious generate
         app App
[mkdir] app/public
[write ] app/templates/not_found.html.ep
[write ] app/templates/exception.html.ep
[write ] app/templates/layouts/default.html.ep
[write ] app/templates/example/welcome.html.ep
Global symbol "$message2" requires explicit
package name at (eval 280) line 2.

1: % layout 'default';
2: <h2><%= $message2 %></h2>
3: ...

{
    'status' => 500,
    'message' => ‘РИТ++ 2010’,
    ...
example/
 welcome.html.ep
Автоматическая генерация имени шаблона
controller/
action.format.handler
 Автоматическая генерация имени шаблона
example/
 welcome.html.ep
Автоматическая генерация имени шаблона
example/
  welcome.xml.ep
Автоматическая генерация имени шаблона
example/
   welcome.rss.ep
Автоматическая генерация имени шаблона
example/
  welcome.json.ep
Автоматическая генерация имени шаблона
example/
 welcome.html.ep
Автоматическая генерация имени шаблона
example/
 welcome.html.epl
Автоматическая генерация имени шаблона
example/
  welcome.html.tt
Автоматическая генерация имени шаблона
example/
welcome.html.cttp2
Автоматическая генерация имени шаблона
script/app COMMAND
      [OPTIONS]
    script/app cgi
    script/app fastcgi
    script/app psgi
    script/app daemon
    script/app daemon_prefork
script/app COMMAND
      [OPTIONS]
    script/app get
    script/app test
    script/app routes
Mojolicious::Lite
   use base 'Mojolicious';
script/mojolicious generate
       lite_app lite.pl
       [write ] lite.pl
       [chmod] lite.pl 744
use Mojolicious::Lite;

get '/' => 'index';

get '/:groovy' => sub {
   my $self = shift;
   $self->render_text( $self->param('groovy') );
};

app->start;
use Mojolicious::Lite;

get '/' => 'index';

get '/:groovy' => sub {
   my $self = shift;
   $self->render_text( $self->param('groovy') );
};

app->start;
use Mojolicious::Lite;

get '/' => 'index';

get '/:groovy' => sub {
   my $self = shift;
   $self->render_text( $self->param('groovy') );
};

app->start;
use Mojolicious::Lite;

post '/' => 'index';

get '/:groovy' => sub {
   my $self = shift;
   $self->render_text( $self->param('groovy') );
};

app->start;
use Mojolicious::Lite;

any '/' => 'index';

get '/:groovy' => sub {
   my $self = shift;
   $self->render_text( $self->param('groovy') );
};

app->start;
use Mojolicious::Lite;

get '/' => (agent => qr/Firefox/) => 'index';

get '/:groovy' => sub {
   my $self = shift;
   $self->render_text( $self->param('groovy') );
};

app->start;
use Mojolicious::Lite;

get '/' => 'index';

get '/:groovy' => {groovy => 42} => sub {
   my $self = shift;
   $self->render_text( $self->param('groovy') );
};

app->start;
use Mojolicious::Lite;

get '/' => 'index';

get '/:groovy' => [groovy => qr/d+/] => sub {
   my $self = shift;
   $self->render_text( $self->param('groovy') );
};

app->start;
use Mojolicious::Lite;
ladder sub {}; # auth
get '/' => 'index';

get '/:groovy' => sub {
   my $self = shift;
   $self->render_text( $self->param('groovy') );
};

app->start;
use Mojolicious::Lite;
websocket '/echo' => sub { ... };
get '/' => 'index';

get '/:groovy' => sub {
   my $self = shift;
   $self->render_text( $self->param('groovy') );
};

app->start;
use Mojolicious::Lite;

get '/' => 'index';

get '/:groovy' => sub {
   my $self = shift;
   $self->render_text( $self->param('groovy') );
};
app->renderer->default_handler('epl');
app->start;
use Mojolicious::Lite;

get '/' => 'index';

get '/:groovy' => sub {
   my $self = shift;
   $self->render_text( $self->param('groovy') );
};

app->start;
__DATA__

@@ index.html.ep
% layout 'funky';
Yea baby!

@@ layouts/funky.html.ep
<!doctype html><html>
   <head><title>Funky!</title></head>
   <body><%== content %></body>
</html>
__DATA__

@@ index.html.ep
% layout 'funky';
Yea baby!

@@ layouts/funky.html.ep
<!doctype html><html>
   <head><title>Funky!</title></head>
   <body><%== content %></body>
</html>
lite.pl COMMAND
     [OPTIONS]
  lite.pl cgi
  lite.pl fastcgi
  lite.pl psgi
  lite.pl daemon
  lite.pl daemon_prefork
lite.pl COMMAND
     [OPTIONS]
  lite.pl test
  lite.pl get
  lite.pl routes
  lite.pl inflate
«Making hard things possible
   and everything fun!»
         Девиз Mojolicious
«Viva la revolution!»
    Девиз Mojolicious #2
«Duct tape for the HTML5
          web»
       Девиз Mojolicious #3
Mojolicious-модули на CPAN
• Mojolicious              • MojoX::Routes::AsGraph
• Mojo::Server::FCGI       • MojoX::Log::*
• AnyEvent::Mojo           • MojoX::Renderer::*
• Apache::Mojo
  Apache2::Mojo             • TT
• Catalyst::Engine::Mojo    • CTTP2, HTP
  Squatting::On::Mojo       • XSLT
Mojolicious-модули на CPAN
• Mojolicious              • MojoX::Routes::AsGraph
• Mojo::Server::FCGI       • MojoX::Log::*
• AnyEvent::Mojo           • MojoX::Renderer::*
• Apache::Mojo
  Apache2::Mojo             • TT
• Catalyst::Engine::Mojo    • CTTP2, HTP
  Squatting::On::Mojo       • XSLT
Mojolicious-модули на CPAN
• Mojolicious              • MojoX::Routes::AsGraph
• Mojo::Server::FCGI       • MojoX::Log::*
• AnyEvent::Mojo           • MojoX::Renderer::*
• Apache::Mojo
  Apache2::Mojo             • TT
• Catalyst::Engine::Mojo    • CTTP2, HTP
  Squatting::On::Mojo       • XSLT
Mojolicious::Lite
       vs.
   Dancer
    Соревнование
Стабильная версия,
 совместимость?
Обратная
  совместимость
не гарантируется :)
  До первой стабильной версии
Mojolicious 0.999925
Последняя версия доступна на github.com
Документация
• Пока не очень, зато очень хороший фидбек :)
• Mojolicious::Lite и Mojolicious::Guides
• Mojolicious Handbook на github.com @kvorg
• Mojolicious FAQ на github.com @vti
Полезная информация
• http://mojolicious.org
• irc://irc.perl.org/#mojo
• http://groups.google.com/group/mojolicious
• Github: kraih, vti, xantus
• Twitter: @kraih, @vtivti, @sharifulin
• Juick: @vti, @sharifulin
«Особая разновидность
современного программиста
 – программист, изучающий
        фреймворки»
«Каждый программист
 должен сделать 3 вещи:
фреймворк, шаблонизатор
 и событийную машину»
use Mojolicious
     or die;
Viva la revolution!
use Perl
  or die;
JFDI
any ‘/questions’ => sub {
	

 	

 shift->render(
	

 	

 	

 answer => ‘sharifulin’,
	

 	

 );
   };
Спасибо за внимание!
      Это 256й слайд
     Анатолий Шарифулин

Más contenido relacionado

La actualidad más candente

CSS: A Slippery Slope to the Backend
CSS: A Slippery Slope to the BackendCSS: A Slippery Slope to the Backend
CSS: A Slippery Slope to the BackendFITC
 
RESTful APIs: Promises & lies
RESTful APIs: Promises & liesRESTful APIs: Promises & lies
RESTful APIs: Promises & liesTareque Hossain
 
CO2 sequestration in a different manner
CO2 sequestration in a different mannerCO2 sequestration in a different manner
CO2 sequestration in a different mannerGreen Minerals B.V.
 
How to use MongoDB with CakePHP
How to use MongoDB with CakePHPHow to use MongoDB with CakePHP
How to use MongoDB with CakePHPichikaway
 
jQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformancejQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformanceJonas De Smet
 
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway ichikaway
 
Hebrew Bible as Data: Laboratory, Sharing, Lessons
Hebrew Bible as Data: Laboratory, Sharing, LessonsHebrew Bible as Data: Laboratory, Sharing, Lessons
Hebrew Bible as Data: Laboratory, Sharing, LessonsDirk Roorda
 
Concept History
Concept HistoryConcept History
Concept Historyjonphipps
 
Getting started with MongoDB and PHP
Getting started with MongoDB and PHPGetting started with MongoDB and PHP
Getting started with MongoDB and PHPgates10gen
 
Why Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary ThingWhy Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary ThingChris Reynolds
 
Missing kids on you
Missing kids on youMissing kids on you
Missing kids on youguest3fa681
 
Forbes MongoNYC 2011
Forbes MongoNYC 2011Forbes MongoNYC 2011
Forbes MongoNYC 2011djdunlop
 
Data Mangling with mongoDB the Right Way [PyData London] 2016]
Data Mangling with mongoDB the Right Way [PyData London] 2016]Data Mangling with mongoDB the Right Way [PyData London] 2016]
Data Mangling with mongoDB the Right Way [PyData London] 2016]Alexander Hendorf
 

La actualidad más candente (17)

CSS: A Slippery Slope to the Backend
CSS: A Slippery Slope to the BackendCSS: A Slippery Slope to the Backend
CSS: A Slippery Slope to the Backend
 
RESTful APIs: Promises & lies
RESTful APIs: Promises & liesRESTful APIs: Promises & lies
RESTful APIs: Promises & lies
 
CO2 sequestration in a different manner
CO2 sequestration in a different mannerCO2 sequestration in a different manner
CO2 sequestration in a different manner
 
How to use MongoDB with CakePHP
How to use MongoDB with CakePHPHow to use MongoDB with CakePHP
How to use MongoDB with CakePHP
 
jQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformancejQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and Performance
 
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
 
Hebrew Bible as Data: Laboratory, Sharing, Lessons
Hebrew Bible as Data: Laboratory, Sharing, LessonsHebrew Bible as Data: Laboratory, Sharing, Lessons
Hebrew Bible as Data: Laboratory, Sharing, Lessons
 
PHP Tutorial (funtion)
PHP Tutorial (funtion)PHP Tutorial (funtion)
PHP Tutorial (funtion)
 
Concept History
Concept HistoryConcept History
Concept History
 
Getting started with MongoDB and PHP
Getting started with MongoDB and PHPGetting started with MongoDB and PHP
Getting started with MongoDB and PHP
 
PHP 1
PHP 1PHP 1
PHP 1
 
Why Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary ThingWhy Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary Thing
 
Missing kids on you
Missing kids on youMissing kids on you
Missing kids on you
 
Forbes MongoNYC 2011
Forbes MongoNYC 2011Forbes MongoNYC 2011
Forbes MongoNYC 2011
 
PHP 5.4
PHP 5.4PHP 5.4
PHP 5.4
 
Yql && Raphaël
Yql && RaphaëlYql && Raphaël
Yql && Raphaël
 
Data Mangling with mongoDB the Right Way [PyData London] 2016]
Data Mangling with mongoDB the Right Way [PyData London] 2016]Data Mangling with mongoDB the Right Way [PyData London] 2016]
Data Mangling with mongoDB the Right Way [PyData London] 2016]
 

Destacado (6)

Frodio
FrodioFrodio
Frodio
 
Apresentação EstAção RH 2016
Apresentação EstAção RH 2016Apresentação EstAção RH 2016
Apresentação EstAção RH 2016
 
บทที่8dd
บทที่8ddบทที่8dd
บทที่8dd
 
TT
TTTT
TT
 
28 profecias cumplidas
28 profecias cumplidas28 profecias cumplidas
28 profecias cumplidas
 
Modern Perl
Modern  PerlModern  Perl
Modern Perl
 

Similar a Mojolicious

анатолий шарифулин Mojolicious финальная версия
анатолий шарифулин Mojolicious   финальная версияанатолий шарифулин Mojolicious   финальная версия
анатолий шарифулин Mojolicious финальная версияrit2010
 
Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Anatoly Sharifulin
 
Beyond HTML - Scriptsprachen, Frameworks, Templatesprachen und vieles mehr
Beyond HTML - Scriptsprachen, Frameworks, Templatesprachen und vieles mehrBeyond HTML - Scriptsprachen, Frameworks, Templatesprachen und vieles mehr
Beyond HTML - Scriptsprachen, Frameworks, Templatesprachen und vieles mehrJens-Christian Fischer
 
PHP Basics and Demo HackU
PHP Basics and Demo HackUPHP Basics and Demo HackU
PHP Basics and Demo HackUAnshu Prateek
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server Masahiro Nagano
 
Ben Bridts - $ aws help
Ben Bridts -  $ aws helpBen Bridts -  $ aws help
Ben Bridts - $ aws helpAWSCOMSUM
 
PHP Experience 2016 - [Workshop] Elastic Search: Turbinando sua aplicação PHP
PHP Experience 2016 - [Workshop] Elastic Search: Turbinando sua aplicação PHPPHP Experience 2016 - [Workshop] Elastic Search: Turbinando sua aplicação PHP
PHP Experience 2016 - [Workshop] Elastic Search: Turbinando sua aplicação PHPiMasters
 
Working with web_services
Working with web_servicesWorking with web_services
Working with web_servicesLorna Mitchell
 
SINATRA + HAML + TWITTER
SINATRA + HAML + TWITTERSINATRA + HAML + TWITTER
SINATRA + HAML + TWITTERElber Ribeiro
 
Ch1(introduction to php)
Ch1(introduction to php)Ch1(introduction to php)
Ch1(introduction to php)Chhom Karath
 
FizzBuzzではじめるテスト
FizzBuzzではじめるテストFizzBuzzではじめるテスト
FizzBuzzではじめるテストMasashi Shinbara
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP GeneratorsMark Baker
 
Generated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 GeneratorsGenerated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 GeneratorsMark Baker
 

Similar a Mojolicious (20)

анатолий шарифулин Mojolicious финальная версия
анатолий шарифулин Mojolicious   финальная версияанатолий шарифулин Mojolicious   финальная версия
анатолий шарифулин Mojolicious финальная версия
 
Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
 
Beyond HTML - Scriptsprachen, Frameworks, Templatesprachen und vieles mehr
Beyond HTML - Scriptsprachen, Frameworks, Templatesprachen und vieles mehrBeyond HTML - Scriptsprachen, Frameworks, Templatesprachen und vieles mehr
Beyond HTML - Scriptsprachen, Frameworks, Templatesprachen und vieles mehr
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
PHP Basics and Demo HackU
PHP Basics and Demo HackUPHP Basics and Demo HackU
PHP Basics and Demo HackU
 
ApacheCon 2005
ApacheCon 2005ApacheCon 2005
ApacheCon 2005
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server
 
Ben Bridts - $ aws help
Ben Bridts -  $ aws helpBen Bridts -  $ aws help
Ben Bridts - $ aws help
 
PHP Experience 2016 - [Workshop] Elastic Search: Turbinando sua aplicação PHP
PHP Experience 2016 - [Workshop] Elastic Search: Turbinando sua aplicação PHPPHP Experience 2016 - [Workshop] Elastic Search: Turbinando sua aplicação PHP
PHP Experience 2016 - [Workshop] Elastic Search: Turbinando sua aplicação PHP
 
Working with web_services
Working with web_servicesWorking with web_services
Working with web_services
 
SINATRA + HAML + TWITTER
SINATRA + HAML + TWITTERSINATRA + HAML + TWITTER
SINATRA + HAML + TWITTER
 
Ch1(introduction to php)
Ch1(introduction to php)Ch1(introduction to php)
Ch1(introduction to php)
 
FizzBuzzではじめるテスト
FizzBuzzではじめるテストFizzBuzzではじめるテスト
FizzBuzzではじめるテスト
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
Bioinformatica p6-bioperl
Bioinformatica p6-bioperlBioinformatica p6-bioperl
Bioinformatica p6-bioperl
 
InnoDB Magic
InnoDB MagicInnoDB Magic
InnoDB Magic
 
Generated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 GeneratorsGenerated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 Generators
 

Mojolicious

  • 2.
  • 3. Sebastian Riedel автор Catalyst и Mojolicious http://twitter.com/kraih
  • 4.
  • 6. Что такое Mojolicious? • Pure Perl веб-фреймворк • Без зависимостей (с версии Perl 5.8.1) • Объектно-ориентированное API (без скрытой магии) • Поддержка HTTP 1.1, WebSocket, IPv6, SSL, IDNA • Поддержка CGI, FastCGI, PSGI, Daemon и Prefork • Веб-фреймворки: Mojo, Mojolicious и Mojolicious::Lite
  • 7. «Fresh code, based upon years of expirience developing Catalyst»
  • 8.
  • 10. • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • 11. • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • 12. Mojo::Base Minimal Base Class For Mojo Projects
  • 13. package App; use base ‘Mojo::Base’; __PACKAGE__->attr(conf => sub { return do ‘conf/app.conf’; }); __PACKAGE__->attr(db => sub { my $self = shift; return Util->db($self->conf->{'db'}); }); sub dispatch { ... }
  • 14. package App; use base ‘Mojo::Base’; __PACKAGE__->attr(conf => sub { return do ‘conf/app.conf’; }); __PACKAGE__->attr(db => sub { my $self = shift; return Util->db($self->conf->{'db'}); }); sub dispatch { ... }
  • 15. package App; use base ‘Mojo::Base’; __PACKAGE__->attr(conf => sub { return do ‘conf/app.conf’; }); __PACKAGE__->attr(db => sub { my $self = shift; return Util->db($self->conf->{'db'}); }); sub dispatch { ... }
  • 16. • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • 17. Mojo::ByteStream ByteStream
  • 18. use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • 19. use Mojo::ByteStream 'b'; my $s = b('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • 20. use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • 21. use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • 22. use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • 23. use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • 24. use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • 25. use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • 26. use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • 27. use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • 28. use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • 29. • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • 30. Mojo::Template Perlish Templates!
  • 31. % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • 32. % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • 33. % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • 34. % my $count = 10 * 5; <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • 35. % use Foo::Bar; <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • 36. % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • 37. % my $list = $self->stash(‘list’); <ul> % if (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • 38. % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • 39. % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • 40. % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%== $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • 41. % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= ucfirst $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • 42. % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • 43. % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • 44. 1 % my $list = $self->stash(‘list’); 2 3 <ul> 4 % for (@$list) { 5 <li> 6 <%= $_->{title} xx %> 7 </li> 8 %} 9 </ul> 10 11 <p><%# comment %></p>
  • 45. Сообщение об ошибке Bareword "xx" not allowed while "strict subs" in use at template line 6.
  • 47. • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • 49. my $json = Mojo::JSON->new; my $string = $json->encode({foo => ‘bar’}); my $hash = $json->decode(‘{"foo":"bar"}’);
  • 50. my $json = Mojo::JSON->new; my $string = $json->encode({foo => ‘bar’}); my $hash = $json->decode(‘{"foo":"bar"}’);
  • 51. • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • 53. • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • 54. • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • 55. • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • 56. Mojo::Trasaction • Mojo::IOLoop • Mojo::Client, Mojo::Server • Mojo::Server::CGI, Mojo::Server::FastCGI • Mojo::Server::PSGI • Mojo::Server::Daemon и ::Prefork • Mojo::Command • Mojo::Command::Generate и ~ Server
  • 57. Mojo::Trasaction • Mojo::IOLoop • Mojo::Client, Mojo::Server • Mojo::Server::CGI, Mojo::Server::FastCGI • Mojo::Server::PSGI • Mojo::Server::Daemon и ::Prefork • Mojo::Command • Mojo::Command::Generate и ~ Server
  • 58. Mojo::Trasaction • Mojo::IOLoop • Mojo::Client, Mojo::Server • Mojo::Server::CGI, Mojo::Server::FastCGI • Mojo::Server::PSGI • Mojo::Server::Daemon и ::Prefork • Mojo::Command • Mojo::Command::Generate и ~ Server
  • 59. Mojo::IOLoop Minimalistic Reactor For TCP Clients And Servers
  • 61. my $loop = Mojo::IOLoop->new; $loop->listen(port => 3000, cb => sub { my ($self, $id) = @_; $self->read_cb ($id => sub { ... }); $self->write_cb($id => sub { ... }); ); my $id = $loop->connect(port => 3000, ...); $loop->start; $loop->stop;
  • 62. my $loop = Mojo::IOLoop->new; $loop->listen(port => 3000, cb => sub { my ($self, $id) = @_; $self->read_cb ($id => sub { ... }); $self->write_cb($id => sub { ... }); ); my $id = $loop->connect(port => 3000, ...); $loop->start; $loop->stop;
  • 63. my $loop = Mojo::IOLoop->new; $loop->listen(port => 3000, cb => sub { my ($self, $id) = @_; $self->read_cb ($id => sub { ... }); $self->write_cb($id => sub { ... }); ); my $id = $loop->connect(port => 3000, ...); $loop->start; $loop->stop;
  • 64. my $loop = Mojo::IOLoop->new; $loop->listen(port => 3000, cb => sub { my ($self, $id) = @_; $self->read_cb ($id => sub { ... }); $self->write_cb($id => sub { ... }); ); my $id = $loop->connect(port => 3000, ...); $loop->start; $loop->stop;
  • 65. Mojo::Trasaction • Mojo::IOLoop • Mojo::Client, Mojo::Server • Mojo::Server::CGI, Mojo::Server::FastCGI • Mojo::Server::PSGI • Mojo::Server::Daemon и ::Prefork • Mojo::Command • Mojo::Command::Generate и ~ Server
  • 66. Mojo::Client Async IO HTTP 1.1 And WebSocket Client
  • 67. my $client = Mojo::Client->new; $client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • 68. my $client = Mojo::Client->new; $self->client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • 69. my $client = Mojo::Client->new; $client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • 70. my $client = Mojo::Client->new; $client->head( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • 71. my $client = Mojo::Client->new; $client->post( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • 72. my $client = Mojo::Client->new; $client->put( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • 73. my $client = Mojo::Client->new; $client->async->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • 74. my $client = Mojo::Client->new; $client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • 75. my $client = Mojo::Client->new; $client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • 76. my $client = Mojo::Client->new; $client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • 77. my $client = Mojo::Client->new; $client->get(‘http://goo.gl’)->res->code; $client->get( 'http://search.twitter.com/trends.json' )->success->json->{trends}->[0]->{name}
  • 78. my $client = Mojo::Client->new; $client->get(‘http://goo.gl’)->res->code; $client->get( 'http://search.twitter.com/trends.json' )->success->json->{trends}->[0]->{name}
  • 80. Mojo::Trasaction • Mojo::IOLoop • Mojo::Client, Mojo::Server • Mojo::Server::CGI, Mojo::Server::FastCGI • Mojo::Server::PSGI • Mojo::Server::Daemon и ::Prefork • Mojo::Command • Mojo::Command::Generate и ~ Server
  • 81. Mojo::Trasaction • Mojo::IOLoop • Mojo::Client, Mojo::Server • Mojo::Server::CGI, Mojo::Server::FastCGI • Mojo::Server::PSGI • Mojo::Server::Daemon и ::Prefork • Mojo::Command • Mojo::Command::Generate и ~ Server
  • 82. Mojo::Trasaction • Mojo::IOLoop • Mojo::Client, Mojo::Server • Mojo::Server::CGI, Mojo::Server::FastCGI • Mojo::Server::PSGI • Mojo::Server::Daemon и ::Prefork • Mojo::Command • Mojo::Command::Generate и ~ Server
  • 83. Всё, что нужно – есть Mojolicious – веб в коробке!
  • 84. Без зависимостей с версии Perl 5.8.1
  • 91. package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • 92. package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • 93. package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • 94. package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • 95. package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • 96. package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • 97. use overload '""' => sub { shift->to_string }, fallback => 1;
  • 98. GET / HTTP/1.1 Connection: keep-alive Accept: text/html, application/xhtml, .... Accept-Charset: windows-1251, utf-8; ... Accept-Encoding: gzip,deflate Accept-Language: ru,en-us;q=0.7,en;q=0.3 Host: localhost:3000 User-Agent: Mozilla/5.0 (Macintosh; ... Content-Length: 0 Keep-Alive: 300
  • 99. Поддержка HTTP 1.1 клиент-сервер
  • 100.
  • 101. Google Summer of Code 2009 Pascal Gaudette MojoX::UserAgent
  • 102. Поддержка WebSocket клиент-сервер
  • 103. Протокол WebSocket Google, Inc 16 декабря 2009 года
  • 104. use Mojolicious::Lite; websocket ‘/echo’ => sub { my $self = shift; $self->receive_message(sub { my ($self, $msg) = @_; $self->send_massage("echo: $msg"); }); }; app->start;
  • 105. use Mojolicious::Lite; websocket ‘/echo’ => sub { my $self = shift; $self->receive_message(sub { my ($self, $msg) = @_; $self->send_massage("echo: $msg"); }); }; app->start;
  • 106. Mojolicious WebSocket Examples Интересный пример IRC-клиент Github.com @xantus
  • 107. Google Summer of Code 2010 Performance tuning the http/websocket implementation
  • 108. Поддержка CGI, FastCGI, PSGI, Daemon и Prefork
  • 109. script/mojolicious COMMAND [OPTIONS] script/mojolicious cgi script/mojolicious fastcgi script/mojolicious psgi script/mojolicious daemon script/mojolicious daemon_prefork
  • 110. script/mojolicious COMMAND [OPTIONS] script/mojolicious cgi script/mojolicious fastcgi script/mojolicious psgi script/mojolicious daemon script/mojolicious daemon_prefork
  • 111. PATH_INFO='/foo/bar' script/mojolicious cgi Легко тестировать Можно профилировать код, используя Devel::NYTProf
  • 112. script/mojolicious COMMAND [OPTIONS] script/mojolicious cgi script/mojolicious fastcgi script/mojolicious psgi script/mojolicious daemon script/mojolicious daemon_prefork
  • 114. script/mojolicious COMMAND [OPTIONS] script/mojolicious cgi script/mojolicious fastcgi script/mojolicious psgi script/mojolicious daemon script/mojolicious daemon_prefork
  • 115. script/mojolicious COMMAND [OPTIONS] script/mojolicious cgi script/mojolicious fastcgi script/mojolicious psgi script/mojolicious daemon script/mojolicious daemon_prefork
  • 116. script/mojolicious daemon --reload Приложение перезагружается перед запросом, если код был изменен
  • 117. Обработка сигнала USR1 Для обновления кода приложения
  • 118. script/mojolicious COMMAND [OPTIONS] script/mojolicious cgi script/mojolicious fastcgi script/mojolicious psgi script/mojolicious daemon script/mojolicious daemon_prefork
  • 121. package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • 122. package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • 124. script/mojo generate app App [write ] app/script/app [chmod] app/script/app 744 [write ] app/lib/App.pm [write ] app/t/basic.t [mkdir ] app/log
  • 125. script/app COMMAND [OPTIONS] script/app cgi script/app fastcgi script/app psgi script/app daemon script/app daemon_prefork
  • 126. script/app COMMAND [OPTIONS] script/app get script/app test
  • 129. Mojolicous::Controller • Mojolicious::Plugins • Mojolicious::Commands • MojoX::Types • MojoX::Session • MojoX::Dispatcher, MojoX::Routes
  • 130. Mojolicous::Controller • Mojolicious::Plugins • Mojolicious::Commands • MojoX::Types • MojoX::Session • MojoX::Dispatcher, MojoX::Routes
  • 131. Mojolicious::Controller Controller Base Class
  • 132. render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 133. render(controller => 'foo', action => 'bar') • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 134. render(template => 'foo/bar') • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 135. render('foo#bar') • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 136. render('foo#bar', format => 'html') • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 137. render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 138. render • render_text('РИТ++ 2010') • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 139. render • render(text => 'РИТ++ 2010') • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 140. render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 141. render • render_text • render_data('binary data') • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 142. render • render_text • render(data => 'binary data') • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 143. render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 144. render • render_text • render_data • render_json({foo => 'bar'}) • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 145. render • render_text • render_data • render(json => {foo => 'bar'}) • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 146. render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 147. render • render_text • render_data • render_json • render_static('img/logo.png') • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 148. render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 149. render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 150. render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • 151. Mojolicous::Controller • Mojolicious::Plugins • Mojolicious::Commands • MojoX::Types • MojoX::Session • MojoX::Dispatcher, MojoX::Routes
  • 153. AgentCondition • Charset • DefaultHelpers • EplRenderer • EpRenderer • HeaderCondition • I18n, JsonConfig, PoweredBy • PodRenderer, RequestTimer
  • 154. AgentCondition • Charset • DefaultHelpers • EplRenderer • EpRenderer • HeaderCondition • I18n, JsonConfig, PoweredBy • PodRenderer, RequestTimer
  • 155. dumper • param • stash • layout • include • content • extends • url_for
  • 156. Data::Dumper (Maxdepth: 2, Indent: 1, Terse: 1) • param • stash • layout • include • content • extends • url_for
  • 157. dumper • param • stash • layout • include • content • extends • url_for
  • 158. dumper • $self->req->param( ... ) • stash • layout • include • content • extends • url_for
  • 159. dumper • param • stash • layout • include • content • extends • url_for
  • 160. dumper • param • $self->stash( ... ) • layout • include • content • extends • url_for
  • 161. dumper • param • stash • layout • include • content • extends • url_for
  • 162. dumper • param • stash • layout • include • content • extends • url_for
  • 163. dumper • param • stash • layout • include • content • extends • url_for
  • 164. dumper • param • stash • layout • include • content • extends • url_for
  • 165. dumper • param • stash • layout • include • content • extends • url_for
  • 166. dumper • param • stash • layout • include • content • extends • $self->url_for
  • 167. AgentCondition • Charset • DefaultHelpers • EplRenderer • EpRenderer • HeaderCondition • I18n, JsonConfig, PoweredBy • PodRenderer, RequestTimer
  • 168. EplRenderer Embed Perl Lite
  • 169. расширение шаблонов .epl • в начале каждого шаблона: % my $self = shift; • $self->stash('foo')
  • 170. AgentCondition • Charset • DefaultHelpers • EplRenderer • EpRenderer • HeaderCondition • I18n, JsonConfig, PoweredBy • PodRenderer, RequestTimer
  • 172. расширение шаблонов .ep • кеширование шаблонов со stash-параметрами • вместо $self->stash('foo') – $foo • доступны все helpers: % layout 'default'; % warn dumper $list; • обработчик по умолчанию в mojolicious
  • 173. Mojolicous::Controller • Mojolicious::Plugins • Mojolicious::Commands • MojoX::Types • MojoX::Session • MojoX::Dispatcher, MojoX::Routes
  • 174. Mojolicous::Controller • Mojolicious::Plugins • Mojolicious::Commands • MojoX::Types • MojoX::Session • MojoX::Dispatcher, MojoX::Routes
  • 175. Mojolicous::Controller • Mojolicious::Plugins • Mojolicious::Commands • MojoX::Types • MojoX::Session • MojoX::Dispatcher, MojoX::Routes
  • 176. Mojolicous::Controller • Mojolicious::Plugins • Mojolicious::Commands • MojoX::Types • MojoX::Session • MojoX::Dispatcher, MojoX::Routes
  • 178. script/mojolicious generate app App [write ] app/script/app [chmod] app/script/app 744 [write ] app/lib/App.pm [write ] app/lib/App/Example.pm [write ] app/t/basic.t [mkdir ] app/log
  • 179. package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; $r->route('/:controller/:action/:id') ->to('example#welcome', id => 1); } 1;
  • 180. package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; $r->route('/:controller/:action/:id') ->to('example#welcome', id => 1); } 1;
  • 181. package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; $r->route('/:controller/:action/:id') ->to('example#welcome', id => 1); } 1;
  • 182. package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; $r->route('/:controller/:action/:id') ->to('example#welcome', id => 1); } 1;
  • 183. package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; $r->route('/:controller/:action/:id') ->to('example#welcome', id => 1); } 1;
  • 184. package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; $r->route('/:id', id => qr/d+/) ->to('example#welcome'); } 1;
  • 185. package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; for ($r->bridge->to('auth#check) { $_->route('/admin')->to('admin#welcome'); } }
  • 186. package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; for ($r->bridge->to('auth#check) { $_->route('/admin')->to('admin#welcome'); } }
  • 187. package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; $r->route('/:controller/:action/:id') ->to('example#welcome', id => 1); } 1;
  • 188. script/mojolicious generate app App [write ] app/script/app [chmod] app/script/app 744 [write ] app/lib/App.pm [write ] app/lib/App/Example.pm [write ] app/t/basic.t [mkdir ] app/log
  • 189. package App::Example; use base 'Mojolicious::Controller'; sub welcome { my $self = shift; warn $self->stash(‘id’); $self->render(message => 'РИТ++ 2010'); } 1;
  • 190. package App::Example; use base 'Mojolicious::Controller'; sub welcome { my $self = shift; warn $self->stash(‘id’); $self->render(message => 'РИТ++ 2010'); } 1;
  • 191. package App::Example; use base 'Mojolicious::Controller'; sub welcome { my $self = shift; warn $self->stash(‘id’); $self->render(message => 'РИТ++ 2010'); } 1;
  • 192. script/mojolicious generate app App [mkdir] app/public [write ] app/templates/not_found.html.ep [write ] app/templates/exception.html.ep [write ] app/templates/layouts/default.html.ep [write ] app/templates/example/welcome.html.ep
  • 193. script/mojolicious generate app App [mkdir] app/public [write ] app/templates/not_found.html.ep [write ] app/templates/exception.html.ep [write ] app/templates/layouts/default.html.ep [write ] app/templates/example/welcome.html.ep
  • 194. script/mojolicious generate app App [mkdir] app/public [write ] app/templates/not_found.html.ep [write ] app/templates/exception.html.ep [write ] app/templates/layouts/default.html.ep [write ] app/templates/example/welcome.html.ep
  • 195. % layout 'default'; <h2><%= $message %></h2> <a href="<%== url_for %>">click here</a>
  • 196. % layout 'default'; <h2><%= $message %></h2> <a href="<%== url_for %>">click here</a>
  • 197. % layout 'default'; <h2><%= $self->stash('message') %></h2> <a href="<%== url_for %>">click here</a>
  • 198. % layout 'default'; <h2><%= $message %></h2> <a href="<%== url_for %>">click here</a>
  • 199. % layout 'default'; <h2><%= stash 'message' %></h2> <a href="<%== url_for %>">click here</a>
  • 200. % layout 'default'; <h2><%= $message %></h2> <a href="<%== url_for %>">click here</a>
  • 201. script/mojolicious generate app App [mkdir] app/public [write ] app/templates/not_found.html.ep [write ] app/templates/exception.html.ep [write ] app/templates/layouts/default.html.ep [write ] app/templates/example/welcome.html.ep
  • 202. <!doctype html> <html> <head><title>Welcome</title></head> <body> <%== content %> </body> </html>
  • 203. <!doctype html> <html> <head><title>Welcome</title></head> <body> <%== content %> </body> </html>
  • 204. script/mojolicious generate app App [mkdir] app/public [write ] app/templates/not_found.html.ep [write ] app/templates/exception.html.ep [write ] app/templates/layouts/default.html.ep [write ] app/templates/example/welcome.html.ep
  • 205. script/mojolicious generate app App [mkdir] app/public [write ] app/templates/not_found.html.ep [write ] app/templates/exception.html.ep [write ] app/templates/layouts/default.html.ep [write ] app/templates/example/welcome.html.ep
  • 206. Global symbol "$message2" requires explicit package name at (eval 280) line 2. 1: % layout 'default'; 2: <h2><%= $message2 %></h2> 3: ... { 'status' => 500, 'message' => ‘РИТ++ 2010’, ...
  • 210. example/ welcome.xml.ep Автоматическая генерация имени шаблона
  • 211. example/ welcome.rss.ep Автоматическая генерация имени шаблона
  • 212. example/ welcome.json.ep Автоматическая генерация имени шаблона
  • 215. example/ welcome.html.tt Автоматическая генерация имени шаблона
  • 217. script/app COMMAND [OPTIONS] script/app cgi script/app fastcgi script/app psgi script/app daemon script/app daemon_prefork
  • 218. script/app COMMAND [OPTIONS] script/app get script/app test script/app routes
  • 219. Mojolicious::Lite use base 'Mojolicious';
  • 220. script/mojolicious generate lite_app lite.pl [write ] lite.pl [chmod] lite.pl 744
  • 221. use Mojolicious::Lite; get '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • 222. use Mojolicious::Lite; get '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • 223. use Mojolicious::Lite; get '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • 224. use Mojolicious::Lite; post '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • 225. use Mojolicious::Lite; any '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • 226. use Mojolicious::Lite; get '/' => (agent => qr/Firefox/) => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • 227. use Mojolicious::Lite; get '/' => 'index'; get '/:groovy' => {groovy => 42} => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • 228. use Mojolicious::Lite; get '/' => 'index'; get '/:groovy' => [groovy => qr/d+/] => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • 229. use Mojolicious::Lite; ladder sub {}; # auth get '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • 230. use Mojolicious::Lite; websocket '/echo' => sub { ... }; get '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • 231. use Mojolicious::Lite; get '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->renderer->default_handler('epl'); app->start;
  • 232. use Mojolicious::Lite; get '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • 233. __DATA__ @@ index.html.ep % layout 'funky'; Yea baby! @@ layouts/funky.html.ep <!doctype html><html> <head><title>Funky!</title></head> <body><%== content %></body> </html>
  • 234. __DATA__ @@ index.html.ep % layout 'funky'; Yea baby! @@ layouts/funky.html.ep <!doctype html><html> <head><title>Funky!</title></head> <body><%== content %></body> </html>
  • 235. lite.pl COMMAND [OPTIONS] lite.pl cgi lite.pl fastcgi lite.pl psgi lite.pl daemon lite.pl daemon_prefork
  • 236. lite.pl COMMAND [OPTIONS] lite.pl test lite.pl get lite.pl routes lite.pl inflate
  • 237. «Making hard things possible and everything fun!» Девиз Mojolicious
  • 238. «Viva la revolution!» Девиз Mojolicious #2
  • 239. «Duct tape for the HTML5 web» Девиз Mojolicious #3
  • 240. Mojolicious-модули на CPAN • Mojolicious • MojoX::Routes::AsGraph • Mojo::Server::FCGI • MojoX::Log::* • AnyEvent::Mojo • MojoX::Renderer::* • Apache::Mojo Apache2::Mojo • TT • Catalyst::Engine::Mojo • CTTP2, HTP Squatting::On::Mojo • XSLT
  • 241. Mojolicious-модули на CPAN • Mojolicious • MojoX::Routes::AsGraph • Mojo::Server::FCGI • MojoX::Log::* • AnyEvent::Mojo • MojoX::Renderer::* • Apache::Mojo Apache2::Mojo • TT • Catalyst::Engine::Mojo • CTTP2, HTP Squatting::On::Mojo • XSLT
  • 242. Mojolicious-модули на CPAN • Mojolicious • MojoX::Routes::AsGraph • Mojo::Server::FCGI • MojoX::Log::* • AnyEvent::Mojo • MojoX::Renderer::* • Apache::Mojo Apache2::Mojo • TT • Catalyst::Engine::Mojo • CTTP2, HTP Squatting::On::Mojo • XSLT
  • 243. Mojolicious::Lite vs. Dancer Соревнование
  • 245. Обратная совместимость не гарантируется :) До первой стабильной версии
  • 246. Mojolicious 0.999925 Последняя версия доступна на github.com
  • 247. Документация • Пока не очень, зато очень хороший фидбек :) • Mojolicious::Lite и Mojolicious::Guides • Mojolicious Handbook на github.com @kvorg • Mojolicious FAQ на github.com @vti
  • 248. Полезная информация • http://mojolicious.org • irc://irc.perl.org/#mojo • http://groups.google.com/group/mojolicious • Github: kraih, vti, xantus • Twitter: @kraih, @vtivti, @sharifulin • Juick: @vti, @sharifulin
  • 249. «Особая разновидность современного программиста – программист, изучающий фреймворки»
  • 250. «Каждый программист должен сделать 3 вещи: фреймворк, шаблонизатор и событийную машину»
  • 251. use Mojolicious or die;
  • 253. use Perl or die;
  • 254. JFDI
  • 255. any ‘/questions’ => sub { shift->render( answer => ‘sharifulin’, ); };
  • 256. Спасибо за внимание! Это 256й слайд Анатолий Шарифулин