Less Boilerplate, More Types: Introducing #[TemplateVariable]
Sometimes a presenter works with a specific domain object (like an article,
order, or user) and naturally keeps it in a property. You also need that same
object in your Latte template. Until now, that required an extra line
with $this->template->…
In Nette Framework 3.2.9, a neat little feature was introduced: the
#[TemplateVariable] attribute. Simply mark a presenter property
with this attribute (it can't be private), and it automatically becomes
available in your template under the same name:
<?php
declare(strict_types=1);
namespace App\Presentation\Article;
use Nette\Application\Attributes\TemplateVariable;
use Nette\Application\UI\Presenter;
final class ArticlePresenter extends Presenter
{
#[TemplateVariable]
public string $siteName = 'My blog';
#[TemplateVariable]
public ?Model\Article $article = null;
public function actionShow(int $id): void
{
$this->article = $this->articleFacade->getById($id);
}
}
In your template, you can then just use $siteName and
$article directly—no extra wiring needed.
If you do assign a variable with the same name via
$this->template->…, though,
#[TemplateVariable] won't override it. In other words, when a
variable already exists in the template, the attribute leaves it alone.
The Easiest Path to Typed Templates
Another nice thing about #[TemplateVariable] is that it
naturally encourages using typed properties as your template's data
source. Types are checked by PHP itself (and picked up by IDEs and static
analysis), so instead of dynamically stuffing values into
$this->template, you're working with proper, strongly-typed
values (Article, bool, string…).
Nette offers a complete solution for type-safe templates through custom
template classes, where variable types are explicitly defined and
$this->template becomes a well-defined object instead of a
generic container.
That said, #[TemplateVariable] can be a nice lightweight
alternative for small to medium-sized use cases: you don't want the overhead of
creating a dedicated template class, but you still want clean code with proper
type safety. And when your project grows, you can always migrate to the full
strictly-typed template approach.
Sign in to submit a comment