Perlã®Webã¢ããªã±ãŒã·ã§ã³ãã¬ãŒã ã¯ãŒã¯(Web Application Framework, 以éWAFãšçç¥)ã®äžçš®ïœ¢Amon2ã®äœ¿ãæ¹ã«ã€ããŠçŽ¹ä»ããŸã. ãã®ãã¥ãŒããªã¢ã«ã¯äºéšæ§æã«ãªã£ãŠããŸã. 第1éšãšãªããã®èšäºã§ã¯, Amon2ã®ã€ã³ã¹ããŒã«ãåæèšå®, ãããŠåºæ¬çãªæ©èœã®è§£èª¬ãè¡ããŸã. 次ã®ç¬¬2éšã§ã¯, 第1éšã§è§£èª¬ããAmon2ã®åºæ¬çãªæ©èœã䜿ã£ãŠ, ç°¡åãªã¹ã±ãžã¥ãŒã«ç®¡çãµãŒãã¹ãäœæããªãã, Amon2ã䜿ã£ãWebã¢ããªã±ãŒã·ã§ã³ã®éçºã®æµããäœéšããŠã¿ãŸã.
Amon2ã¯, @tokuhiromãããäžå¿ã«éçºãããŠãã, Perl補ã®WAFã§ã. æ§ã ãªèšèªã®æ§ã ãªWAFã®äžã§, Amon2ãã©ã®ãããªããžã·ã§ã³ã«ããã®ããèŠãŠã¿ãçºã«, Amon2ãå«ãPerlã®ä»£è¡šçãªWAFãäžå¿ã«, ãã®ïœ¢éã(æ©èœã®å å®æ§)ã§åé¡ã, è¡šã«ããŠã¿ãŸãã. (ãã ããã®è¡šã¯, ã ã㶠@papix ã®äž»èŠ³ãã¯ãã£ãŠããŸã...)
ã¯ã©ã¹ | å ·äœçãªWAF | æŠèŠ |
---|---|---|
ééçŽ | Ruby on Rails (Ruby) | åäœã§å®çµã§ãã, ãã«ã¹ã¿ãã¯ãªWAF |
äžéçŽ | Mojolicious(Perl), Catalyst (Perl), FuelPHP (PHP) | RoRçšã§ã¯ãªããé«æ©èœãªWAF |
軜éçŽ | Amon2 (Perl) | WAFãšããŠéåžžã«ã·ã³ãã«, ãã®åæ¡åŒµæ§ã«å¯ã |
è¶ è»œéçŽ | Sinatra (Ruby), Amon2::Lite (Perl) | ããŒãžæ°ãå°ãªã(2ã3)ã¢ããªã±ãŒã·ã§ã³åã |
äžã®è¡šã«ãããããã«, Amon2ã¯, WAFã®äžã§ã¯ããªã軜éãªåé¡ã«å ¥ããŸã. Ruby on Railsã®ãããªééçŽ, æãã¯Perlã®MojoliciousãPHPã®FuelPHPã®ãããªäžéçŽã®WAFã«æ¯ã¹ãŠ, Amon2ãã®ãã®ãåããŠããæ©èœã¯å°ãªãã§ã. ã·ã³ãã«ã§ã¯ãããŸãã, WAFãšããŠå¿ èŠæäœéã®æ©èœã¯åããŠããŸãã, 軜éããã«æ¡åŒµæ§ããã, ãããã¯ãã«æé©ãªWAFãæ§ç¯ããããšãåºæ¥ãŸã. ããããæå³ã§, Amon2ã¯ïœ¢WAFã®ãã¬ãŒã ã¯ãŒã¯ïœ£ãšèšãããšãåºæ¥ããããããŸãã.
ãã®ãã¥ãŒããªã¢ã«ã§ã¯, Amon2ã®åºæ¬çãªæ©èœãå©çšããªãã, ç°¡åãªã¹ã±ãžã¥ãŒã«ç®¡çã·ã¹ãã ãäœã£ãŠãããŸã. æéã®å¶çŽäž, WAF(Amon2)ãæ¡åŒµããŠãããšããéšåã«ã€ããŠã¯å²æã, å¥ã®æ©äŒã«çŽ¹ä»ããããšæããŸã.
ãã¥ãŒããªã¢ã«ã«å©çšããAmon2ã¯2015幎3æ10æ¥æç¹ã®ææ°çã§ããAmon2 6.11ãå©çšããŸã. Amon2ã¯åºæ¬çã«ã¯åŸæ¹äºææ§ãç¶æããªããéçºãé²ãã§ããã®ã§, 6.11以éã®Amon2ã§ãåäœãããšæããŸã.
å çšã®è¡šã«ããã£ãããã«, Amon2ã«æ¯ã¹ãŠ, Ruby on Railsã¯æ§ã ãªæ©èœãèªåã§æã£ãŠãããã«ã¹ã¿ãã¯ãªWAFãšèšããŸã. ãã®ãã, 垞ã«Ruby on Railsã䜿ãã°ããã®ã§ã¯?ãšããæèŠãããããšæããŸãã, å人çã«ã¯WAFã¯é©æé©æã§äœ¿ãåããã¹ãã ãšæã£ãŠããŸã.
äŸãã°, Ruby on Railsã¯é«æ§èœãªä»£ããã«, ãã®é²åã¯éåžžã«æ©ãã§ã(é²åã®éãã«ã€ããŠã¯, Rubyãšããèšèªãã®ãã®ã«ãåœãŠã¯ãŸãã§ããã). åžžã«æãå ¥ãç¶ãããããã¯ãã§ããã°, ãã®é²åã«å¯Ÿå¿ããªãã, æ°ããè¿œå ãããæ©èœã䜿ãã€ã€, å¹ççã«éçºãé²ããããšãåºæ¥ãã§ããã.
ããã瀟å ããŒã«ã§ãã£ãã, æãã¯ãããã¯ãããšã³ãžãã¢ããŒã ã®æ¯æŽããããããªããŒã«(瀟å åããããã¯ã)ã§ããã°, äžæŠéçºãããã£ãåŸã¯ãããŸã§æãå ããã«, é·ã䜿ããšããå ŽåããããšæããŸã. ããããå Žåã¯, èšèªãã®ãã®ãã©ã€ãã©ãªã®åŸæ¹äºææ§ãæè(éèŠ)ããPerl補ã®WAFãæ¡çšããæ¹ã, ã»ãã¥ãªãã£ãã£ãã¯ã¹ãªã©ã«ããèšèª/ã¢ãžã¥ãŒã«ã®æŽæ°ãå®æœãããã... ãšããèŠæ¹ãåºæ¥ãã§ããã.
...ãã®ããã«, WAF1ã€ããšã£ãŠãæ§ã ãªéžæè¢ãå¯èœã§, ããŒã ããããã¯ãã«ãšã£ãŠã®ïœ¢é©åãªæè¡éžæãšããã®ã¯éåžžã«é£ãããã®ã§ã. ãã®ç ä¿®ã®äžã§ã, ãã£ãšæ§ã ãªïœ¢æè¡éžæã®æ©äŒããããšæããŸãã®ã§, ãã®éœåºŠãã®éœåºŠ, ãã£ããèããŠãããŸããã.
Perlãã¥ãŒããªã¢ã«ã®Perlç°å¢ã®æ§ç¯å
ã®, ã¢ãžã¥ãŒã«ãšCPANãšããéšåã§, Perlã®ã¢ãžã¥ãŒã«ãã€ã³ã¹ããŒã«ããããã®cpanm
ãšããã³ãã³ããã€ã³ã¹ããŒã«ããŠããã¯ãã§ã.
$ which cpanm
/Users/username/.plenv/shims/cpanm
Amon2ãCPANã«å
¬éãããŠããã®ã§, cpanm
ã³ãã³ãããã€ã³ã¹ããŒã«ããããšãåºæ¥ãŸã.
$ cpanm Amon2
--> Working on Amon2
Fetching http://www.cpan.org/authors/id/T/TO/TOKUHIROM/Amon2-6.11.tar.gz ... OK
Configuring Amon2-6.11 ... OK
Building and testing Amon2-6.11 ... OK
Successfully installed Amon2-6.11
1 distribution installed
ããAmon2ã®äŸåã¢ãžã¥ãŒã«ãå°å
¥ãããŠããªãå Žå, cpanm
ã¯èªåçã«ãããã®ã€ã³ã¹ããŒã«ãå®è¡ããŸã.
Amon2ã䜿ã£ãWebã¢ããªã±ãŒã·ã§ã³ã®é圢ã¯, amon2-setup.pl
ã³ãã³ãããçæåºæ¥ãŸã.
$ amon2-setup.pl
% amon2-setup.pl MyApp
--flavor=Basic basic flavour (default)
--flavor=Lite Amon2::Lite flavour (need to install)
--flavor=Minimum minimalistic flavour for benchmarking
--flavor=Standalone CPAN uploadable web application(EXPERIMENTAL)
--vc=Git setup the git repository (default)
--list-flavors (or -l) Shows the list of flavors installed
--help Show this help
Amon2ã«ã¯, Sinatraã®ãããªè¶
軜éã®Amon2::Lite
ãå©çšãã, Liteãã¬ãŒããŒ(é圢ã®å
)ãçšæãããŠããŸãã, ä»åã¯Basicãã¬ãŒããŒãå©çšããŸã.
Amon2ã§äžèŠæš¡ã倧èŠæš¡ãªWebã¢ããªã±ãŒã·ã§ã³ãéçºããå Žå, Basicãã¬ãŒããŒã§é圢ãçæã, å¿
èŠã«å¿ããŠæ¹å€ããŠãã... ãšããæµããå€ãã§ã.
ããã§ã¯æ©é, é圢ãçæããŠãããŸããã.
amon2-setup.pl
ãå©çšããé圢çææã«ã¯, ãã®Webã¢ããªã±ãŒã·ã§ã³ã®ååãåŒæ°ãšããŠäžããå¿
èŠããããŸã.
ä»åã¯, ã¹ã±ãžã¥ãŒã«ç®¡çã®ã¢ããªã±ãŒã·ã§ã³ãªã®ã§, Schedulerãšããååã«ããŸãããã.
$ amon2-setup.pl Scheduler
-- Running flavor: Basic --
[main] Loading asset: jQuery
[main] Loading asset: Bootstrap
[main] Loading asset: ES5Shim
[main] Loading asset: MicroTemplateJS
[main] Loading asset: StrftimeJS
... äžç¥ ...
create mode 100644 tmpl/include/layout.tx
create mode 100644 tmpl/include/pager.tx
create mode 100644 tmpl/index.tx
create mode 100644 xt/01_pod.t
create mode 100644 xt/02_perlcritic.t
--------------------------------------------------------------
Setup script was done! You are ready to run the skelton.
You need to install the dependencies by:
> carton install
And then, run your application server:
> carton exec perl -Ilib script/scheduler-server
--------------------------------------------------------------
ã«ã¬ã³ããã£ã¬ã¯ããªã«Scheduler
ãšãããã£ãã¯ããªãçæãã, ãã®äžã«é圢ãçæãããŸãã.
é圢ã®äžèº«ã詳ããèŠãåã«, Cartonã䜿ã£ãŠäŸåã¢ãžã¥ãŒã«ãã€ã³ã¹ããŒã«ããŠãããŸããã.
Cartonã¯, Rubyã®Bundlerã®ãããªãã®ã§, Webã¢ããªã±ãŒã·ã§ã³ã®äŸåã¢ãžã¥ãŒã«ã, cpanm
ã³ãã³ãã§ã€ã³ã¹ããŒã«ããã¢ãžã¥ãŒã«ãšã¯å¥ã«ç®¡çããŠãããã¢ããªã±ãŒã·ã§ã³ã§ã.
Cartonãå©çšããã°, Webã¢ããªã±ãŒã·ã§ã³ãåäœããéã«å©çšããã©ã€ãã©ãªãšãã®ããŒãžã§ã³ãåºå®ããããšãåºæ¥ãã®ã§, éçºç°å¢ãšæ¬çªç°å¢ã§ã©ã€ãã©ãªã®ããŒãžã§ã³ã«å·®ç°ãçãããªã©ãšãã£ãäºæ
ãé²ãããšãã§ããŸã.
$ cpanm Carton
ãŸã, cpanm
ã³ãã³ãã§Cartonãã€ã³ã¹ããŒã«ããŸã.
Amon2ã®æãšåæ§, Cartonã®äŸåã¢ãžã¥ãŒã«ãèªåçã«ã€ã³ã¹ããŒã«ããŠãããŸã.
$ cd Scheduler
$ carton install
Cartonã®ã€ã³ã¹ããŒã«ãçµãã£ãã, amon2-setup.pl
ãçæããé圢ãæ ŒçŽãããŠããScheduler
ãã£ã¬ã¯ããªã«ç§»åã, carton install
ã³ãã³ãã§äŸåã¢ãžã¥ãŒã«ãã€ã³ã¹ããŒã«ããŸã.
èªåã®ç°å¢ã§ã¯, 次ã®ãããªåºåãåŸãããŸãã.
$ carton install
Installing modules using /Users/username/Scheduler/cpanfile
Successfully installed CPAN-Meta-2.150001 (upgraded from 2.140640)
Successfully installed Module-Build-0.4211 (upgraded from 0.4205)
Successfully installed URI-1.67
... äžç¥ ...
Successfully installed Test-LongString-0.17
Successfully installed Test-WWW-Mechanize-1.44
Successfully installed Test-WWW-Mechanize-PSGI-0.35
115 distributions installed
Complete! Modules were installed into /Users/username/Scheduler/local
Cartonã¯, ã¢ããªã±ãŒã·ã§ã³ã®ã«ãŒããã£ã¬ã¯ããª(ä»åã®å Žå, /Users/username/Scheduler
)ã®çŽäžã«, local
ãšãããã£ã¬ã¯ããªãçæã, ãã®äžã«äŸåã¢ãžã¥ãŒã«ãã€ã³ã¹ããŒã«ããŸã.
carton install
ã§ã€ã³ã¹ããŒã«ããã¢ãžã¥ãŒã«ãå©çšããªãã, Perlã®ã¹ã¯ãªãããåããã«ã¯, carton exec
ãå©çšããŸã.
carton exec --
ã®åŸã«, äŸãã°perl hello.pl
ãªã©, ä»»æã®Perlã¹ã¯ãªãããåããã³ãã³ããå
¥åãããš, ãã®Perlã¹ã¯ãªããã¯
local`ãã£ã¬ã¯ããªä»¥äžã®ã¢ãžã¥ãŒã«ãå©çšããªããå®è¡ããŠãããŸã.
Perlã¹ã¯ãªãããåããã³ãã³ãã§ãã, ãã®Schedulerã®å Žå, amon2-setup.pl
ã§é圢ãçæããéã«script/scheduler-server
ãšããèµ·åçšã¹ã¯ãªãããçæãããŠããã®ã§, ããã䜿ããŸã.
$ carton exec -- perl -Ilib script/scheduler-server
Scheduler: http://127.0.0.1:5000/
ãã©ãŠã¶ã§, localhost:5000
ã«ç¹ãã§ã¿ãŠäžãã.
...ãã®ãããªç»é¢ã確èªåºæ¥ãŸããã? åºæ¥ãã®ã§ããã°, Amon2ã䜿ã£ãWebã¢ããªã±ãŒã·ã§ã³ã®éçºã®, 第äžæ©ãèžã¿åºãããšãåºæ¥ãŸãã!
åäœç¢ºèªãåºæ¥ããšããã§, Amon2ã®æ§æã«ã€ããŠåŠãã§ãããŸã. Amon2ã¯, Webã¢ããªã±ãŒã·ã§ã³ã«ã€ããŠèããæã«ããåºãŠããMVC, ããªãã¡Model, View, Controllerã®ãã¡, ViewãšControllerãæäŸããWAFã§ã. Modelã«é¢ããŠã¯, ããããã䜿ãããã圢ã§å®è£ ãããšããã®ã, Amon2ã®æ¹éã«ãªã£ãŠããŸã.
ãŸãã¯Controllerã®éšåãèŠãŠè¡ããŸããã.
Schedulerã¢ããªã±ãŒã·ã§ã³ã®Controllerã¯, lib/Scheduler/Web/Dispatcher.pm
ã®éšåã«ãªããŸã.
package Scheduler::Web::Dispatcher;
use strict;
use warnings;
use utf8;
use Amon2::Web::Dispatcher::RouterBoom;
any '/' => sub {
my ($c) = @_;
my $counter = $c->session->get('counter') || 0;
$counter++;
$c->session->set('counter' => $counter);
return $c->render('index.tx', {
counter => $counter,
});
};
post '/reset_counter' => sub {
my $c = shift;
$c->session->remove('counter');
return $c->redirect('/');
};
post '/account/logout' => sub {
my ($c) = @_;
$c->session->expire();
return $c->redirect('/');
};
1;
ãã®ã³ãŒãã§ã¯, Amon2::Web::Dispatcher::RouterBoom
ãšããã¢ãžã¥ãŒã«ãæäŸããany
ãpost
ãšããã¡ãœãããå©çšããŠ, ããã¡ãœããã§ïœ£, ãããã¹ã«æ¥ç¶ããã, ããåŠçããããšããçµã¿åãããèšè¿°ããŠããŸã.
any '/' => sub {
my ($c) = @_;
my $counter = $c->session->get('counter') || 0;
$counter++;
$c->session->set('counter' => $counter);
return $c->render('index.tx', {
counter => $counter,
});
};
ãã®éšåãäžå¿ã«èŠãŠãããŸããã. ãããã, ãã, æ£ããèšæ³ãªã®?ãšæããããããŸããã, ããæžãæããŠã¿ããšã©ãã§ããã?
any ('/' => sub { ... });
any
ãšããã¡ãœããã«, '/'
ãš, sub { ... }
ãšããåŒæ°ãæž¡ããŠããèš³ã§ã.
ã¡ãªã¿ã«, sub { ... }
ã®éšåã¯, ãµãã«ãŒãã³ã®ãªãã¡ã¬ã³ã¹ã«ãªã£ãŠããŸã.
ããŠ, å çšãã®ã³ãŒãã§ã¯ïœ¢ããã¡ãœããã§ïœ£, ãããã¹ã«æ¥ç¶ããã, ããåŠçããããšããçµã¿åãããæžããŠãã, ãšæžããŸãã. ããããã®ã³ãŒãã«åœãŠã¯ãããš...
- ããã¡ãœãã :
any
(anyã¯, HTTPã®ã¡ãœããã®ãã¡, GETãšPOSTã®äž¡æ¹) - ãããã¹ :
'/'
- ããåŠç :
sub { ... }
ãšãªããŸã.
ãªã, ã¡ãœããã«ã€ããŠã¯, ããã§çŽ¹ä»ããany
ã®ä»ã«GETã¡ãœãããå©çšããæã®get
, POSTã¡ãœãããå©çšããæã®post
ãå©çšããããšãã§ããŸã.
äŸãã°...
get '/hoge/fuga' => sub { ... };
ãã®ããã«æžããå Žå, ãµãã«ãŒãã³ãªãã¡ã¬ã³ã¹ã«æžãããåŠçã¯GETã¡ãœããã§/hoge/fuga
ã«ã¢ã¯ã»ã¹ããéã«å®è¡ãããŸã. ãŸã,
post '/hoge/fuga/new' => sub { ... };
ãã®ããã«æžããå Žå, ãµãã«ãŒãã³ãªãã¡ã¬ã³ã¹ã«æžãããåŠçã¯POSTã¡ãœããã§/hoge/fuga/new
ã«ã¢ã¯ã»ã¹ããéã«å®è¡ãããŸã.
ããã§ã¯æ¬¡ã«, ãµãã«ãŒãã³ãªãã¡ã¬ã³ã¹ã®äžèº«ã«ã€ããŠè©³ããèŠãŠè¡ããŸããã.
sub {
my ($c) = @_;
my $counter = $c->session->get('counter') || 0;
$counter++;
$c->session->set('counter' => $counter);
return $c->render('index.tx', {
counter => $counter,
});
};
ããã§éèŠãªã®ã¯, $c
ã§åããŠããã³ã³ããã¹ãã§ã.
ã³ã³ããã¹ãã®éèŠæ§ã«ã€ããŠã¯, Amon2ã®äœè
ã§ããtokuhiromãããPerl Hackers Hubã§ã®ïœ¢Amon2ã«ããWebã¢ããªã±ãŒã·ã§ã³éçºã®é«ééçº(2)ã«ãããŠ, Amon2ã®äžçã§ã¯,ã³ã³ããã¹ããšãããã®ã®ååšãéåžžã«éèŠã§ããã³ã³ããã¹ããç解ããã°Amon2ã®80%ãç解ãããšèšã£ãŠãããã§ãããããšè¿°ã¹ãŠããŸã.
ãªãã³ã³ããã¹ããéèŠããšèšããš, Amon2ãå©çšããWebã¢ããªã±ãŒã·ã§ã³ã¯, ãã®$c
ããå©çšã§ããã¡ãœãããå©çšããŠçµã¿ç«ãŠãŠããå¿
èŠãããããã§ã.
ããã§ã¯, ãã®äžéšãããã§çŽ¹ä»ããŸã(ãªã, ããã§çŽ¹ä»ããã¡ãœããã¯Basicãã¬ãŒããŒã§é圢ãçæããéã«å©çšåºæ¥ããã®ã®äžéšã§ã. Amon2ãæ¡åŒµããçµæ, å©çšã§ããªããªã£ãã¡ãœããã, æ°ãã䜿ããããã«ãªã£ãã¡ãœãããããå ŽåããããŸã).
ãªã¯ãšã¹ãã«é¢ããæ å ±ãååŸããããšãã§ããŸã. ãã䜿ãã®ã¯, ãã©ãŒã ã«å ¥åãããã©ã¡ãŒã¿ãWebã¢ããªã±ãŒã·ã§ã³åŽã§ååŸããæã§ã.
<form method="POST" action="/post">
<input type="text" name="name">
<input type="submit">
</form>
ãã®ãããªHTMLããã£ãæ, Controllerã«ãããŠ
post '/post' => sub {
my ($c) = @_;
my $name = $c->req->parameters->{name};
...
};
ã®ããã«æžããš, $name
ã®äžã«ã¯, ããã¹ããã©ãŒã ã«å
¥åããæååãå
¥ããŸã.
ã¡ãªã¿ã«, $c->req->param('name')
ã§ãåãããã«ååŸããããšãåºæ¥ãŸãã, ãã®ãããªæžãæ¹ã¯è匱æ§ãæãå¯èœæ§ãããã®ã§äœ¿ããªãããã«ããŸããã: Perl åå¿è
ããŠã§ãã¢ããªã±ãŒã·ã§ã³ãæžãæã«æ°ãã€ããã¹ãããš
ã¬ã¹ãã³ã¹ãçæããŸã.
render
ã«ã€ããŠã¯, Viewã®æ©èœãšå¯æ¥ã«ç¹ããéšåãå€ãã®ã§, 詳ããã¯åŸè¿°ããŸã.
$path
ã§æå®ããå¥ã®ããŒãžãžé·ç§»ããŸã(ãªãã€ã¬ã¯ã).
$c->render()
ãåæ§ã§ãã, ãããã®ã¡ãœããã¯ïœ¢å®è¡ããã¿ã€ãã³ã°ã§åŠçãããã®ã§ã¯ãªã, ãã®ã¡ãœããã®è¿ãå€ããµãã«ãŒãã³ãªãã¡ã¬ã³ã¹ã®è¿ãå€ã«ããå Žåã«é©çšããããã®ã§ã.
ãã®ãã, 次ã®ããã«æžããšæåŸ éãã®åäœãããŠãããŸãã.
sub {
my ($c) = @_;
...
$c->redirect('/'); # '/'ã«é·ç§»ãããã...
print "ok!"; # ãµãã«ãŒãã³ãªãã¡ã¬ã³ã¹ã®è¿ãå€ã¯`print "ok!"`ã®å®è¡çµæ, ããªãã¡`1`ã«ãªãã®ã§, ãªãã€ã¬ã¯ãããªã!
};
TengãšåŒã°ããO/R Mapper(ORM)ãå©çšããŠ, DBãæäœããŸã(æ£ç¢ºã«èšãã°, $c->db
ã§Tengã®ãªããžã§ã¯ããååŸããããšãåºæ¥ãã®ã§, ãããå
ã«ããŠDBãæäœããããšãã§ããŸã).
Tengã®äœ¿ãæ¹ã«ã€ããŠã®è©³çŽ°ã¯å²æããŸãã, Perl Advent Calendar Japan 2011ã®Teng Tracã詳ããã§ã.
äŸãã°, Tengã®search
ã¡ãœããã䜿ã£ãŠ, schedules
ããŒãã«ã®å
šãŠã®ã¬ã³ãŒããååŸããã«ã¯, 次ã®ããã«æžããŸã.
sub {
my ($c) = @_;
...
my @schedules = $c->db->search('schedules');
...
};
ãããŸã§Controllerã«ãããéšåã®ã³ãŒããèŠãŠããŸãã. ç¶ããŠViewã«ã€ããŠèŠãŠè¡ããŸããã.
Webã¢ããªã±ãŒã·ã§ã³ã¯, ãŠãŒã¶(ã®ãã©ãŠã¶)ãããªã¯ãšã¹ãããããš, ãããåŠçããŠ, HTMLãã¬ã³ããªã³ã°ããŠè¿ããŸã. ãã®èŸºãã®åŠçãæ ãã®ã, Viewã®åœ¹å²ã§ã. 倧éæãªèª¬æã«ãªããŸãã, Viewã¯ïœ¢Controllerããããã£ããã©ã¡ãŒã¿ã䜿ã£ãŠ, HTMLãé©åã«æç»ããéšåãæ ã£ãŠãã, ãšæãã°è¯ãã§ããã.
sub {
my ($c) = @_;
my $counter = $c->session->get('counter') || 0;
$counter++;
$c->session->set('counter' => $counter);
return $c->render('index.tx', {
counter => $counter,
});
};
ãããŸã§èŠãŠããControllerã®ãµãã«ãŒãã³ãªãã¡ã¬ã³ã¹ã®äžã«ãããŠ, $c->render
ã®éšåã§HTMLãã¬ã³ããªã³ã°ããŠããŸã.
ãã®render
ã¡ãœããã¯, 2ã€ã®åŒæ°ãæã¡ãŸã. 第1åŒæ°ãã¬ã³ããªã³ã°æã«äœ¿ããã³ãã¬ãŒãã®æå®ã§, 第2åŒæ°ã¯ãã³ãã¬ãŒãã«äžãããã©ã¡ãŒã¿ã§ã.
次ã«, ãã®ãµãã«ãŒãã³ãªãã¡ã¬ã³ã¹ã§äœ¿ãããŠãã, index.tx
ãšãããã³ãã¬ãŒããèŠãŠã¿ãŸããã.
ãã³ãã¬ãŒãã¯, Webã¢ããªã±ãŒã·ã§ã³ã®ã«ãŒãã«ããtmpl
ãã£ã¬ã¯ããªã®äžã«ãããŸã.
: cascade "include/layout.tx"
: override content -> {
<h1 style="padding: 70px; text-align: center; font-size: 80px; line-height: 1; letter-spacing: -2px;">Hello, Amon2 world!</h1>
... äžç¥ ...
<h2>Session counter demo</h2>
<p>You seen this page <: $counter :> times.</p>
<form method="post" action="/reset_counter">
<input type="submit" name="Reset counter." class="btn btn-default">
</form>
: }
Amon2ã§ã¯, ãã³ãã¬ãŒããšã³ãžã³ãšããŠText::Xslateã䜿ã£ãŠããŸã. Text::Xslateã¯, @__gfx__ãããéçºãã, Perlçæéã®ãã³ãã¬ãŒããšã³ãžã³ã§ã. éããšé«æ§èœããå Œãåãããã³ãã¬ãŒããšã³ãžã³ã§, Perlã§Webã¢ããªã±ãŒã·ã§ã³ãéçºããã®ã§ããã°, ãã®ãã³ãã¬ãŒããšã³ãžã³ã䜿ã£ãŠããã°ãŸãééãã¯ãªãã§ããã.
Text::Xslateã«ã¯, ããã€ãã®ã·ã³ã¿ãã¯ã¹ããããŸãã, ä»åã¯ããã©ã«ãã®Kolonãå©çšããŸã. 詳ãã䜿ãæ¹ã¯, Text::Xslate::Syntax::Kolonã®POD(ããã¥ã¡ã³ã)ãèŠããšè¯ãã§ããã.
ããã§ã¯, ãã®äžã§ãéèŠãã€æçšãªcascade/overrideãšå€æ°ã®å±éã«ã€ããŠã ã説æããŠãããŸã.
: cascade "include/layout.tx"
: override content -> {
...
: }
ãŸããã®éšåã§ãã, cascade/overrideã®éšåã§ã.
ç°¡åã«èšãã°: override content -> {
ãã: }
ã§å²ãŸããéšåã, include/layout.tx
ã®<: block content -> { } :>
ã®éšåã«åã蟌ã, ãšããæå³ã«ãªããŸã.
ãã®ããã«æžãããšã§, äŸãã°HTMLã®ãããã, WebãµãŒãã¹ã®ããã²ãŒã·ã§ã³ããŒã®éšåãå
±éåããããšãåºæ¥ãŸã(詳ããã¯, tmpl/include/layout.tx
ãèŠãŠã¿ãŸããã).
次ã«å€æ°ã®å±éã®éšåã§ãã, ãã³ãã¬ãŒãå éšã«æ¬¡ã®ãããªéšåããããšæããŸã.
<p>You seen this page <: $counter :> times.</p>
ãã®, <: $counter :>
ã®éšåã§, å
çšrender
ã¡ãœããã§æž¡ãããã©ã¡ãŒã¿ãå±éããããšãã§ããŸã.
return $c->render('index.tx', {
counter => $counter,
});
ãã®, counter
ãšããããŒã«çŽä»ããå€ãå±éãããŸã.
äŸãã°, $counter
ã3ã§ããã°...
<p>You seen this page 3 times.</p>
ã®ããã«HTMLã¯ã¬ã³ããªã³ã°ãããŸã.
index.tx
ã, 次ã®ããã«æžãæããŠã·ã³ãã«ã«ããŸããã.
: cascade "include/layout.tx"
: override content -> {
<h1 style="padding: 70px; text-align: center; font-size: 80px; line-height: 1; letter-spacing: -2px;">Scheduler</h1>
: }
ãŸã, ããã«ãã£ãŠControllerã«ããã/reset_counter
ã/account/logout
ãšãã£ããã¹ãžã®åŠçã¯äžèŠã«ãªããŸãã.
ãããã®ã³ãŒããåé€ã, Controller(Scheduler/Web/Dispatcher.pm
)ã®ã³ãŒãã, GETã¡ãœããã§ïœ£, /
ã«ã¢ã¯ã»ã¹ãããšã, index.tx
ãã¬ã³ããªã³ã°ãããšããã³ãŒãã ããå«ãããã«æžãæããŸããã.
GETã¡ãœããã§'/user'
ã«ã¢ã¯ã»ã¹ããæ, èªåã®ãããã£ãŒã«(åå, 趣å³, 幎霢, åºèº«æ ¡ãªã©...)ã衚瀺ããããã«, ãã³ãã¬ãŒã(tmpl/user.tx
)ãäœæã, Controllerã«ãããŠå¿
èŠãªã³ãŒããçšæããŠã¿ãŸããã.
ãªã, ãããã£ãŒã«ã®å ·äœçãªãã©ã¡ãŒã¿ã«ã€ããŠã¯, ãã³ãã¬ãŒãã«çŽæ¥æžãã®ã§ã¯ãªã, Controllerããæž¡ããŠ, ã¬ã³ããªã³ã°ããããã«ããŸããã.
-> Amon2å ¥é (第2éš)ã«ç¶ã