The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

yatt_manual(ja) -- 構文マニュアル (日本語版)

Overview

yatt のテンプレートは、通常の HTML に、 指定した名前空間 で始まる構文要素を埋め込んだ形式で記述します。 (以下の説明では名前空間 yatt を用います。)

  • <!yatt:...>

    宣言 (部品の始まり)

  • &yatt:...;

    変数や entity の参照

  • <yatt:.../>, <yatt:...> ~ </yatt:...>

    部品(widget) の呼び出し

  • <:yatt:.../> ~, <:yatt:...> ~ </:yatt:...>

    部品(widget) への引数(タグ形式)

  • <?yatt ... ?>

    ロジックを直接埋め込みたい時

  • &yatt[[; ... &yatt]];

  • &yatt#num[[; ...singular... &yatt||; ...plural... &yatt]];

    多国語化メッセージ

  • <!--#yatt ... -->

    コメント. この部分は yatt の解析対象外。

テンプレートの構文は XML に似ていますが、XML よりも再帰性を改善した、 よりテンプレート用途向きの独自構文 LRXML を採用しています。

Files

*.yatt

public な (ユーザに見せたい)テンプレートのファイル名には拡張子 .yatt をつけて下さい。

*.ytmpl

private な (ユーザに見せる予定の無い)テンプレートには拡張子 .ytmpl をつけてください。

.htyattconfig.xhf

ディレクトリ毎の設定パラメータを記述します。書式は XHF 形式です。 YATT::Lite::FactoryYATT::Lite を構築する時に使います。

.htyattrc.pl

ディレクトリ毎の YATT::Lite インスタンスで各種ハンドラをオーバロードしたり、 Entity を定義したい時に使います。

残念ながら、現時点では、*.ytmpl, .htyattconfig.xhf.htyattrc.pl の更新を反映させるには、 プロセスの再起動 が必要です。

YATT Declaration

yatt のテンプレートは宣言文と本文の並びです。 yatt宣言 は <!yatt:... で始まり > で終わります。

なお、宣言の中には XML と同様に -- ... --コメント を書くことが出来ます。

<!yatt:args>

テンプレート(の表す widget)に引数を渡せるようにするために使います。

  <!yatt:args x y>
  ...(以下、このテンプレートでは引数x と y が使用可能に)...

引数には "Argument Declaration" を用いて型やデフォルト値を指定することが出来ます。

また、URL Pattern を用いて, path_info の残りを引数に用いるよう指定することも出来ます。

<!yatt:widget>

yatt では一つのテンプレートの中に複数の widget を定義することが出来ます。

  <!yatt:widget foo x y>
   ...(foo の定義)...
  
  <!yatt:widget bar x y>
   ...(bar の定義)...

このようにして定義した widget は (次の "page" とは異なって) 内部的なものであり、外部からのリクエストで勝手に呼び出されることは有りません。

<!yatt:page>

public な widget を定義します。一つのテンプレートファイルで 複数の page を記述したい時に使います。 URL Pattern も指定できます。

    <h2>以下をご記入ください</h2>
    <yatt:input_form />
    
    <!yatt:page confirm>
    <h2>入力内容をご確認ください</h2>
    <yatt:input_form confirm_mode=1 />
    
    <!yatt:widget input_form confirm_mode>
    ...(入力フォーム)...

page を呼び出すには request parameter の name に "~ページ名" を指定したボタンを 押すか、 "~~" の value に ページ名を指定します。上記の confirm ページの例では

    <input type="submit" name="~confirm" value="確認画面へ進む">

あるいは

    <input type="hidden" name="~~" value="confirm">
    <input type="submit" value="確認画面へ進む">

(submit ボタンが一つしか無いときは、後者の方が安全です)

<!yatt:action>

テンプレートの中に POST 動作も記述したい時に使います。 action 部分に書けるプログラムの詳細は XXX: (未完) prog_action を参照してください

    <!yatt:page confirm>
    <h2>入力内容をご確認ください</h2>
    <yatt:input_form confirm_mode=1 />

    <!yatt:action register>
    ...(ここからperl のプログラム)...

action を呼び出すには request parameter の name に "!ページ名" を指定したボタンを 押すか、 "!!" の value に ページ名を指定します。上記の register 操作の例では

    <input type="submit" name="!register" value="登録する">

あるいは

    <input type="hidden" name="!!" value="register">
    <input type="submit" value="登録する">

Inline URL Router

yatt の args 又は page には、URL パターンを書く事が出来ます。

   <!yatt:args "/:user">
     ... &yatt:user; ...

   <!yatt:page blog="/blog/:article_id">
     ... &yatt:article_id; ...

   <!yatt:page blog_comments="/blog/:article_id/:comment_id">
     ... &yatt:article_id; ... &yatt:comment_id; ...

   <!yatt:page "/admin/:action" x y z>
     ...

パターンは yatt 宣言の中の先頭(引数よりも前)に 文字列形式 ('/...'"/...") で書きます。

パターンの前に 識別子= を加えて name="/..パターン.." の形式で書いた場合、 name が widget の名前として用いられます。 name= を省略することも可能です。この場合、URLパターンから widget 名が自動生成されます。

(パターンは必ず "/" で始まる必要が有ります。(将来の拡張のため))

(!yatt:args は (既に名前が決まっているので) name= は不要です。)

実際のルーティングでは、最初に page のパターンが上から順に試され、 最後に args のパターンが試されます。

:var - colon notation
   <!yatt:page '/authors/:id'>
   <!yatt:page '/authors/:id/edit'>
   <!yatt:page '/articles/:article_id/comments/:id'>
'{var}' - curly notation
   <!yatt:page "/{controller}/{action}/{id}">
   <!yatt:page '/blog/{year}/{month}'>
'{var:regexp}' - curly with regexp notation
   <!yatt:page '/blog/{year:[0-9]+}/{month:[0-9]{2}}'>
'{var:named_pattern}' - curly with named pattern notation
   <!yatt:page '/blog/{year:digits}-{month:digits}'>

XXX: named_pattern の拡張方法を書かねば... 現状では変数の型名とは無関係です。

(pattern) - optional match notation

optional match, つまり, (..) にマッチする内容が無いケースも許すパターンを書きたいときに使います。

   <!yatt:args "/:article(/:comment(/:action))">

Argument Declaration

yatt の widget は引数を取ることが出来ます。引数は必ず名前を持ちます。

   <!yatt:args x y z  -- 3つの引数 x y z を宣言。-- >

また、引数には "TYPE" in 型"DEFAULT FLAG" を指定することが出来ます。

   <!yatt:args title="text?Hello world!"  -- text型, ?フラグ, デフォルト値 --
               yesno="value/0"            -- value型, /フラグ, デフォルト値 --
   >

TYPE

引数には(escapeの)型があります。型を指定しなかった場合は "text" 型として扱われます。

text

出力時に escape されます。通常はこちらを用います。

   <yatt:foo x="my x" y="my y"/>

   <!yatt:widget foo x  y="text">
     &yatt:x;
     &yatt:y;

html

引数として渡される値が、既に外側で何らかの方法で 安全な html へと escape 済みであると分かっている場合に指定します。 (なお body 引数の解説は こちら を参照してください)

  <yatt:bq>
    <h2>foo</h2>
    bar
  </yatt:bq>

   <!yatt:widget bq body=html>
   <blockquote>
      &yatt:body;
   </blockquote>

value

引数に数値など計算結果を渡したい時に使います。

   <yatt:expr_and_result expr="3 * 4" val="3 * 4"/>
   
   <!yatt:widget expr_and_result expr=text val=value>
   &yatt:expr; = &yatt:val;

list

引数としてリスト形式のデータを渡したいときに使います。

   <yatt:mymenu list="&yatt:some_db_query();"/>

   <!yatt:widget mymenu items=list>
   <ul>
   <yatt:foreach my=item list=items>
     <li>&yatt:item;</li>
   </yatt:foreach>
   </ul>

code

条件式や widget を渡したいときに使います。遅延評価されます。 widget の場合、更に引数の型指定が可能です。

  <!yatt:widget myquote  author=[code name=text url=text]>

  <yatt:foreach my=rec list="&yatt:some_db_query();">
   ...
    <yatt:author name="&yatt:rec{name};" url="&yatt:rec{url};" />
   ...
  </yatt:foreach>

XXX: attr

XXX: delegate

DEFAULT FLAG

|

値が undef, "", 0 の時はデフォルト値に置き換えられます。(perl の || に相当)

   <!yatt:args  x="| 1">

?

値が undef, "" の時はデフォルト値に置き換えられます。

   <!yatt:args  x="?foo" y="html?bar">

/

値が undef の時はデフォルト値に置き換えられます。 (perl の // に相当)

   <!yatt:args  x="value/0">

!

必ず指定しなければならない引数であることを宣言します。 この指定がある場合、引数を忘れるとコンパイルエラー扱いになります。

   <!yatt:args  title="!" x="value!">

Widget Invocation

定義した widget を呼び出すには、 <yatt:... > で始まるタグを書きます。 タグは /> で閉じる empty element 形式か、閉じタグ </yatt:... > を 使う形式、どちらでも書けます。引数は x="..." のようにタグの属性として渡すか、 後述の 属性タグ 形式で渡します。

  ...
  <yatt:foo x="hello!"/>
  ...


  <!yatt:widget foo x>
  ...foo の定義...

widget は同一ファイル内 → 同一ディレクトリ内 → 他に指定されたテンプレートディレクトリ、 の順で検索され、最初に見つかったものが使われます。この検索はコンパイル時に行われ、 見つからない場合はコンパイルエラーとなります。

widget path

別のファイルやディレクトリ内で定義された widget を呼び出す事も可能です。 この場合、パス名を : でつなげて書きます。(拡張子 .yatt は省いて下さい)

例えばファイル foo/bar.yatt の中に

    <!yatt:widget baz>
    ....

が有った場合、これを index.yatt から呼び出すには

    <yatt:foo:bar:baz/>

と書きます。

XXX: 同じ名前のファイルとディレクトリが有った場合

XXX: positional arguments

name= を省略して引数を書く話

XXX: path thru arguments

引数の右辺に bareword を渡したときの挙動

body

全ての widget は閉じタグを使う形式で呼び出すことが出来ます。

   <yatt:foo>
     bar
   </yatt:foo>

この時、閉じタグまでの間に書いた記述は、暗黙の引数 body として widget に渡されます。 body は (明示的に宣言しない限り) code 型とされます。

これを呼び出すには, entity 呼び出し形式か、widget 呼び出し形式、 どちらでも使用できます。

   &yatt:body();

   <yatt:body/>

これは最も頻繁に現れる、ブロック形式の部品を定義するときに役立ちます。

   <yatt:env title="mypage">
     ...ここに延々と本体を...
   </yatt:env>


   <!yatt:widget env title>
   <h2>&yatt:title;</h2>
   <div class="content">
     <yatt:body/>
   </div>

attribute element

閉じタグを使う <yatt:...> ... </yatt:...>形式で widget 呼び出しを書いたときは、そのタグで囲まれた body の箇所に、他の引数を特別なタグ (属性タグ) として書くことができます。 (タグ型引数) これを用いると、html 属性 の中にタグ的な記述を持ち込む必要を減らすことが 出来ます。

属性タグは、先頭が <:yatt... で始まるタグです。 (lisp の :keyword 引数のイメージです)

属性タグの書き方は二通りあり、 /> で終わる空要素を使う形式と、 </:yatt... 閉じタグを持つ形式です。

   <yatt:env>
     ...body として渡される部分...
     <:yatt:title/>
     タイトル
   </yatt:env>


   <yatt:env>
     <:yatt:title> タイトル </:yatt:title>
     ...body として渡される部分...
   </yatt:env>

BUILTIN Macro

yatt のタグは widget の呼び出しだけではなく、 他にも制御構文を表すタグにすることも出来ます。 これは yatt のマクロ機能によって実現されています。 YATT::Lite には以下のマクロが組込み定義されています。

yatt:my

局所変数を宣言・初期化したい時に使います。属性として var="初期値" を複数 書くことが出来ます。初期値を省略することも可能です。 変数に型を指定するには var:type="初期値" のように : に続けて 型名を書きます。型を指定しない場合は "text" 型になります。

  <yatt:my x=3 y=8 z />

  <yatt:my
     foo="bar"
     val:value="&yatt:x; * &yatt:y;"
  />

閉じタグを用いた場合、自動的に html 型の変数宣言となり、body に相当する部分が 値として用いられます。

  <yatt:my foo>
    <h2>foobar</h2>
  </yatt:my>

yatt:if, :yatt:else

条件分岐を記述したい時に使います。

  <yatt:if "not &yatt:x;">
   ...not x の時...
  <:yatt:else if="&yatt:x; < 10"/>
   ... x が 10 より小さい時 ...
  <:yatt:else/>
   ...その他...
  </yatt:if>

yatt:foreach

ループを書く時に使います。 list="..." にリストを作る式を渡すと、 そのリストに対してループします。 my=var でループ変数を宣言出来ます。 宣言を省略した場合は &yatt:_; が使われます。

  <yatt:foreach my=row list="&yatt:some_db_query();">
    ...DB から取り出した一行毎に...
  </yatt:foreach>

my で変数を宣言する時に型を指定するには、(変則的ですが) my:型名= のように、 my= の間に :型名 で型を指定します。

  <yatt:foreach my:list=row list="&yatt:some_db_query();">
     &yatt:row[0]; &yatt:row[1];
  </yatt:foreach>

Entity reference

&yatt から ; までの範囲は、Entity 参照式となり、テンプレートへの値の埋め込みを 記述するために使われます。 Entity 参照式には以下の要素を含めることが出来ます。

:var

変数 var を参照します。

:func(arg...)

そのディレクトリの .htyattrc.pl で定義された Entity "func" を呼び出します。

引数は , で区切って複数個書くことができます。

:hash{key}

HASH変数 hash の要素 key を参照します。

:list[ix]

配列変数 list の要素 ix を参照します。

例:

  &yatt:x;
  &yatt:sum(3,4,5);
  &yatt:dict{foo};
  &yatt:list[0];

(), {}, [] の括弧の中には、上記の : で始まる式か、 以下のいずれかの式を再帰的に書くことが出来ます。

{key,value...}

HASH リテラルを表します。

[val,val,...]

配列リテラルを表します。

(...text with matching parens...)

文字列に空白や , などを含めたい時には、全体を (...) で囲んで下さい。

  &yatt:query((select x, y from t));
=expr, (=expr)

文字列の先頭が = で始まる場合、(perl の)式として扱われます。 部分式に計算式を書きたい時に使います。

  &yatt:if(=$x<$y,yes,no);
  &yatt:if((= $x < $y),yes,no);
その他の文字列

以上いずれにも属さない文字列は、単なるテキスト値として扱われます。

現時点では ここに perl の $var 形式の変数埋め込みを書くことが許されています。

例:

  &yatt:dict{foo}{:y};
  &yatt:list[:y];
  &yatt:x[0][:y][1];
  &yatt:if(=$$list[0]or$$list[1],yes,no);
  &yatt:if(=$$list[0]*$$list[1]==24,yes,no);
  &yatt:if((=($$list[0]+$$list[1])==11),yes,no);
  &yatt:HTML(:dump([3]));
  &yatt:HTML([=3][0]);
  &yatt:HTML(=@$var);

XXX: BUILTIN Entity

XXX: dump, render, HTML, default, join, url_encode, datetime, mkhash, breakpoint site_prefix, site_config, dir_config

Processing instruction

<?perl= ... ?>

処理結果を escape して出力します。

<?perl=== ... ?>

escape せずに、生のままで結果を出力します。

<?perl ... ?>

単純に処理だけ行います。

Comment block

<!--#yatt ... --> で囲まれた範囲は yatt の解析対象から外され、 また出力にも出されません。これに対し、 #yatt を含まない普通の <!--...--> は、その通りに出力されます。

もし yatt のテンプレートにうまく動かずエラーになる箇所がある時に、 そこをコメントアウトする(字面上は残しつつ、機能はさせない、 単なるコメントにする)には、必ず #yatt のついた、 yatt のコメントを使って下さい。

Inline comment

!yatt宣言widget 呼び出しタグ, タグ型引数 の中にも、制限付きながら -- ... -- でコメントを書き入れることが出来ます(タグ内コメント)。

制限としては、「使える文字が制限される(ex. 中にタグは書けない)」、 「タグの終わり, コメントの終わり」と誤解される書き方は出来ない、があります。

タグ内コメントの例を挙げます。

  <yatt:foo id="myfoo" -- id="mybar" と書こうと思ったけどやめた -- >
    ...
  <:yatt:title  -- ここにもコメントを書けます -- />
    <h2>あれやこれや</h2>
  </yatt:foo>


  <!yatt:widget foo
     id -- id には dom id を入れて下さい, とかなんとか --
     title -- title には○○を入れて下さい... --
  >
  ...