Cheetah:キャッシュとフィルター
キャッシュ
個々の変数でのキャッシュ
デフォルトでは、それぞれの$変数の値が取得され、リクエストごとに展開されます。 ただし、テンプレートの入力を高速化するために、頻繁に変更されない場合では、個々の変数の値をキャッシュすることができます。
単一の$変数の値をキャッシュするには、ドル記号($)の後にアスタリスクを追加します。
例:$* var。 テンプレートが初めて入力されると、$varが検索されます。 その後、テンプレートが再度入力されるたびに、ルックアップを実行する代わりに、キャッシュされた値が使用されます。
$*形式は永久にキャッシュします。 つまり、テンプレートインスタンスがメモリに残っている限りキャッシュされ続けます。 $*<interval>* variableの形式を使用して、特定の期間キャッシュすることもできます。ここで、<interval>は間隔です。 時間間隔は、秒(5s)、分(15m)、時間(3h)、日(2d)、または週(1.5w)で指定できます。 デフォルトは分です。
code: html
<HTML>
<HEAD><TITLE>$title</TITLE></HEAD>
<BODY>
$var ${var} ## 動的:リクエストごとに毎回、検索し展開される
$*var2 $*{var2} ## 静的:リクエストされた初回だけ、検索し展開される
$*5*var3 $*5*{var3} ## 時間指定で更新:5分ごとに更新される
</BODY>
</HTML>
この例の「5分ごと」は、実際に5分ごとを意味することに注意してください。テンプレートが頻繁に入力されているかどうかに関係なく、制限時間に達すると変数が再度検索されます。
長い変数構文${...}を使用している場合、中括弧は変数名だけを囲みます。
例:$ *5h* {var.func('arg')}
特定の時間間隔ではなく、いつでも、キャッシュされたアイテムを明示的に無効にする方が望ましい場合があります。 個々の変数を使用してこれを行うことはできませんが、次に説明するキャッシュされた領域を使用して行うことができます。
領域全体のキャッシュ
書式
#cacheディレクティブは、コンテンツの領域をテンプレートにキャッシュするために使用されます。リージョン内のプレースホルダーとディレクティブが評価された後、リージョンは単一のユニットとしてキャッシュされます。キャッシュ領域内に$*<interval>* varがある場合、それらはキャッシュ領域と変数が同時に更新される必要がある場合にのみ更新されます。
領域のキャッシュは、個々の変数をキャッシュするよりも柔軟性があります。変数または式を使用して更新間隔を指定するか、特定の時間間隔ではなく他の基準に従って更新することができます。
引数のない#cacheディレクティブは、$* varと同じ方法で、領域を静的にキャッシュします。キャッシュされた領域は自動的には更新されません。
一定の間隔で領域を更新するには、$*<interval>* と同等の timer=EXPRESSION引数を使用します。式は、有効な時間間隔(0.5、3mなど)である数値または文字列に評価される必要があります。
式の結果がTrueの場合だけ常に更新するには、test=EXPRESSIONを使用します。式は、TrueまたはFalseを返すメソッド/関数、変数、およびandやorで結合されたこれらのいくつか式にすることができます。式にスペースが含まれている場合は、括弧(())で囲むと読みやすくなりますが、必須ではありません。
リクエストするたびに更新させるには、id=EXPRESSION を使用します。その後、プログラムは必要に応じていつでも refreshCache(ID)を呼び出すことができます。これは、キャッシュが、めったに変更されないが、今変更されたばかりの外部条件に依存しているような場合に役立ちます。
引数をコンマで区切って組み合わせることができます。たとえば、id=とinterval=の両方、または id=とtest=の両方を指定できます。
interval=とtest=を組み合わせることもできますが、あまり便利ではありません。
また、同じ引数の繰り返しは許されていません。
code: html
これは静的キャッシュです。 更新されません。
$a $b $c
#cache timer='30m', id='cache1' $cust.name:
$cust.street - $cust.city
#cache id='sidebar', test=$isDBUpdated ... left sidebar HTML ...
#cache id='sidebar2', test=($isDBUpdated or $someOtherCondition) ... right sidebar HTML ...
#cacheディレクティブはネストすることができません。
将来的には、varyByキーワード引数を追加して、さまざまなクエリ文字列パラメータやブラウザタイプなど、さまざまな条件に対して個別のキャッシュインスタンスを作成できるようにする予定です。 これは、ASP.netのvaryByParamおよびvaryByBrowserの出力キャッシュキーワードに触発されています。
フィルタリング
書式
#filter $PLACEHOLDER_TO_A_FILTER_INSTANCE $変数 からの出力は、出力フィルターを通過します。 デフォルトのフィルターは、値がNoneでない限り、変数の値の文字列表現を返すだけです。Noneの場合、フィルターは空の文字列を返します。 トップレベルの変数だけがフィルターを呼び出します。 式の中での変数はフィルターで処理されません。
特定のフィルターは、オプションの引数を使用して動作を変更します。 引数を渡すには、長い変数構文(${変数})を使用し、各フィルター引数の前にコンマを付けます。 慣例により、フィルター引数は$プレフィックスを取りません。これは、すでにドル記号がたくさんあるプレースホルダータグが乱雑にならないようにするためです。 たとえば、MaxLenフィルターは引数maxlenを与えることで動作します。
code: html
${placeholderName, maxlen=20}
${functionCall($functionArg), maxlen=$myMaxLen}
出力フィルターを変更するには、filterキーワード引数をTemplateクラスのコンストラクターに与えるか、実行時に#filterディレクティブを使用します。特定の$変数に1つのフィルターが必要で、他の$変数には別のフィルターが必要な場合は、#filterを何度でも使用できます。
標準フィルターはモジュールCheetah.Filtersにあります。
Cheetah では、現在次のフィルターを提供しています。
デフォルトフィルター
Noneを空の文字列('')に変換し、その他のすべてをstr()で変換するフィルター
これは、他のすべてのフィルターのベースクラスであり、Cheetahで配布されるすべてのフィルターの最小動作です。
MaLenフィルター
特定の長さより長い場合は値を切り捨てます。前述の例のように、maxlenフィルター引数を使用して長さを指定します。 maxlenを指定しない場合、値は切り捨てられません。
長い文字列を「ページ一杯」を出力するフィルター
ページの後に、前のページと次のページへのHTMLハイパーリンクを出力します。このフィルターは、まだ文書化されていないいくつかのフィルター引数と環境変数を使用します。
デフォルトと同じですが、HTMLに依存する文字($<$、&、$>$)をHTMLエンティティに変換して、ブラウザがHTMLタグとして解釈するのではなく文字通りに表示するようにします。これは、パスワードなどの機密文字が含まれている可能性のあるデータベース値またはユーザー入力で役立ちます。ただし、値に保持する埋め込みHTMLタグが含まれている場合は、このフィルターは必要ありません。
alsoフィルタ
フィルタ引数alsoを使用して、エスケープする追加の文字を指定することができます。たとえば、値がすべて1行に表示されるようにしたいとします。値内のすべてのスペースを、改行しないスペースである   でエスケープします。
code: html
${$country, also=' '}}
クラスオブジェクトを使用してフィルターを切り替えるには、filter引数を使用してクラスをTemplateコンストラクターに渡すか、$変数を介して#filterディレクティブに渡します。
code: html
クラスはCheetah.Filters.Filterのサブクラスである必要があります。クラスオブジェクトを渡す場合、クラスがどこで定義されたかは重要ではないため。filtersLibの値は重要ではありません。
フィルタを名前で切り替えるには、クラスの名前をfilter引数を使用して文字列としてTemplateコンストラクタに渡すか、そのままの単語(引用符なし)として#filterディレクティブに渡します。クラスはfiltersLibで検索されます。
code: html
filtersLibは、デフォルトでCheetah.Filtersのフィルタークラスを含むモジュールです。 Cheetah.Filters.Filterのサブクラスであるモジュール内のすべてのクラスは、フィルターと見なされます。フィルタが別のモジュールにある場合は、モジュールオブジェクトをfiltersLib引数としてテンプレートコンストラクタに渡します。
カスタムフィルターの作成は簡単です。Cheetah.Filters.Filterクラスを継承したクラスで、filterメソッドをオーバーライドするだけです。
code: html
def filter(self, val, **kw): # 文字列を返す
pass
filter()メソッドは、引数valに対して出力される文字列を返します。 valの型はどれでもかまいません。ほとんどのフィルターは、Noneに対して空の文字列('')を返します。
Cheetahはキーワード引数を1つの渡します。kw['rawExpr']は、すべての添え字と引数を含む、テンプレート定義に表示される変数名です。 長い変数構文(${変数})を使用する場合、渡すオプションはすべてキーワード引数として表示されます。 繰り返しますが、戻り値は文字列でなければなりません。
#filter Noneのように、いつでもデフォルトのフィルターに戻すことができます。 フィルターNoneはデフォルトのフィルターを意味し、デフォルトのフィルターが特別に扱う唯一のオブジェクトはNoneであるため、これは覚えやすいはずです。