-
-
Notifications
You must be signed in to change notification settings - Fork 282
/
develop.texy
363 lines (249 loc) · 16.8 KB
/
develop.texy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
開発者向けプラクティス
***********
インストール .[#toc-installation]
===========================
Latteのインストールには、Composerを使うのが一番です。
```shell
composer require latte/latte
```
対応するPHPのバージョン(最新のパッチLatteのバージョンに適用されます)。
| バージョン|PHPと互換性がある
|-----------------|-------------------
| Latte 3.0 | PHP 8.0 - 8.2
テンプレートのレンダリング方法 .[#toc-how-to-render-a-template]
================================================
テンプレートをレンダリングする方法は?この簡単なコードを使うだけです。
```php
$latte = new Latte\Engine;
// cache directory
$latte->setTempDirectory('/path/to/tempdir');
$params = [ /* template variables */ ];
// or $params = new TemplateParameters(/* ... */);
// render to output
$latte->render('template.latte', $params);
// or render to variable
$output = $latte->renderToString('template.latte', $params);
```
パラメータには配列や[オブジェクトを |#Parameters as a class]指定することができ、エディターで型チェックやサジェストを行うことができます。
.[note]
また、[Latte examplesという |https://github.com/nette-examples/latte]リポジトリで使用例を見ることができます。
パフォーマンスとキャッシング .[#toc-performance-and-caching]
==============================================
Latteのテンプレートは非常に高速です。Latteはテンプレートを直接PHPコードにコンパイルし、ディスク上にキャッシュしているからです。したがって、純粋なPHPで書かれたテンプレートと比較して、余分なオーバーヘッドがありません。
キャッシュは、ソースファイルを変更するたびに自動的に再生成されます。そのため、開発中にLatteのテンプレートを編集しても、すぐにブラウザで変更内容を確認できる便利な機能です。本番環境ではこの機能を無効にして、パフォーマンスを少し節約することができます。
```php
$latte->setAutoRefresh(false);
```
本番サーバーに導入した場合、特に大規模なアプリケーションの場合、最初のキャッシュ生成には当然ながら時間がかかることがあります。Latteは「キャッシュスタンピード」に対する:https://en.wikipedia.org/wiki/Cache_stampede予防策を内蔵しています。
これは、サーバーが多数の同時リクエストを受け、Latteのキャッシュがまだ存在しないため、それらがすべて同時にキャッシュを生成してしまう状況です。これがCPUを急上昇させるのです。
Latteは賢く、複数の同時リクエストがあった場合、最初のスレッドだけがキャッシュを生成し、他のスレッドは待ってからキャッシュを使用します。
クラスとしてのパラメータ .[#toc-parameters-as-a-class]
==========================================
テンプレートに変数を配列として渡すよりも、クラスを作成する方がよいでしょう。[型安全な記法が |type-system]得られるし、[IDEでの表示もきれい |recipes#Editors and IDE]だし、[フィルタや |extending-latte#Filters Using the Class] [関数を |extending-latte#Functions Using the Class] [登録 |extending-latte#Filters Using the Class]する方法もある。
```php
class MailTemplateParameters
{
public function __construct(
public string $lang,
public Address $address,
public string $subject,
public array $items,
public ?float $price = null,
) {}
}
$latte->render('mail.latte', new MailTemplateParameters(
lang: $this->lang,
subject: $title,
price: $this->getPrice(),
items: [],
address: $userAddress,
));
```
変数の自動エスケープを無効にする .[#toc-disabling-auto-escaping-of-variable]
============================================================
変数にHTML文字列が含まれている場合、Latteが自動的に(つまり二重に)エスケープしないようにマークすることができます。これにより、テンプレートで`|noescape` を指定する必要がなくなります。
最も簡単な方法は、文字列を`Latte\Runtime\Html` オブジェクトで囲むことです。
```php
$params = [
'articleBody' => new Latte\Runtime\Html($article->htmlBody),
];
```
また、Latteは、`Latte\HtmlStringable` インターフェースを実装するすべてのオブジェクトをエスケープしません。そこで、`__toString()` メソッドが自動的にエスケープされないHTMLコードを返すクラスを独自に作成することができます。
```php
class Emphasis extends Latte\HtmlStringable
{
public function __construct(
private string $str,
) {
}
public function __toString(): string
{
return '<em>' . htmlspecialchars($this->str) . '</em>';
}
}
$params = [
'foo' => new Emphasis('hello'),
];
```
.[warning]
`__toString` メソッドは正しい HTML を返し、パラメータのエスケープを提供しなければなりません。そうでなければ、XSS 脆弱性が発生する可能性があります。
フィルターやタグなどを使ってラテを拡張する方法。 .[#toc-how-to-extend-latte-with-filters-tags-etc]
==========================================================================
Latteにカスタムフィルタ、関数、タグなどを追加するには?Latte[の拡張の |extending Latte]章を参照してください。
変更した内容を別のプロジェクトで再利用したい場合や、他の人と共有したい場合は、[拡張機能を作成 |creating-extension]する必要があります。
テンプレート内の任意のコード`{php ...}` .{toc: RawPhpExtension}
=================================================
の中に書くことができるのは、PHPの式だけです。 [`{do}` |tags#do]タグを使用するため、例えば、`if ... else` やセミコロンで終端されたステートメントのような構成要素を挿入することはできません。
ただし、`{php ...}` タグを追加する`RawPhpExtension` 拡張を登録することができます。これを利用して、任意のPHPコードを挿入することができます。サンドボックスモードのルールは適用されないので、使用はテンプレート作者の責任でお願いします。
```php
$latte->addExtension(new Latte\Essential\RawPhpExtension);
```
生成コードのチェック .[#toc-checking-generated-code]{data-version:3.0.7}
==============================================================
LatteはテンプレートをPHPコードにコンパイルします。もちろん、生成されたコードが構文的に有効であることを保証します。しかし、サードパーティの拡張モジュールやRawPhpExtensionを使用する場合、Latteは生成されたファイルの正しさを保証することはできません。
また、PHPでは、構文的には正しいが禁止されているコード(例えば$this変数に値を代入する)を書くことができ、PHPコンパイルエラーを引き起こします。
このような操作をテンプレートに書くと、生成されるPHPコードにも含まれることになります。PHPには200種類以上の禁則処理があるため、Latteはそれらを検出することを目的としていません。PHP自身がレンダリング時にフラグを立てますので、通常は問題ありません。
しかし、テンプレートのコンパイル時にPHPコンパイルエラーがないことを確認したい場合があります。特に、テンプレートをユーザが編集できるようにしたり、[サンドボックスを |Sandbox]使用したりする場合です。このような場合、コンパイル中にテンプレートをチェックします。
この機能を有効にするには、Engine::enablePhpLint() メソッドを使用します。チェックのためにPHPバイナリを呼び出す必要があるので、そのパスをパラメータとして渡します:
```php
$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');
try {
$latte->compile('home.latte');
} catch (Latte\CompileException $e) {
// PHPのラテ・エラーとコンパイル・エラーをキャッチする
echo 'Error: ' . $e->getMessage();
}
```
ロケール .[#toc-locale]{data-version:3.0.18}
========================================
Latteではロケールを設定することができます。ロケールは数値、日付、ソートのフォーマットに影響します。ロケールは`setLocale()` 。ロケール識別子は IETF の言語タグ標準に従い、PHP の`intl` 拡張モジュールを使用します。これは、言語コードと場合によっては国コードで構成されます。 たとえば、`en_US` は米国の英語、`de_DE` はドイツのドイツ語といった具合です。
```php
$latte = new Latte\Engine;
$latte->setLocale('cs');
```
ロケールの設定は、フィルタ[localDate |filters#localDate]、[sort |filters#sort]、[number |filters#number] および[bytes |filters#bytes] に影響します。
.[note]
PHP の`intl` 拡張モジュールが必要です。Latte での設定は、PHP のグローバルロケール設定には影響しません。
ストリクトモード .[#toc-strict-mode]{data-version:3.0.8}
================================================
厳密な解析モードでは、LatteはHTMLの閉じタグの欠落をチェックし、`$this` 変数の使用も無効にします。これを有効にするには
```php
$latte = new Latte\Engine;
$latte->setStrictParsing();
```
`declare(strict_types=1)` ヘッダーを持つテンプレートを生成するには、以下のようにしてください:
```php
$latte = new Latte\Engine;
$latte->setStrictTypes();
```
テンプレートでの翻訳 .{toc: TranslatorExtension}
======================================
`TranslatorExtension` の拡張機能を使用して、追加します。 [`{_...}` |tags#_], [`{translate}` |tags#translate]とフィルター [`translate` |filters#translate]をテンプレートに追加します。これらは、テンプレートの値や部分を他の言語に翻訳するために使用されます。パラメータは、翻訳を実行するメソッド(PHP callable)です。
```php
class MyTranslator
{
public function __construct(private string $lang)
{}
public function translate(string $original): string
{
// create $translated from $original according to $this->lang
return $translated;
}
}
$translator = new MyTranslator($lang);
$extension = new Latte\Essential\TranslatorExtension(
$translator->translate(...), // [$translator, 'translate'] in PHP 8.0
);
$latte->addExtension($extension);
```
トランスレータは、テンプレートがレンダリングされるときに実行時に呼び出されます。しかし、Latteはテンプレートのコンパイル時にすべての静的テキストを翻訳することができます。これは、各文字列が一度だけ翻訳され、その結果の翻訳がコンパイルされたファイルに書き込まれるため、パフォーマンスを節約することができます。これにより、キャッシュディレクトリに、各言語ごとに複数のコンパイル済みバージョンのテンプレートが作成されます。これを行うには、第2パラメータとして言語を指定するだけです。
```php
$extension = new Latte\Essential\TranslatorExtension(
$translator->translate(...),
$lang,
);
```
静的テキストとは、例えば、`{_'hello'}` や`{translate}hello{/translate}` のような静的でないテキストを意味します。`{_$foo}` のような静的でないテキストは、実行時に翻訳が継続されます。
また,テンプレートは,`{_$original, foo: bar}` または`{translate foo: bar}` を介して,トランスレータに追加のパラメータを渡すことができ,トランスレータはこれを`$params` の配列として受け取ります.
```php
public function translate(string $original, ...$params): string
{
// $params['foo'] === 'bar'
}
```
デバッグとトレイシー .[#toc-debugging-and-tracy]
======================================
ラテは、できるだけ快適に開発できるように心がけています。デバッグのために、以下の3つのタグを用意しています。 [`{dump}` |tags#dump], [`{debugbreak}` |tags#debugbreak]と [`{trace}` |tags#trace].
優れた[デバッグツールであるTracyを |tracy:en]インストールし、Latteプラグインを有効化すれば、最も快適になります。
```php
// enables Tracy
Tracy\Debugger::enable();
$latte = new Latte\Engine;
// activates Tracy's extension
$latte->addExtension(new Latte\Bridges\Tracy\TracyExtension);
```
これで、行と列が強調表示されたテンプレート内のエラーも含め、すべてのエラーがきちんと赤い画面で確認できるようになります[(動画 |https://github.com/nette/tracy/releases/tag/v2.9.0])。
同時に、右下のいわゆるトレーシーバーにラテのタブが表示され、レンダリングされたすべてのテンプレートとその関係(テンプレートやコンパイルされたコードにクリックする可能性を含む)、および変数を明確に見ることができます。
[* latte-debugging.webp *]
Latteはテンプレートを読みやすいPHPコードにコンパイルするので、IDEでステップを踏んでいけるのが便利です。
リンターテンプレートの構文を検証する .{toc: Linter}
=================================
Linterツールは、すべてのテンプレートを調べて、シンタックスエラーをチェックするのに役立ちます。コンソールから起動します。
```shell
vendor/bin/latte-lint <path>
```
[ストリクト・モード|#strict mode] 有効にするには、`--strict` パラメータを使用する。
カスタムタグを使用する場合は、カスタマイズしたLinterも作成してください(例:`custom-latte-lint` )。
```php
#!/usr/bin/env php
<?php
// autoload.phpファイルへの実際のパスを入力します。
ここに個々の拡張子を追加します
require __DIR__ . '/vendor/autoload.php';
$path = $argv[1] ?? '.';
$linter = new Latte\Tools\Linter;
$latte = $linter->getEngine();
//$latte->addExtension(/* ... */);
$ok = $linter->scanDirectory($path);
exit($ok ? 0 : 1);```
あるいは、独自の`Latte\Engine` オブジェクトを Linter に渡すこともできます:
```php
$latte = new Latte\Engine;
// ここでは、$latteオブジェクトを設定します。
$linter = new Latte\Tools\Linter(engine: $latte);```
文字列からテンプレートを読み込む .[#toc-loading-templates-from-a-string]
========================================================
テスト用に、ファイルではなく文字列からテンプレートをロードする必要がありますか?[StringLoaderは |extending-latte#stringloader]、そんなあなたのお役に立ちます。
```php
$latte->setLoader(new Latte\Loaders\StringLoader([
'main.file' => '{include other.file}',
'other.file' => '{if true} {$var} {/if}',
]));
$latte->render('main.file', $params);
```
例外ハンドラ .[#toc-exception-handler]
================================
期待される例外に対して、独自のハンドラを定義することができます。の内部で発生する例外は [`{try}` |tags#try]と[サンドボックス |sandbox]内に渡されます。
```php
$loggingHandler = function (Throwable $e, Latte\Runtime\Template $template) use ($logger) {
$logger->log($e);
};
$latte = new Latte\Engine;
$latte->setExceptionHandler($loggingHandler);
```
レイアウトの自動検索 .[#toc-automatic-layout-lookup]
==========================================
タグの使用 [`{layout}` |template-inheritance#layout-inheritance]を指定すると、そのテンプレートが親テンプレートを決定します。また、レイアウトを自動的に検索させることも可能で、この場合、`{layout}` タグを記述する必要がなくなるため、テンプレートの記述が簡略化されます。
これを実現するために、次のような工夫をしています。
```php
$finder = function (Latte\Runtime\Template $template) {
if (!$template->getReferenceType()) {
// it returns the path to the parent template file
return 'automatic.layout.latte';
}
};
$latte = new Latte\Engine;
$latte->addProvider('coreParentFinder', $finder);
```
テンプレートがレイアウトを持つべきではない場合は、`{layout none}` タグでその旨を表示します。