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

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

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
 
Введение в веб-технологии. Лекция.
Введение в веб-технологии. Лекция. Введение в веб-технологии. Лекция.
Введение в веб-технологии. Лекция. Rauf Aliev
 
Ленивые итераторы для разбора разнородных данных. Михаил Озеров. 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, .rtfMoscow.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
 
Beyond HTML - Scriptsprachen, Frameworks, Templatesprachen und vieles mehr
Beyond HTML - Scriptsprachen, Frameworks, Templatesprachen und vieles mehrBeyond HTML - Scriptsprachen, Frameworks, Templatesprachen und vieles mehr
Beyond HTML - Scriptsprachen, Frameworks, Templatesprachen und vieles mehrJens-Christian Fischer
 
PHP Basics and Demo HackU
PHP Basics and Demo HackUPHP Basics and Demo HackU
PHP Basics and Demo HackUAnshu Prateek
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server Masahiro Nagano
 
Ben Bridts - $ aws help
Ben Bridts -  $ aws helpBen Bridts -  $ aws help
Ben Bridts - $ aws helpAWSCOMSUM
 
PHP Experience 2016 - [Workshop] Elastic Search: Turbinando sua aplicação PHP
PHP Experience 2016 - [Workshop] Elastic Search: Turbinando sua aplicação PHPPHP Experience 2016 - [Workshop] Elastic Search: Turbinando sua aplicação PHP
PHP Experience 2016 - [Workshop] Elastic Search: Turbinando sua aplicação PHPiMasters
 
Working with web_services
Working with web_servicesWorking with web_services
Working with web_servicesLorna Mitchell
 
SINATRA + HAML + TWITTER
SINATRA + HAML + TWITTERSINATRA + HAML + TWITTER
SINATRA + HAML + TWITTERElber Ribeiro
 
Ch1(introduction to php)
Ch1(introduction to php)Ch1(introduction to php)
Ch1(introduction to php)Chhom Karath
 
FizzBuzzではじめるテスト
FizzBuzzではじめるテストFizzBuzzではじめるテスト
FizzBuzzではじめるテストMasashi Shinbara
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP GeneratorsMark Baker
 
Generated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 GeneratorsGenerated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 GeneratorsMark Baker
 

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
 
AppFollow митап в Москве
AppFollow митап в МосквеAppFollow митап в Москве
AppFollow митап в МосквеAnatoly Sharifulin
 
То, что русскому — ФРИИ, финну — Startup Sauna. Опыт прохождения акселерации ...
То, что русскому — ФРИИ, финну — Startup Sauna. Опыт прохождения акселерации ...То, что русскому — ФРИИ, финну — Startup Sauna. Опыт прохождения акселерации ...
То, что русскому — ФРИИ, финну — Startup Sauna. Опыт прохождения акселерации ...Anatoly Sharifulin
 
Аналитика приложений конкурентов в Google Play
Аналитика приложений конкурентов в Google PlayАналитика приложений конкурентов в Google Play
Аналитика приложений конкурентов в Google PlayAnatoly 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.ruAnatoly 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

TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...Nguyen Thanh Tu Collection
 
Seal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptxSeal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptxnegromaestrong
 
Python Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docxPython Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docxRamakrishna Reddy Bijjam
 
Making communications land - Are they received and understood as intended? we...
Making communications land - Are they received and understood as intended? we...Making communications land - Are they received and understood as intended? we...
Making communications land - Are they received and understood as intended? we...Association for Project Management
 
How to Manage Global Discount in Odoo 17 POS
How to Manage Global Discount in Odoo 17 POSHow to Manage Global Discount in Odoo 17 POS
How to Manage Global Discount in Odoo 17 POSCeline George
 
Application orientated numerical on hev.ppt
Application orientated numerical on hev.pptApplication orientated numerical on hev.ppt
Application orientated numerical on hev.pptRamjanShidvankar
 
Spellings Wk 3 English CAPS CARES Please Practise
Spellings Wk 3 English CAPS CARES Please PractiseSpellings Wk 3 English CAPS CARES Please Practise
Spellings Wk 3 English CAPS CARES Please PractiseAnaAcapella
 
Basic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptxBasic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptxDenish Jangid
 
psychiatric nursing HISTORY COLLECTION .docx
psychiatric  nursing HISTORY  COLLECTION  .docxpsychiatric  nursing HISTORY  COLLECTION  .docx
psychiatric nursing HISTORY COLLECTION .docxPoojaSen20
 
1029-Danh muc Sach Giao Khoa khoi 6.pdf
1029-Danh muc Sach Giao Khoa khoi  6.pdf1029-Danh muc Sach Giao Khoa khoi  6.pdf
1029-Danh muc Sach Giao Khoa khoi 6.pdfQucHHunhnh
 
Food safety_Challenges food safety laboratories_.pdf
Food safety_Challenges food safety laboratories_.pdfFood safety_Challenges food safety laboratories_.pdf
Food safety_Challenges food safety laboratories_.pdfSherif Taha
 
This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.christianmathematics
 
Unit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxUnit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxVishalSingh1417
 
On National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsOn National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsMebane Rash
 
Mixin Classes in Odoo 17 How to Extend Models Using Mixin Classes
Mixin Classes in Odoo 17  How to Extend Models Using Mixin ClassesMixin Classes in Odoo 17  How to Extend Models Using Mixin Classes
Mixin Classes in Odoo 17 How to Extend Models Using Mixin ClassesCeline George
 
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptxMaritesTamaniVerdade
 
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdfUGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdfNirmal Dwivedi
 
How to Create and Manage Wizard in Odoo 17
How to Create and Manage Wizard in Odoo 17How to Create and Manage Wizard in Odoo 17
How to Create and Manage Wizard in Odoo 17Celine George
 
Magic bus Group work1and 2 (Team 3).pptx
Magic bus Group work1and 2 (Team 3).pptxMagic bus Group work1and 2 (Team 3).pptx
Magic bus Group work1and 2 (Team 3).pptxdhanalakshmis0310
 

Último (20)

TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
 
Seal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptxSeal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptx
 
Python Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docxPython Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docx
 
Making communications land - Are they received and understood as intended? we...
Making communications land - Are they received and understood as intended? we...Making communications land - Are they received and understood as intended? we...
Making communications land - Are they received and understood as intended? we...
 
How to Manage Global Discount in Odoo 17 POS
How to Manage Global Discount in Odoo 17 POSHow to Manage Global Discount in Odoo 17 POS
How to Manage Global Discount in Odoo 17 POS
 
Application orientated numerical on hev.ppt
Application orientated numerical on hev.pptApplication orientated numerical on hev.ppt
Application orientated numerical on hev.ppt
 
Spellings Wk 3 English CAPS CARES Please Practise
Spellings Wk 3 English CAPS CARES Please PractiseSpellings Wk 3 English CAPS CARES Please Practise
Spellings Wk 3 English CAPS CARES Please Practise
 
Basic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptxBasic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptx
 
psychiatric nursing HISTORY COLLECTION .docx
psychiatric  nursing HISTORY  COLLECTION  .docxpsychiatric  nursing HISTORY  COLLECTION  .docx
psychiatric nursing HISTORY COLLECTION .docx
 
1029-Danh muc Sach Giao Khoa khoi 6.pdf
1029-Danh muc Sach Giao Khoa khoi  6.pdf1029-Danh muc Sach Giao Khoa khoi  6.pdf
1029-Danh muc Sach Giao Khoa khoi 6.pdf
 
Food safety_Challenges food safety laboratories_.pdf
Food safety_Challenges food safety laboratories_.pdfFood safety_Challenges food safety laboratories_.pdf
Food safety_Challenges food safety laboratories_.pdf
 
This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.
 
Unit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxUnit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptx
 
On National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsOn National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan Fellows
 
Mixin Classes in Odoo 17 How to Extend Models Using Mixin Classes
Mixin Classes in Odoo 17  How to Extend Models Using Mixin ClassesMixin Classes in Odoo 17  How to Extend Models Using Mixin Classes
Mixin Classes in Odoo 17 How to Extend Models Using Mixin Classes
 
Asian American Pacific Islander Month DDSD 2024.pptx
Asian American Pacific Islander Month DDSD 2024.pptxAsian American Pacific Islander Month DDSD 2024.pptx
Asian American Pacific Islander Month DDSD 2024.pptx
 
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
 
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdfUGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
 
How to Create and Manage Wizard in Odoo 17
How to Create and Manage Wizard in Odoo 17How to Create and Manage Wizard in Odoo 17
How to Create and Manage Wizard in Odoo 17
 
Magic bus Group work1and 2 (Team 3).pptx
Magic bus Group work1and 2 (Team 3).pptxMagic bus Group work1and 2 (Team 3).pptx
Magic bus Group work1and 2 (Team 3).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й слайд Анатолий Шарифулин