voltエンジン
Volt は、PHPのためにCで記述されており、とても速く、デザイナにも扱いやすいテンプレート言語です。簡単にビューを書けるようにヘルパーセットも提供されており、また、Phalcon の他のコンポーネントに高度に統合されているので、コーディング量も少なく使い勝手はいいと思います。voltで書かれたコードは初回読み込み時にキャッシュとして、phpファイルにコンパイルされます。phalcon volt ドキュメントより抜粋。
voltの有効化
サービスコンテナの設定時に:$di = new Phalcon\DI\FactoryDefault();
use Phalcon\Mvc\View; // Voltをテンプレートエンジンとして登録する $di->set('view', function () { $view = new View(); $view->setViewsDir('../app/views/'); $view->registerEngines( array( ".volt" => 'Phalcon\Mvc\View\Engine\Volt' ) ); return $view; });
コントローラからビューへのデータ設定
MVCモデルではデータの取得や加工等をコントローラで行いコントローラからビューへデータを渡す必要があります。
Phalconでは以下のように2通りの書き方があります。
コントローラのアクション内で
//例えばモデルPostから取得したデータをビューへ受け渡す場合 $post = Post::findFirst(); $this->view->post = $post; //または $this->view->setVar("post", $post); //もちろん変数でなくても $this->view->name = "テスト"; //または $this->view->setVar("name", "テスト");
コントローラからセットした変数($this->view->post or $this->view->setVar(“post”, ????))をビューで利用するためには
{{ post }}
でOKです。
voltの表記
設定した変数や文字を出力する場合、{{}}
{{ post }}
制御分を扱う場合、{% %}
{% if a==b %} {% endif %}
といった感じになります。phpで書くよりコーディング量は減りますね
制御文
よく利用する制御文の利用方法と解説
変数
変数postの属性にアクセスする
voltの場合
{{ post.title }}
phpの場合
$post->title
変数postが配列のときのアクセス
voltの場合
{{ post['title'] }}
phpの場合
$post['title']
if文
if文の書き方
voltの場合
{% set a = 1 %} {% if a === 1 %} OK {% else %} ELSE {% endif %}
コンパイル後のphp
<?php $a = 1; ?> <?php if ($a === 1) { ?> OK <?php } else { ?> ELSE <?php } ?>
ループ
単純なループ
voltのforはforeachにコンパイルされます。
voltの場合
{% set numbers = ['one': 1, 'two': 2, 'three': 3] %} {% for value in numbers %} Value: {{ value }} {% endfor %}
コンパイル後のphp
<?php $numbers = array('one' => 1, 'two' => 2, 'three' => 3); ?> <?php foreach ($numbers as $value) { ?> Value: <?php echo $value; ?> <?php } ?>
keyとvalueの扱い
voltの場合
{% set numbers = ['one': 1, 'two': 2, 'three': 3] %} {% for name, value in numbers %} Name: {{ name }} Value: {{ value }} {% endfor %}
コンパイル後のphp
<?php $numbers = array('one' => 1, 'two' => 2, 'three' => 3); ?> <?php foreach ($numbers as $name => $value) { ?> Name: <?php echo $name; ?> Value: <?php echo $value; ?> <?php } ?>
for文とifを同時に書く。ループに条件をつけることができます。
コンパイル後のphpをみるとforeachの直下にif文が入っていることが分かります。
voltの場合
{% set numbers = ['one': 1, 'two': 2, 'three': 3] %} {% for value in numbers if value < 2 %} Value: {{ value }} {% endfor %}
コンパイル後のphp
<?php $numbers = array('one' => 1, 'two' => 2, 'three' => 3); ?> <?php foreach ($numbers as $value) { if ($value < 2) { ?> Value: <?php echo $value; ?> <?php } ?><?php } ?>
もちろん、「break」と「continue」があります。ループから抜けたり、現在のブロック内で強制的に次のイテレーションへ移ったりすることができます。
voltの場合
{% set numbers = ['one': 1, 'two': 2, 'three': 3] %} {% for index, value in numbers %} {% if index is even %} {% continue %} {% else %} {% break %} {% endif %} ... {% endfor %}
コンパイル後のphp
<?php $numbers = array('one' => 1, 'two' => 2, 'three' => 3); ?> <?php foreach ($numbers as $index => $value) { ?> <?php if (((($index) % 2) == 0)) { ?> <?php continue; ?> <?php } else { ?> <?php break; ?> <?php } ?> ... <?php } ?>
この中で利用している「{% if index is even %}」については後ほど解説します。
ループの特別な変数
- loop.index
- ループ中、現在のイテレーションが何番目かを返す(順番は1からスタート)
- loop.index0
- ループ中、現在のイテレーションが何番目かを返す(順番は0からスタート)
- loop.revindex
- ループ中、現在のイテレーションがループの最後から何番目かを返す(順番は1からスタート)
- loop.revindex0
- ループ中、現在のイテレーションがループの最後から何番目かを返す(順番は0からスタート)
- loop.first
- ループの最初のイテレーションであれば、(boolean)trueを返す
- loop.last
- ループの最後のイテレーションであれば、(boolean)trueを返す
- loop.length
- ループの要素数を返す
実際にコーディングし、その結果を記載します。
{% set numbers = ['one', 'two', 'three','four'] %} {% for index, value in numbers %} {% if loop.first %} 最初<br> loop.length:{{ loop.length }}<br> {% endif %} {% if loop.last %} 最後<br> {% endif %} value:{{ value }}<br> loop.index:{{ loop.index }}<br> loop.index0:{{ loop.index0 }}<br> loop.revindex:{{ loop.revindex }}<br> loop.revindex0:{{ loop.revindex0 }}<br> {% endfor %}
実行結果は
/*** 1週目 ***/ 最初 loop.length:4 value:one loop.index:1 loop.index0:0 loop.revindex:4 loop.revindex0:3 /*** 2週目 ***/ value:two loop.index:2 loop.index0:1 loop.revindex:3 loop.revindex0:2 /*** 3週目 ***/ value:three loop.index:3 loop.index0:2 loop.revindex:2 loop.revindex0:1 /*** 4週目 ***/ 最後 value:four loop.index:4 loop.index0:3 loop.revindex:1 loop.revindex0:0
となります。これは重宝します。ちなみに、コンパイル後のphpは
<?php $v22032113141iterator = $numbers; $v22032113141incr = 0; $v22032113141loop = new stdClass(); $v22032113141loop->length = count($v22032113141iterator); $v22032113141loop->index = 1; $v22032113141loop->index0 = 1; $v22032113141loop->revindex = $v22032113141loop->length; $v22032113141loop->revindex0 = $v22032113141loop->length - 1; ?><?php foreach ($v22032113141iterator as $index => $value) { ?><?php $v22032113141loop->first = ($v22032113141incr == 0); $v22032113141loop->index = $v22032113141incr + 1; $v22032113141loop->index0 = $v22032113141incr; $v22032113141loop->revindex = $v22032113141loop->length - $v22032113141incr; $v22032113141loop->revindex0 = $v22032113141loop->length - ($v22032113141incr + 1); $v22032113141loop->last = ($v22032113141incr == ($v22032113141loop->length - 1)); ?> <?php if ($v22032113141loop->first) { ?> 最初<br> loop.length:<?php echo $v22032113141loop->length; ?><br> <?php } ?> <?php if ($v22032113141loop->last) { ?> 最後<br> <?php } ?> value:<?php echo $value; ?><br> loop.index:<?php echo $v22032113141loop->index; ?><br> loop.index0:<?php echo $v22032113141loop->index0; ?><br> loop.revindex:<?php echo $v22032113141loop->revindex; ?><br> loop.revindex0:<?php echo $v22032113141loop->revindex0; ?><br> <?php $v22032113141incr++; } ?>
コンパイル後のphpもごちゃごちゃしていますが、やってることは単純なのです。phpにて他の書き方もできますが、コーディング量は抑えられます。
※stdClassはhttp://php.net/manual/ja/language.oop5.basic.phpによると、定義済みのクラス。
演算子
以下の演算子はphpのものと使い方は同じです。
演算子
- =
- 代入演算子
- +=
- 加算代入
- -=
- 減算代入
- *=
- 乗算代入
- /=
- 除算代入
- +
- 加算
- –
- 減算
- *
- 乗算
- /
- 除算
- %
- 余り {{ 10 % 3 }} は、1が出力
比較演算子
- ==
- 型の相互変換をした後で両辺の値が等しければtrue
- !=
- 型の相互変換をした後で両辺の値が等しくなければtrue
- <>
- 型の相互変換をした後で両辺の値が等しくなければtrue
- >
- 左の値が右の値より大きければtrue
- <
- 右の値が左の値より大きければtrue
- <=
- 左の値が右の値以上であればtrue
- >=
- 右の値が左の値以上であればtrue
- ===
- 両辺の型と値が等しければtrue
- !==
- 両辺の型と値が等しくなければtrue
論理演算子
- A or B
- AまたはBがtrueなら、trueを返す
- and
- AとBの両方がtrueなら、trueを返す
その他
以下のものは少し解説します。
- ~
- 演算子の両辺をつなげます。例えば、
{{ "hello " ~ "world" }}
の出力結果は「hello world」となり、phpで表現すると
<?php echo 'hello ' . 'world'; ?>
となる
- |
- 前の演算子に対し、後ろの演算子にてフィルターをかける。例えば、
{{ "hello"|uppercase }}
の出力結果は「HELLO」となり、phpで表現すると
<?php echo Phalcon\Text::upper('hello'); ?>
となる
- ..
- 演算子の両辺の文字(1文字のみ)または整数の間のすべてを配列として返す。例えば、
{{ 'a'..'z' }}
は、phpで表現すると
<?php echo range('a', 'z'); ?>
となり、
{{ 1..10 }}
は
<?php echo var_dump(range(1, 10)); ?>
となる。出力結果は、array(10) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) [4]=> int(5) [5]=> int(6) [6]=> int(7) [7]=> int(8) [8]=> int(9) [9]=> int(10) }
- is
- ==と同じ働きをする。例えば
{% if 'aaa' is 'bbb' %}
はphpで表現すると
<?php if ('aaa' == 'bbb') { ?>
- in
- 演算子の左辺が右に含まれているかどうかチェックする。
{% if 'a' in 'abc' %}
これはtrueの処理になり、一方
{% if 'd' in 'abc' %}
は、falseの処理になる。phpで表現すると
<?php if ($this->isIncluded('a', 'abc')) { ?>
になる
- is not
- !=と同じ働きをする。例えば
{% if 'aaa' is not 'bbb' %}
はphpで表現すると
<?php if ('aaa' != 'bbb') { ?>
- ‘a’ ? ‘b’ : ‘c’
- phpの三項演算子と同じ働きをする。
{{ true ? 'b' : 'c' }}
は「b」を出力、一方
{{ false ? 'b' : 'c' }}
は「c」を出力
- ++
- phpと同様のインクリメント
- –
- phpと同様のデクリメント
長くなったので一旦ここまでです。
続きはVolt vol2に記載します。