--- name: latte-templates description: Invoke before creating or modifying .latte files. Provides Latte syntax, tags, filters, layouts, and extensions. --- ## Latte Templating System Latte is a secure templating engine with context-aware escaping, intuitive syntax, and powerful template inheritance. ```shell composer require latte/latte ``` ### Basic Syntax ```latte {* this is a comment *} ``` ### Printing Variables ```latte {$name} {* prints escaped variable *} {$user->name} {* object property *} {$items[0]} {* array access *} {='hello'|upper} {* expression with filter *} {$html|noescape} {* disable escaping (use carefully!) *} ``` ### Filters Filters modify output, written after `|`: ```latte {$title|upper} {* HELLO *} {$text|truncate:100} {* shortens to 100 chars *} {$price|number:2} {* formats number *} {$date|date:'j. n. Y'} {* formats date *} {$name|lower|capitalize} {* chained filters *} ``` Common filters: `upper`, `lower`, `capitalize`, `truncate`, `number`, `date`, `noescape`, `escapeUrl`, `stripHtml`, `trim`, `replace`, `first`, `last`, `length`, `sort`, `reverse` For complete filter reference, see [filters.md](filters.md). ### n:attributes Pair tags can be written as HTML attributes: ```latte {* These are equivalent: *} {if $condition}
...
{/if}
...
{* Applies to element content only: *}
...
{* Applies to tag only (not content): *} Link ``` ### Conditions ```latte {if $stock > 0} In stock {elseif $onWay} On the way {else} Not available {/if} {ifset $user}...{/ifset} {* if variable exists *} {* switch/case *} {switch $type} {case admin}Administrator {case user}User {default}Guest {/switch} ``` ### Loops ```latte {foreach $items as $item} {$item->name} {/foreach} {foreach $items as $key => $item} {$key}: {$item} {/foreach} {* With else for empty arrays *} {foreach $items as $item}
  • {$item}
  • {else}
  • No items found
  • {/foreach} {* Iterator variable *} {foreach $items as $item} {$iterator->counter}. {$item} {* 1, 2, 3... *} {if $iterator->first}First!{/if} {if $iterator->last}Last!{/if} {/foreach} {* Helper tags *} {foreach $items as $item} {first}{/last} {sep}, {/sep} {* separator between items *} {/foreach} ``` ### Variables ```latte {var $name = 'John'} {var $items = [1, 2, 3]} {default $lang = 'en'} {* only if not set *} {capture $content}

    Captured HTML

    {/capture} {$content} ``` ### Template Inheritance **Layout template (`@layout.latte`):** ```latte {block title}Default{/block} {block content}{/block} ``` **Child template:** ```latte {layout '@layout.latte'} {block title}My Page{/block} {block content}

    Welcome

    Content here

    {/block} ``` ### Including Templates ```latte {include 'header.latte'} {include 'item.latte', item: $item, showPrice: true} {include $dynamicTemplate} ``` ### Blocks ```latte {block sidebar} {/block} {include sidebar} {* print block *} {include sidebar from 'other.latte'} {* from another file *} {* Reusable definitions with parameters *} {define button, $text, $type = 'primary'} {/define} {include button, 'Submit'} {include button, 'Cancel', 'secondary'} ``` ### Common Tags Reference | Tag | Description | |-----|-------------| | `{$var}` | Print escaped variable | | `{if}...{/if}` | Condition | | `{foreach}...{/foreach}` | Loop | | `{var $x = ...}` | Create variable | | `{include 'file'}` | Include template | | `{block name}...{/block}` | Define block | | `{layout 'file'}` | Extend layout | | `{do expression}` | Execute without output | | `{php code}` | Raw PHP (needs extension) | | `{dump $var}` | Debug dump (Tracy) | For complete tag reference, see [tags.md](tags.md). ### Smart HTML Attributes ```latte {* null removes attribute *}
    {* boolean controls presence *} {* arrays in class *}
    $isActive]}> {* arrays JSON-encoded in data- *}
    ``` ### n:class Helper ```latte {foreach $items as $item} {$item->name} {/foreach} ``` --- ## Latte in Nette Applications ### Template Organization Strategy **Keep templates with presenters:** ``` Product/ ├── ProductPresenter.php ├── default.latte ├── edit.latte └── detail.latte ``` **Layout placement follows presenter organization:** ``` Admin/ ├── @layout.latte ← Admin-wide layout ├── Auth/ │ ├── @layout.latte ← Auth-specific layout │ └── AuthPresenter.php └── Catalog/ └── Product/ ├── ProductPresenter.php └── edit.latte ``` ### Template Partial Patterns **Shared template parts use @ prefix:** - `@layout.latte` - layout templates - `@form.latte` - reusable form structures - `@item.latte` - list item templates ### Template Class Strategy **Create template classes for complex presenters:** ```php /** * @property-read ProductTemplate $template */ class ProductPresenter extends BasePresenter { } class ProductTemplate extends Nette\Bridges\ApplicationLatte\Template { public ProductRow $product; public array $variants; public ?CategoryRow $category; } ``` **When to use template classes:** - Presenters with 5+ template variables - Complex data structures passed to templates - When you want full IDE support in templates **Template Type Declaration:** ```latte {templateType App\Presentation\Product\ProductTemplate}

    {$product->name}

    {foreach $variants as $variant}
    {$variant->name} - {$variant->price}
    {/foreach} ``` ### Nette-specific Tags ```latte {* Links *} Detail Detail Absolute {* Components *} {control productForm} {control dataGrid} {* AJAX Snippets *} {snippet items} {foreach $items as $item}
    {$item->name}
    {/foreach} {/snippet} {* Forms *} {form loginForm} {label username}{input username} {label password}{input password} {input submit} {/form} {* Assets (Nette Assets) *} {asset 'admin.js'} {asset 'front.css'} ``` ### Extension and Customization **Create single extension for entire application:** ```php final class LatteExtension extends Latte\Extension { public function getFilters(): array { return [ 'money' => fn($amount) => number_format($amount, 0, ',', ' ') . ' Kč', ]; } public function getFunctions(): array { return [ 'canEdit' => fn($entity) => $this->user->isAllowed($entity, 'edit'), ]; } } ``` **Register in config:** ```neon latte: extensions: - App\Presentation\Accessory\LatteExtension ``` ### Latte Configuration ```neon latte: strictParsing: yes locale: cs ``` ### Anti-Patterns to Avoid - **Don't put business logic in templates** - templates display data, don't process it - **Don't create deep template hierarchies** - prefer composition over inheritance - **Don't duplicate template code** - extract to partials or components --- ## Online Documentation For detailed information beyond this reference, fetch from latte.nette.org: - [Syntax](https://latte.nette.org/en/syntax) - complete syntax guide with examples - [Tags](https://latte.nette.org/en/tags) - all available tags in detail - [Filters](https://latte.nette.org/en/filters) - all filters with usage examples - [Template Inheritance](https://latte.nette.org/en/template-inheritance) - layouts, blocks, embed - [Functions](https://latte.nette.org/en/functions) - built-in functions - [Extending Latte](https://latte.nette.org/en/extending-latte) - custom tags, filters, extensions - [Type System](https://latte.nette.org/en/type-system) - template types and IDE support - [Safety First](https://latte.nette.org/en/safety-first) - security and escaping When you need more details about a specific Latte feature not covered in this skill, use WebFetch to retrieve information from these URLs.