1# Templates 2 3A simple template engine separates logic from the presentation and provides 4methods for creating nested templates and escaping strings to protect against 5too common XSS vulnerabilities. 6 7Template engine initialization: 8 9```php 10$template = new App\Template\Engine(__DIR__.'/../path/to/templates'); 11``` 12 13Site-wide configuration parameters can be assigned before rendering so they are 14available in all templates: 15 16```php 17$template->assign([ 18 'siteUrl' => 'https://bugs.php.net', 19 // ... 20]); 21``` 22 23Page can be rendered in the controller: 24 25```php 26echo $template->render('pages/how_to_report.php', [ 27 'mainHeading' => 'How to report a bug?', 28]); 29``` 30 31The `templates/pages/how_to_report.php`: 32 33```php 34<?php $this->extends('layout.php', ['title' => 'Reporting bugs']) ?> 35 36<?php $this->start('main_content') ?> 37 <h1><?= $this->noHtml($mainHeading) ?></h1> 38 39 <p><?= $siteUrl ?></p> 40<?php $this->end('main_content') ?> 41 42<?php $this->start('scripts') ?> 43 <script src="/js/feature.js"></script> 44<?php $this->end('scripts') ?> 45``` 46 47The `templates/layout.php`: 48 49```html 50<!DOCTYPE html> 51<html lang="en"> 52 <head> 53 <meta charset="utf-8"> 54 <link rel="stylesheet" href="/css/style.css"> 55 <title>PHP Bug Tracking System :: <?= $title ?? '' ?></title> 56 </head> 57 <body> 58 <?= $this->block('main_content') ?> 59 60 <div><?= $siteUrl ?></div> 61 62 <script src="/js/app.js"></script> 63 <?= $this->block('scripts') ?> 64 </body> 65</html> 66``` 67 68## Including templates 69 70To include a partial template snippet file: 71 72```php 73<?php $this->include('forms/report_bug.php') ?> 74``` 75 76which is equivalent to `<?php include __DIR__.'/../forms/contact.php' ?>`, 77except that the variable scope is not inherited by the template that included 78the file. To import variables into the included template snippet file: 79 80```php 81<?php $this->include('forms/contact.php', ['formHeading' => 'value', 'foo' => 'bar']) ?> 82``` 83 84## Blocks 85 86Blocks are main building elements that contain template snippets and can be 87included into the parent file(s). 88 89Block is started with the `$this->start('block_name')` call and ends with 90`$this->end('block_name')`: 91 92```php 93<?php $this->start('block_name') ?> 94 <h1>Heading</h1> 95 96 <p>...</p> 97<?php $this->end('block_name') ?> 98``` 99 100### Appending blocks 101 102Block content can be appended to existing blocks by the 103`$this->append('block_name')`. 104 105The `templates/layout.php`: 106 107```html 108<html> 109<head></head> 110<body> 111 <?= $this->block('content'); ?> 112 113 <?= $this->block('scripts'); ?> 114</body> 115</html> 116``` 117 118The `templates/pages/index.php`: 119 120```php 121<?php $this->extends('layout.php'); ?> 122 123<?php $this->start('scripts'); ?> 124 <script src="/js/foo.js"></script> 125<?php $this->end('scripts'); ?> 126 127<?php $this->start('content') ?> 128 <?php $this->include('forms/form.php') ?> 129<?php $this->end('content') ?> 130``` 131 132The `templates/forms/form.php`: 133 134```php 135<form> 136 <input type="text" name="title"> 137 <input type="submit" value="Submit"> 138</form> 139 140<?php $this->append('scripts'); ?> 141 <script src="/js/bar.js"></script> 142<?php $this->end('scripts'); ?> 143``` 144 145The final rendered page: 146 147```html 148<html> 149<head></head> 150<body> 151 <form> 152 <input type="text" name="title"> 153 <input type="submit" value="Submit"> 154 </form> 155 156 <script src="/js/foo.js"></script> 157 <script src="/js/bar.js"></script> 158</body> 159</html> 160``` 161 162## Helpers 163 164Registering additional template helpers can be useful when a custom function or 165class method needs to be called in the template. 166 167### Registering function 168 169```php 170$template->register('formatDate', function (int $timestamp): string { 171 return gmdate('Y-m-d H:i e', $timestamp - date('Z', $timestamp)); 172}); 173``` 174 175### Registering object method 176 177```php 178$template->register('doSomething', [$object, 'methodName']); 179``` 180 181Using helpers in templates: 182 183```php 184<p>Time: <?= $this->formatDate(time()) ?></p> 185<div><?= $this->doSomething('arguments') ?></div> 186``` 187 188## Escaping 189 190When protecting against XSS there are two built-in methods provided. 191 192To replace all characters to their applicable HTML entities in the given string: 193 194```php 195<?= $this->noHtml($var) ?> 196``` 197 198To escape given string and still preserve certain characters as HTML: 199 200```php 201<?= $this->e($var) ?> 202``` 203