Amon2::Lite おさらい 4. Kolon


[3.](http://qiita.com/bunzaemon/items/5b3c893bc0528dc6427e) の続き

ここでは、 `Kolon` のみの話。

`Kolon` の全容は、
http://search.cpan.org/~syohex/Text-Xslate-3.3.7/lib/Text/Xslate/Syntax/Kolon.pm

## カスケードを利用して、コードを整理する。

```
@@ index.tx
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>BL2SEQ</title>
</head>
<body>
     <h1>input</h1>
     <form method="post" action="/bl2seq">
     <textarea name="seq1" rows="15">input sequence1</textarea><br>
     <textarea name="seq2" rows="15">input sequence2</textarea><br>
     <input type="submit" value="submit" /></br>
     <p>それぞれのテキストエリアにシーケンスを入力してください。</p>
</body>
</html>

@@ result.tx
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>BL2SEQ</title>
</head>
<body>
     <h1>result</h1>
     <pre><: $result :></pre>
     <p>結果が出ました。</p>
     <form method="get" action="/">
     <input type="submit" value="了解" /></br>
     </form>  
</body>
</html>
```

html 部分は、`</head>` まではまるで同じ。本番のコードになれば、膨れ上る場所。なのに同じコードを2回も書いてる。
そう言う時にこそカスケード。
共通部分は、`index.tx` にまかせて差分だけ `result.tx` に書く。

1. `index.tx` を、違う部分だけ `Kolon` の `: block XXX -> {}` で囲む。
2. `result.tx` では、`: cascade index` した上で、`: override XXX -> {}` で上書きする。

そんな感じで記載をさっぱりさせる。

### 1. `index.tx` を、違う部分だけ、、、

```
@@ index.tx
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>BL2SEQ</title>
</head>
<body>
: block contents -> {
     <h1>input</h1>
     <form method="post" action="/bl2seq">
     <textarea name="seq1" rows="15">input sequence1</textarea><br>
     <textarea name="seq2" rows="15">input sequence2</textarea><br>
     <input type="submit" value="submit" /></br>
     <p>それぞれのテキストエリアにシーケンスを入力してください。</p>
: }
</body>
</html>
```
この場合は、 `contents` って名前のブロックにした。
行頭は、 `:` でエスケープ。

### 2. `result.tx` では、`: cascade index` した上で、、、

```
@@ result.tx
: cascade index               # カスケード宣言
: override contents -> {      # override
     <h1>result</h1>
     <pre><: $result :></pre>
     <p>結果が出ました。</p>
     <form method="get" action="/">
     <input type="submit" value="了解" /></br>
: }
```


### app.psgi

で、結果は以下の様に。


```app.psgi
use strict;
use warnings;
use Amon2::Lite;
use utf8 ;
use File::Temp qw( tempfile ) ;

sub load_config {
    +{
        'Text::Xslate' => +{
            syntax => 'Kolon',
            suffix => '.tx',
            module => undef,
            cache  => 0,
        },
    }
}

get '/' => sub { return shift->render('index.tx'); };

post '/bl2seq' => sub {
    my $c = shift;
    my ( $out_fh1, $seq1 ) = tempfile ;
    my ( $out_fh2, $seq2 ) = tempfile ;
    print { $out_fh1 } $c->req->param('seq1') ;
    print { $out_fh2 } $c->req->param('seq2') ;
    my $result = qx{/Users/bunzaemon/cmd/bin/ncbi-blast-2.2.31+/bin/blastn -query $seq1  -subject $seq2 } ;
    return $c->render('result.tx', { result => $result }); 
} ;


__PACKAGE__->to_app(handle_static => 1);

__DATA__

@@ index.tx
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>BL2SEQ</title>
</head>
<body>
: block contents -> {
     <h1>input</h1>
     <form method="post" action="/bl2seq">
     <textarea name="seq1" rows="15">input sequence1</textarea><br>
     <textarea name="seq2" rows="15">input sequence2</textarea><br>
     <input type="submit" value="submit" /></br>
     <p>それぞれのテキストエリアにシーケンスを入力してください。</p>
: }
</body>
</html>

@@ result.tx
: cascade index               # カスケード宣言
: override contents -> {      # override
     <h1>result</h1>
     <pre><: $result :></pre>
     <p>結果が出ました。</p>
     <form method="get" action="/">
     <input type="submit" value="了解" /></br>
: }

```

* `around` は、挙動にあった名前と思えないので `override` を使ってる。
* `before`, `after` で block の前後に自由に記載が出来る。
* `Kolon` のコード部分でのコメントは `#`
* html 部分で、コメントしたい時は、 `:#`[^1]

## Amon2 の Basic に移行したくなった時

余談になる。

テンプレートの app.psgi からの分離は、

### app.psgi 同階層の tmpl/ 以下に、 *.tx を置く。
```
/PATH/TO/APP/
+--app.psgi
+--tmpl/
   +--index.tx
   +--result.tx
   +--include/
(omitted)
```

- `@@` 行は書かなくていい。
- tmpl/ は自動的に見に行く
	- perl 側のコードに変更無し。
- app.psgi 側のコードは当然消す。

### カスケードしたいものは include/ へ

- Basic からは用意されてるディレクトリ
- 呼び出し元では、`::` によるパス指定で呼び出せる。

```
: cascade include::FOO
```

- include/ 中の BAR から include/ 中の FOO を呼ぶ時も `include::FOO`

### cascade with の with には、`,` 区切りで複数のテンプレートが指定出来る。

```
: cascade index with include::FOO, include::BAR
```

### 更に。

load_config 時に、`path  => []` で相対パス指定する事によって、テンプレート検索パスの追加が可能

```
sub load_config {
    +{
        'Text::Xslate' => +{
            syntax => 'Kolon',
            suffix => '.tx',
            module => undef,
            cache  => 0,
            path   => ['./tmpl/mufufu/'],
        },
    }
}
```

この場合、テンプレートは、

```
./tmpl
./tmpl/include
./tmpl/mufufu
./tmpl/mufufu/include
```

にあると見なされる。

http://search.cpan.org/~syohex/Text-Xslate-3.3.5/lib/Text/Xslate/Manual/FAQ.pod



[^1]: だけど行頭からのコメント行は、空行として html に表われるので、10行とかコメントしたらかなり間抜け。空ブロック作って、その中でコメントしまくるか。