yatt::lite - psgi を直接サポートしたテンプレートエンジン at #plackcon

21
PSGI を直接サポートした テンプレートエンジン YATT::Lite の解説 twitter: @hkoba, CPAN: HKOBA, real: 小林 弘明

Upload: hiroaki-kobayasi

Post on 26-Dec-2014

278 views

Category:

Technology


3 download

DESCRIPTION

 

TRANSCRIPT

Page 1: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

PSGI を直接サポートしたテンプレートエンジンYATT::Lite の解説twitter: @hkoba, CPAN: HKOBA, real: 小林 弘明

Page 2: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

@hkoba プロフィール今はフリーランス(個人事業主)

Perl 屋さん募集中. Perl友達欲しいな...

hachioji.pm さんにお邪魔したり

Perl5 歴 (多分 1994?から)

学生時代に Perl/Tk (800.400?)の日本語化

Oreilly の Perl Conference に呼んでもらえた!

Page 3: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

YATT::Lite とは?

Pure Perl なテンプレートエンジン

HTML に近い構文

Perl コードへ変換、実行

テンプレートにも use strict を!

PSGI 対応な WAF も添付

大分使える、けどもっと良くしたい!

Perl友達(and/or GF)欲しいな...

Page 4: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

でも、そもそも、なんで??今さら、テンプレートエンジン?

テンプレートエンジンが PSGI WAF を?

Page 5: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

プログラマー不足だから(><)

ページ追加=テンプレート置くだけ

use strict でコピペでも安全! 戦力になれるよ!

Page 6: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

全体の動き

Frontend(Template)

Backend(Model, DB)

PSGI

thin control

entity funcs

user

Page 7: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

app.psgi の中身# -*- perl -*-sub MY () {__PACKAGE__}; # omissibleuse FindBin;use lib "$FindBin::Bin/lib";use YATT::Lite::WebMVC0::SiteApp -as_base;use YATT::Lite qw/Entity *CON/;{ my $site = MY->new(doc_root => "$FindBin::Bin/html"); Entity param => sub { my ($this, $name) = @_; $CON->param($name) }; return $site if MY->want_object; $site->to_app;}

Page 8: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

Install 方法 その1$ cpanm YATT::Lite

git submodule$ git submodule add git://github.com/hkoba/yatt_lite.git lib/YATT$ git submodule update --init

$ mkdir html$ cp lib/YATT/samples/minimum.psgi app.psgi

Page 9: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

Install 方法 その2github からスクリプトで

$ curl https://raw.github.com/hkoba/yatt_lite/dev/scripts/skels/min/install.sh | bash$ tree|head -6.├── app.psgi├── html│ └── index.yatt└── lib └── YATT ....

Page 10: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

Emacs Lisp の支援モードlib/YATT/elisp/yatt-autoload.el を load して下さい

$ emacsclient --eval '(load "'$PWD/lib/YATT/elisp/yatt-autoload.el'")'

mmm-mode を使った構文着色

保存時の lint

Page 11: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

テンプレートの解説1元の html (これを吐かせたい)

<!doctype html><html><title>Hello world</title><meta charset="utf-8"><body><h2>Hello world</h2>

My first yatt!

</body></html>

Page 12: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

YATT で DRY に分けてみるhello.yatt

<yatt:envelope title="Hello world">My first yatt!</yatt:envelope>

envelope.yatt<!yatt:args title>

<!doctype html><html><title>&yatt:title;</title><meta charset="utf-8"><body><h2>&yatt:title;</h2>

<yatt:body/>

</body></html>

Page 13: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

解説1.

ファイル名(envelope)がタグ(widget)になる

widget名を打ち間違ったら、静的エラーになる

名前付き引数(title)が使える(位置引数も)

変数参照は実体参照 &yatt:title;

打ち間違ったら(ry

詳しい構文は perldoc YATT::Lite::docs::yatt_manual

Page 14: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

どんな perl スクリプトに?../lib/YATT/scripts/yatt genperl hello.yatt の出力:

package MyApp::INST1::EntNS::hello; use strict;use warnings;use 5.010;our @ISA = qw(MyApp::INST1::EntNS);sub filename {__FILE__};

#line 1 "/home/hkoba/db/monthly/201311/plackcon/demo1/html/hello.yatt"sub render_ { my ($this, $CON) = splice @_, 0, 2; my $body = $_[0];MyApp::INST1::EntNS::envelope->render_($CON, (undef, q|Hello world|, sub { print $CON (q|My first yatt!|);})[1, 2]); print $CON ("\n");}

(少しいじってます)

Page 15: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

解説2.

タグで囲まれた部分は、暗黙のクロージャー(body)

呼び出すには <yatt:body/>

Page 16: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

envelope.yatt の変換結果package MyApp::INST1::EntNS::envelope;use strict;use warnings;use 5.010; our @ISA = qw(MyApp::INST1::EntNS);sub filename {__FILE__};#line 1 "/home/hkoba/db/monthly/201311/plackcon/demo1/html/envelope.yatt"sub render_ { my ($this, $CON) = splice @_, 0, 2;my $title = $_[0]; my $body = $_[1]; print $CON (q|<!doctype html>|, "\n"); print $CON (q|<html>|, "\n"); print $CON (q|<title>|, YATT::Lite::Util::escape($title), q|</title>|, "\n"); print $CON (q|<meta charset="utf-8">|, "\n"); print $CON (q|<body>|, "\n"); print $CON (q|<h2>|, YATT::Lite::Util::escape($title), q|</h2>|, "\n"); $body && $body->(); print $CON (q|</body></html>|); print $CON ("\n");}

Page 17: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

一ファイルにまとめても ok<!yatt:args>What?

<!yatt:page "/hello"><yatt:envelope title="Hello world">My first yatt!</yatt:envelope>

<!yatt:widget envelope title><!doctype html><html><title>&yatt:title;</title><meta charset="utf-8"><body><h2>&yatt:title;</h2><yatt:body/></body></html>

Page 18: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

Backend へのアクセスapp.psgi に Entity 関数として定義:

Entity repeat => sub { my ($this, $str, $n) = @_; ($str // "") x ($n // 0)};

呼び出し方:&yatt:repeat(foo,3);

生成コード:$this->entity_repeat("foo", 3)

Page 19: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

例:Sessionapp.psgi

# -*- perl -*-use strict;use FindBin;use lib "$FindBin::Bin/lib";use YATT::Lite::WebMVC0::SiteApp -as_base;use YATT::Lite qw/Entity *CON/;use YATT::Lite::PSGIEnv;

{ my $yatt = MY->new(doc_root => "$FindBin::Bin/html");

Entity session => sub { my ($this, $name, $default) = @_; my Env $env = $CON->env; $env->{'psgix.session'}{$name} // $default; };

Entity set_session => sub { my ($this, $name, $value) = @_; my Env $env = $CON->env; $env->{'psgix.session'}{$name} = $value; ''; };

return $yatt if MY->want_object;

Page 20: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

index.yatt<!yatt:args user><yatt:if "&yatt:user;">

set user as &yatt:user; <br> &yatt:set_session(user,:user); <a href="./">back</a>

<:yatt:else/>

<h2>Hello, &yatt:session(user,((Unknown user)));</h2> <form> User name: <input name="user"><input type="submit"> </form>

</yatt:if>

Page 21: YATT::Lite - PSGI を直接サポートしたテンプレートエンジン at #plackcon

YATT::Lite 、よろしくです!https://github.com/hkoba/yatt_liteありがとうございました!!