https://github.com/modxcms-jp/evolution ... evelop.zip
@IF構文の処理をさらに改善しました。前回は「どこからどこまでが@IF、どこからどこまでが@ELSE」といった切り出し処理を正確・高速に行なうように改善しましたが、今回は@IF・@ELSEIF内の判定処理を改善しました。
本来はフィルターとして利用すべきモディファイアの機能を流用して複雑な分岐処理を実装するケースが増えて、テンプレートワークが分かりにくくなりがちだったのを解決するために@IF構文の開発を進めていました。テンプレートエンジンの実装を行わないことがMODXの思想のひとつでしたが、実際には需要があり、裏技のような実装が普及していました。@IF構文では、モディファイア単体で実装できないレベルの高度な分岐処理を実装する目標がありましたが、今回の改善で実現できたと思います。
コード: 全て選択
<@IF:[*longtitle*]><h1>[*longtitle*]</h1><@ENDIF>
これまでは、たとえば上記のように書いた場合、[*longtitle*]の値が空だと判定処理ではエラーが発生していました。
コード: 全て選択
<@IF:[*longtitle:isNotEmpty*]><h1>[*longtitle*]</h1><@ENDIF>
そのため、上記のように:isNotEmptyモディファイアなどを用いて、「空でなければ1を、空であれば0を返す」という判定をさらに加えて対応する必要がありました。そのように書くほうが意味が分かりやすくてよいかもしれませんが、できるだけ少ない文字数に抑えたいこともあると思います。
コード: 全て選択
<@IF:[*longtitle:isNotEmpty:then(1):else(0)*]><h1>[*longtitle*]</h1><@ENDIF>
もともとは上記のように書く必要がありましたが、
コード: 全て選択
<@IF:[*longtitle*]><h1>[*longtitle*]</h1><@ENDIF>
今回の改善では、上記のように書くだけで動作します。モディファイア処理にスイッチしないため、実際は誤差の範囲ですが、理論的には動作も少しだけ軽くなります。
コード: 全て選択
<@IF:[*description*]><meta name="description" content="[*description*]"><@ENDIF>
[*description*]に何も入力していない場合は何も出力しません。
また、たとえば「郵便番号」というテンプレート変数を設置したとして、その値が「123-4567」だった場合、
コード: 全て選択
<@IF:[*郵便番号*]>[*郵便番号*]<@ENDIF>
「123-4567」を数式と見なして計算してしまい「-4687」として結果的にはfalse判定になることがある問題も修正しました。ただし書き方を少し変更する必要があります。
コード: 全て選択
<@IF:"[*郵便番号*]">[*郵便番号*]<@ENDIF>
コード: 全て選択
<@IF:'[*郵便番号*]'>[*郵便番号*]<@ENDIF>
上記のように、ダブルクォートまたはシングルクォートで囲みます。囲まない場合は、数式として判定できる文字列が含まれている場合は数式として判定します。この仕様はPHPプログラミングに倣っています(もう少しスタイリッシュな方法はないかという気もしますが)。工夫して使い分ければ、たとえばテンプレート変数の値を日付文字列と見なして、何日前になったら色を変更するなどといった処理をモディファイアなどを利用して簡単に作ることができると思います。
クォートで囲まなければ従来どおりの動作です。実際には、数式として自動的に判定されたくないケースのほうが多いはずなので、明示的にクォートで囲むことを習慣付けるのがよいかもしれません。
コード: 全て選択
<@IF:20-[[今日の日付]]==1>
今日は一日前です
<@ENDIF>
あるいは、ビルトインの機能だけで済ませるなら、
コード: 全て選択
<@IF:20-[[$_SERVER['REQUEST_TIME']:date(d)]]==1>
今日は一日前です
<@ENDIF>
式では数字以外に「 - + < = / * ( ) % 」などの文字を使えますので、上記のような判定ができます。これ以外の文字を含む場合は数式文字列とは判定せず、無条件に「1」という値に変換します。
「 [*longtitle*]の文字数が10文字を超える場合は[*pagetitle*]を表示する」 といった実装を行なう場合、
コード: 全て選択
<@IF:[*longtitle:strlen*]>10><h1>[*pagetitle*]</h1><@ENDIF>
上記は動作しません。
コード: 全て選択
<@IF:10<[*longtitle:strlen*]><h1>[*pagetitle*]</h1><@ENDIF>
上記のように書く必要があります。現時点では式の中で「>」を使うことができないためです。これを無理なく実装するためには@IF構文の書式を少し変更する必要があり、互換性の解決方法も含めて今後検討します。
また、冒頭に「!」を付けることで判定を反転させる仕様がありますが、これはIF判定内で使えるケースが限られるという問題がありました。
コード: 全て選択
<@IF:![*longtitle*]&&![*alias*]>[*pagetitle*]<@ENDIF>
たとえば上記のように、&&や||で複数の条件を重ねたケースで使えませんでした。今回の改善で、ほぼ自由に使えるようになりました。
@IFやモディファイアなどでMODX変数(プレースホルダや一時スニペットなどもできれば…)を評価する時に定義されていなければ false に
http://forum.modx.jp/viewtopic.php?p=9541#p9541
上記の件、対応しました。