No Heavy Programming in Templates
-
Rule: Templates MUST NOT contain heavy programming logic. Complex logic MUST be placed in presenters, models, or custom filters/functions.
-
Reason: Templates should focus on presentation only. Business logic in templates is hard to test, maintain, and debug.
What Belongs in Templates:
- Simple conditions (
n:if) - Loops (
n:foreach) - Variable output with filters
- Component rendering
- Block definitions and includes
What Does NOT Belong in Templates:
- Database queries
- Complex calculations
- Business logic decisions
- Data transformations
- API calls
Example (Correct):
{* Data prepared in presenter *}
<p>Total: {$calculatedTotal|number:2} Kč</p>
<p>Discount: {$discountPercentage} %</p>
<ul n:if="$filteredProducts">
<li n:foreach="$filteredProducts as $item">{$item->name}</li>
</ul>
Example (Incorrect):
{* DO NOT do calculations in template *}
{var $total = 0}
{foreach $items as $item}
{var $total += $item->price * $item->quantity}
{if $item->category->hasDiscount() && $user->isPremium()}
{var $total -= $total * 0.1}
{/if}
{/foreach}
<p>Total: {$total}</p>
{* DO NOT filter data in template *}
{foreach $products as $item}
{if $item->isActive && $item->stock > 0 && $item->category->id === 5}
<li>{$item->name}</li>
{/if}
{/foreach}
Moving Logic to Presenter
Example (Presenter):
// In Presenter
public function renderDefault(): void
{
$this->template->calculatedTotal = $this->orderService->calculateTotal($this->order);
$this->template->discountPercentage = $this->discountService->getDiscount($this->user);
$this->template->filteredProducts = $this->productRepository->findActiveInStock(categoryId: 5);
}
Summary:
- Templates MUST NOT contain heavy programming logic.
- Complex calculations, filtering, and business logic MUST be in presenters or services.
- Templates should only handle presentation: conditions, loops, output, and formatting.