SlideShare uma empresa Scribd logo
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й слайд
     Анатолий Шарифулин

Mais conteúdo relacionado

Mais procurados

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
FITC
 
RESTful APIs: Promises & lies
RESTful APIs: Promises & liesRESTful APIs: Promises & lies
RESTful APIs: Promises & lies
Tareque Hossain
 
CO2 sequestration in a different manner
CO2 sequestration in a different mannerCO2 sequestration in a different manner
CO2 sequestration in a different manner
Green 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 CakePHP
ichikaway
 
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
Jonas 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, Lessons
Dirk Roorda
 
PHP Tutorial (funtion)
PHP Tutorial (funtion)PHP Tutorial (funtion)
PHP Tutorial (funtion)
Tinnakorn Puttha
 
Concept History
Concept HistoryConcept History
Concept History
jonphipps
 
Getting started with MongoDB and PHP
Getting started with MongoDB and PHPGetting started with MongoDB and PHP
Getting started with MongoDB and PHP
gates10gen
 
PHP 1
PHP 1PHP 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
Chris Reynolds
 
Missing kids on you
Missing kids on youMissing kids on you
Missing kids on you
guest3fa681
 
Forbes MongoNYC 2011
Forbes MongoNYC 2011Forbes MongoNYC 2011
Forbes MongoNYC 2011
djdunlop
 
Yql && Raphaël
Yql && RaphaëlYql && Raphaël
Yql && Raphaël
Lachlan Hardy
 
PHP 5.4
PHP 5.4PHP 5.4
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
 

Mais procurados (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
 
Yql && Raphaël
Yql && RaphaëlYql && Raphaël
Yql && Raphaël
 
PHP 5.4
PHP 5.4PHP 5.4
PHP 5.4
 
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]
 

Destaque

Mojo. The web in a box!
Mojo. The web in a box!Mojo. The web in a box!
Mojo. The web in a box!
Anatoly Sharifulin
 
Guitar Hero, Wikipedia, VK, Perl, Like it!
Guitar Hero, Wikipedia, VK, Perl, Like it!Guitar Hero, Wikipedia, VK, Perl, Like it!
Guitar Hero, Wikipedia, VK, Perl, Like it!
Anatoly Sharifulin
 
Ae internals
Ae internalsAe internals
Ae internals
mnikolenko
 
Введение в веб-технологии. Лекция.
Введение в веб-технологии. Лекция. Введение в веб-технологии. Лекция.
Введение в веб-технологии. Лекция.
Rauf Aliev
 
Perepelitsa
PerepelitsaPerepelitsa
Perepelitsa
kuchinskaya
 
Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...
Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...
Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...
Moscow.pm
 
О работе с документами .xls, .xlsx, .rtf
О работе с документами .xls, .xlsx, .rtfО работе с документами .xls, .xlsx, .rtf
О работе с документами .xls, .xlsx, .rtf
Moscow.pm
 

Destaque (8)

Mojo. The web in a box!
Mojo. The web in a box!Mojo. The web in a box!
Mojo. The web in a box!
 
Guitar Hero, Wikipedia, VK, Perl, Like it!
Guitar Hero, Wikipedia, VK, Perl, Like it!Guitar Hero, Wikipedia, VK, Perl, Like it!
Guitar Hero, Wikipedia, VK, Perl, Like it!
 
Ae internals
Ae internalsAe internals
Ae internals
 
Введение в веб-технологии. Лекция.
Введение в веб-технологии. Лекция. Введение в веб-технологии. Лекция.
Введение в веб-технологии. Лекция.
 
Kharkov
KharkovKharkov
Kharkov
 
Perepelitsa
PerepelitsaPerepelitsa
Perepelitsa
 
Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...
Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...
Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...
 
О работе с документами .xls, .xlsx, .rtf
О работе с документами .xls, .xlsx, .rtfО работе с документами .xls, .xlsx, .rtf
О работе с документами .xls, .xlsx, .rtf
 

Semelhante a Mojolicious. Веб в коробке!

анатолий шарифулин Mojolicious финальная версия
анатолий шарифулин Mojolicious   финальная версияанатолий шарифулин Mojolicious   финальная версия
анатолий шарифулин Mojolicious финальная версия
rit2010
 
Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!
Anatoly Sharifulin
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
Yusuke Wada
 
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
Jens-Christian Fischer
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
Flavio Poletti
 
Mojolicious
MojoliciousMojolicious
Mojolicious
Marcos Rebelo
 
PHP Basics and Demo HackU
PHP Basics and Demo HackUPHP Basics and Demo HackU
PHP Basics and Demo HackU
Anshu Prateek
 
ApacheCon 2005
ApacheCon 2005ApacheCon 2005
ApacheCon 2005
Adam Trachtenberg
 
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 help
AWSCOMSUM
 
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
iMasters
 
Working with web_services
Working with web_servicesWorking with web_services
Working with web_services
Lorna Mitchell
 
SINATRA + HAML + TWITTER
SINATRA + HAML + TWITTERSINATRA + HAML + TWITTER
SINATRA + HAML + TWITTER
Elber 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 Generators
Mark Baker
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
Fabien Potencier
 
Bioinformatica p6-bioperl
Bioinformatica p6-bioperlBioinformatica p6-bioperl
Bioinformatica p6-bioperl
Prof. Wim Van Criekinge
 
InnoDB Magic
InnoDB MagicInnoDB Magic
InnoDB Magic
sunnygleason
 
Generated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 GeneratorsGenerated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 Generators
Mark Baker
 

Semelhante 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
 

Mais de Anatoly Sharifulin

Ещё один способ привлекать и удерживать пользователей в играх
Ещё один способ привлекать и удерживать пользователей в играхЕщё один способ привлекать и удерживать пользователей в играх
Ещё один способ привлекать и удерживать пользователей в играх
Anatoly Sharifulin
 
ASO Аудит для приложений и игр
ASO Аудит для приложений и игрASO Аудит для приложений и игр
ASO Аудит для приложений и игр
Anatoly Sharifulin
 
ASO для iOS 11 (продвижение In-App Prurchases)
ASO для iOS 11 (продвижение In-App Prurchases)ASO для iOS 11 (продвижение In-App Prurchases)
ASO для iOS 11 (продвижение In-App Prurchases)
Anatoly Sharifulin
 
ASO для iOS 11
ASO для iOS 11ASO для iOS 11
ASO для iOS 11
Anatoly Sharifulin
 
AppFollow митап в Москве
AppFollow митап в МосквеAppFollow митап в Москве
AppFollow митап в Москве
Anatoly Sharifulin
 
ASO Best Practices 2016
ASO Best Practices 2016ASO Best Practices 2016
ASO Best Practices 2016
Anatoly Sharifulin
 
То, что русскому — ФРИИ, финну — Startup Sauna. Опыт прохождения акселерации ...
То, что русскому — ФРИИ, финну — Startup Sauna. Опыт прохождения акселерации ...То, что русскому — ФРИИ, финну — Startup Sauna. Опыт прохождения акселерации ...
То, что русскому — ФРИИ, финну — Startup Sauna. Опыт прохождения акселерации ...
Anatoly Sharifulin
 
Аналитика приложений конкурентов в Google Play
Аналитика приложений конкурентов в Google PlayАналитика приложений конкурентов в Google Play
Аналитика приложений конкурентов в Google Play
Anatoly Sharifulin
 
ASO FAQ
ASO FAQASO FAQ
ASO: Best Practices 2015
ASO: Best Practices 2015ASO: Best Practices 2015
ASO: Best Practices 2015
Anatoly Sharifulin
 
AppFollow Demo Day ФРИИ
AppFollow Demo Day ФРИИAppFollow Demo Day ФРИИ
AppFollow Demo Day ФРИИ
Anatoly Sharifulin
 
Конкурентный анализ мобильных приложений
Конкурентный анализ мобильных приложенийКонкурентный анализ мобильных приложений
Конкурентный анализ мобильных приложений
Anatoly Sharifulin
 
Аналитика приложений конкурентов
Аналитика приложений конкурентовАналитика приложений конкурентов
Аналитика приложений конкурентов
Anatoly Sharifulin
 
Аналитика магазинов приложений
Аналитика магазинов приложенийАналитика магазинов приложений
Аналитика магазинов приложений
Anatoly Sharifulin
 
Аналитика мобильных приложений
Аналитика мобильных приложенийАналитика мобильных приложений
Аналитика мобильных приложений
Anatoly Sharifulin
 
Анализ приложений конкурентов
Анализ приложений конкурентовАнализ приложений конкурентов
Анализ приложений конкурентов
Anatoly Sharifulin
 
ASO оптимизация мобильных приложений: «Что такое хорошо и что такое плохо?»
ASO оптимизация мобильных приложений: «Что такое хорошо и что такое плохо?»ASO оптимизация мобильных приложений: «Что такое хорошо и что такое плохо?»
ASO оптимизация мобильных приложений: «Что такое хорошо и что такое плохо?»
Anatoly Sharifulin
 
Продвижение мобильных приложений: с чего начать?
Продвижение мобильных приложений: с чего начать?Продвижение мобильных приложений: с чего начать?
Продвижение мобильных приложений: с чего начать?
Anatoly Sharifulin
 
Основной продукт vs. мобильный на примере Ostrovok.ru
Основной продукт vs. мобильный на примере Ostrovok.ruОсновной продукт vs. мобильный на примере Ostrovok.ru
Основной продукт vs. мобильный на примере Ostrovok.ru
Anatoly Sharifulin
 
ASO оптимизация и продвижение мобильных приложений
ASO  оптимизация и продвижение мобильных приложенийASO  оптимизация и продвижение мобильных приложений
ASO оптимизация и продвижение мобильных приложений
Anatoly Sharifulin
 

Mais de Anatoly Sharifulin (20)

Ещё один способ привлекать и удерживать пользователей в играх
Ещё один способ привлекать и удерживать пользователей в играхЕщё один способ привлекать и удерживать пользователей в играх
Ещё один способ привлекать и удерживать пользователей в играх
 
ASO Аудит для приложений и игр
ASO Аудит для приложений и игрASO Аудит для приложений и игр
ASO Аудит для приложений и игр
 
ASO для iOS 11 (продвижение In-App Prurchases)
ASO для iOS 11 (продвижение In-App Prurchases)ASO для iOS 11 (продвижение In-App Prurchases)
ASO для iOS 11 (продвижение In-App Prurchases)
 
ASO для iOS 11
ASO для iOS 11ASO для iOS 11
ASO для iOS 11
 
AppFollow митап в Москве
AppFollow митап в МосквеAppFollow митап в Москве
AppFollow митап в Москве
 
ASO Best Practices 2016
ASO Best Practices 2016ASO Best Practices 2016
ASO Best Practices 2016
 
То, что русскому — ФРИИ, финну — Startup Sauna. Опыт прохождения акселерации ...
То, что русскому — ФРИИ, финну — Startup Sauna. Опыт прохождения акселерации ...То, что русскому — ФРИИ, финну — Startup Sauna. Опыт прохождения акселерации ...
То, что русскому — ФРИИ, финну — Startup Sauna. Опыт прохождения акселерации ...
 
Аналитика приложений конкурентов в Google Play
Аналитика приложений конкурентов в Google PlayАналитика приложений конкурентов в Google Play
Аналитика приложений конкурентов в Google Play
 
ASO FAQ
ASO FAQASO FAQ
ASO FAQ
 
ASO: Best Practices 2015
ASO: Best Practices 2015ASO: Best Practices 2015
ASO: Best Practices 2015
 
AppFollow Demo Day ФРИИ
AppFollow Demo Day ФРИИAppFollow Demo Day ФРИИ
AppFollow Demo Day ФРИИ
 
Конкурентный анализ мобильных приложений
Конкурентный анализ мобильных приложенийКонкурентный анализ мобильных приложений
Конкурентный анализ мобильных приложений
 
Аналитика приложений конкурентов
Аналитика приложений конкурентовАналитика приложений конкурентов
Аналитика приложений конкурентов
 
Аналитика магазинов приложений
Аналитика магазинов приложенийАналитика магазинов приложений
Аналитика магазинов приложений
 
Аналитика мобильных приложений
Аналитика мобильных приложенийАналитика мобильных приложений
Аналитика мобильных приложений
 
Анализ приложений конкурентов
Анализ приложений конкурентовАнализ приложений конкурентов
Анализ приложений конкурентов
 
ASO оптимизация мобильных приложений: «Что такое хорошо и что такое плохо?»
ASO оптимизация мобильных приложений: «Что такое хорошо и что такое плохо?»ASO оптимизация мобильных приложений: «Что такое хорошо и что такое плохо?»
ASO оптимизация мобильных приложений: «Что такое хорошо и что такое плохо?»
 
Продвижение мобильных приложений: с чего начать?
Продвижение мобильных приложений: с чего начать?Продвижение мобильных приложений: с чего начать?
Продвижение мобильных приложений: с чего начать?
 
Основной продукт vs. мобильный на примере Ostrovok.ru
Основной продукт vs. мобильный на примере Ostrovok.ruОсновной продукт vs. мобильный на примере Ostrovok.ru
Основной продукт vs. мобильный на примере Ostrovok.ru
 
ASO оптимизация и продвижение мобильных приложений
ASO  оптимизация и продвижение мобильных приложенийASO  оптимизация и продвижение мобильных приложений
ASO оптимизация и продвижение мобильных приложений
 

Último

BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
Nguyen Thanh Tu Collection
 
বাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdf
বাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdfবাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdf
বাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdf
eBook.com.bd (প্রয়োজনীয় বাংলা বই)
 
Gender and Mental Health - Counselling and Family Therapy Applications and In...
Gender and Mental Health - Counselling and Family Therapy Applications and In...Gender and Mental Health - Counselling and Family Therapy Applications and In...
Gender and Mental Health - Counselling and Family Therapy Applications and In...
PsychoTech Services
 
Temple of Asclepius in Thrace. Excavation results
Temple of Asclepius in Thrace. Excavation resultsTemple of Asclepius in Thrace. Excavation results
Temple of Asclepius in Thrace. Excavation results
Krassimira Luka
 
IGCSE Biology Chapter 14- Reproduction in Plants.pdf
IGCSE Biology Chapter 14- Reproduction in Plants.pdfIGCSE Biology Chapter 14- Reproduction in Plants.pdf
IGCSE Biology Chapter 14- Reproduction in Plants.pdf
Amin Marwan
 
The basics of sentences session 6pptx.pptx
The basics of sentences session 6pptx.pptxThe basics of sentences session 6pptx.pptx
The basics of sentences session 6pptx.pptx
heathfieldcps1
 
Wound healing PPT
Wound healing PPTWound healing PPT
Wound healing PPT
Jyoti Chand
 
The History of Stoke Newington Street Names
The History of Stoke Newington Street NamesThe History of Stoke Newington Street Names
The History of Stoke Newington Street Names
History of Stoke Newington
 
Your Skill Boost Masterclass: Strategies for Effective Upskilling
Your Skill Boost Masterclass: Strategies for Effective UpskillingYour Skill Boost Masterclass: Strategies for Effective Upskilling
Your Skill Boost Masterclass: Strategies for Effective Upskilling
Excellence Foundation for South Sudan
 
MARY JANE WILSON, A “BOA MÃE” .
MARY JANE WILSON, A “BOA MÃE”           .MARY JANE WILSON, A “BOA MÃE”           .
MARY JANE WILSON, A “BOA MÃE” .
Colégio Santa Teresinha
 
How to Setup Warehouse & Location in Odoo 17 Inventory
How to Setup Warehouse & Location in Odoo 17 InventoryHow to Setup Warehouse & Location in Odoo 17 Inventory
How to Setup Warehouse & Location in Odoo 17 Inventory
Celine George
 
UGC NET Exam Paper 1- Unit 1:Teaching Aptitude
UGC NET Exam Paper 1- Unit 1:Teaching AptitudeUGC NET Exam Paper 1- Unit 1:Teaching Aptitude
UGC NET Exam Paper 1- Unit 1:Teaching Aptitude
S. Raj Kumar
 
NEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptx
NEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptxNEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptx
NEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptx
iammrhaywood
 
LAND USE LAND COVER AND NDVI OF MIRZAPUR DISTRICT, UP
LAND USE LAND COVER AND NDVI OF MIRZAPUR DISTRICT, UPLAND USE LAND COVER AND NDVI OF MIRZAPUR DISTRICT, UP
LAND USE LAND COVER AND NDVI OF MIRZAPUR DISTRICT, UP
RAHUL
 
Main Java[All of the Base Concepts}.docx
Main Java[All of the Base Concepts}.docxMain Java[All of the Base Concepts}.docx
Main Java[All of the Base Concepts}.docx
adhitya5119
 
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
Nguyen Thanh Tu Collection
 
Advanced Java[Extra Concepts, Not Difficult].docx
Advanced Java[Extra Concepts, Not Difficult].docxAdvanced Java[Extra Concepts, Not Difficult].docx
Advanced Java[Extra Concepts, Not Difficult].docx
adhitya5119
 
Hindi varnamala | hindi alphabet PPT.pdf
Hindi varnamala | hindi alphabet PPT.pdfHindi varnamala | hindi alphabet PPT.pdf
Hindi varnamala | hindi alphabet PPT.pdf
Dr. Mulla Adam Ali
 
Chapter wise All Notes of First year Basic Civil Engineering.pptx
Chapter wise All Notes of First year Basic Civil Engineering.pptxChapter wise All Notes of First year Basic Civil Engineering.pptx
Chapter wise All Notes of First year Basic Civil Engineering.pptx
Denish Jangid
 
ZK on Polkadot zero knowledge proofs - sub0.pptx
ZK on Polkadot zero knowledge proofs - sub0.pptxZK on Polkadot zero knowledge proofs - sub0.pptx
ZK on Polkadot zero knowledge proofs - sub0.pptx
dot55audits
 

Último (20)

BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
 
বাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdf
বাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdfবাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdf
বাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdf
 
Gender and Mental Health - Counselling and Family Therapy Applications and In...
Gender and Mental Health - Counselling and Family Therapy Applications and In...Gender and Mental Health - Counselling and Family Therapy Applications and In...
Gender and Mental Health - Counselling and Family Therapy Applications and In...
 
Temple of Asclepius in Thrace. Excavation results
Temple of Asclepius in Thrace. Excavation resultsTemple of Asclepius in Thrace. Excavation results
Temple of Asclepius in Thrace. Excavation results
 
IGCSE Biology Chapter 14- Reproduction in Plants.pdf
IGCSE Biology Chapter 14- Reproduction in Plants.pdfIGCSE Biology Chapter 14- Reproduction in Plants.pdf
IGCSE Biology Chapter 14- Reproduction in Plants.pdf
 
The basics of sentences session 6pptx.pptx
The basics of sentences session 6pptx.pptxThe basics of sentences session 6pptx.pptx
The basics of sentences session 6pptx.pptx
 
Wound healing PPT
Wound healing PPTWound healing PPT
Wound healing PPT
 
The History of Stoke Newington Street Names
The History of Stoke Newington Street NamesThe History of Stoke Newington Street Names
The History of Stoke Newington Street Names
 
Your Skill Boost Masterclass: Strategies for Effective Upskilling
Your Skill Boost Masterclass: Strategies for Effective UpskillingYour Skill Boost Masterclass: Strategies for Effective Upskilling
Your Skill Boost Masterclass: Strategies for Effective Upskilling
 
MARY JANE WILSON, A “BOA MÃE” .
MARY JANE WILSON, A “BOA MÃE”           .MARY JANE WILSON, A “BOA MÃE”           .
MARY JANE WILSON, A “BOA MÃE” .
 
How to Setup Warehouse & Location in Odoo 17 Inventory
How to Setup Warehouse & Location in Odoo 17 InventoryHow to Setup Warehouse & Location in Odoo 17 Inventory
How to Setup Warehouse & Location in Odoo 17 Inventory
 
UGC NET Exam Paper 1- Unit 1:Teaching Aptitude
UGC NET Exam Paper 1- Unit 1:Teaching AptitudeUGC NET Exam Paper 1- Unit 1:Teaching Aptitude
UGC NET Exam Paper 1- Unit 1:Teaching Aptitude
 
NEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptx
NEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptxNEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptx
NEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptx
 
LAND USE LAND COVER AND NDVI OF MIRZAPUR DISTRICT, UP
LAND USE LAND COVER AND NDVI OF MIRZAPUR DISTRICT, UPLAND USE LAND COVER AND NDVI OF MIRZAPUR DISTRICT, UP
LAND USE LAND COVER AND NDVI OF MIRZAPUR DISTRICT, UP
 
Main Java[All of the Base Concepts}.docx
Main Java[All of the Base Concepts}.docxMain Java[All of the Base Concepts}.docx
Main Java[All of the Base Concepts}.docx
 
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
 
Advanced Java[Extra Concepts, Not Difficult].docx
Advanced Java[Extra Concepts, Not Difficult].docxAdvanced Java[Extra Concepts, Not Difficult].docx
Advanced Java[Extra Concepts, Not Difficult].docx
 
Hindi varnamala | hindi alphabet PPT.pdf
Hindi varnamala | hindi alphabet PPT.pdfHindi varnamala | hindi alphabet PPT.pdf
Hindi varnamala | hindi alphabet PPT.pdf
 
Chapter wise All Notes of First year Basic Civil Engineering.pptx
Chapter wise All Notes of First year Basic Civil Engineering.pptxChapter wise All Notes of First year Basic Civil Engineering.pptx
Chapter wise All Notes of First year Basic Civil Engineering.pptx
 
ZK on Polkadot zero knowledge proofs - sub0.pptx
ZK on Polkadot zero knowledge proofs - sub0.pptxZK on Polkadot zero knowledge proofs - sub0.pptx
ZK on Polkadot zero knowledge proofs - sub0.pptx
 

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й слайд Анатолий Шарифулин