Chapter 6 of 15
Views and layouts.
Render PHP templates with explicit data, a shared layout, and safe output escaping.
Rendering from a controller
The injected ViewRendererInterface is request-scoped. render() returns a response, while content() returns a string for further composition.
Controller
<?php
use Lemonade\Framework\View\ViewRendererInterface;
use Psr\Http\Message\ResponseInterface;
final readonly class ArticleController
{
public function __construct(
private ViewRendererInterface $views,
private ArticleRepository $articles,
) {}
public function detail(string $id): ResponseInterface
{
return $this->views->render('articles.detail', [
'article' => $this->articles->get($id),
]);
}
}The articles.detail name resolves to the matching PHP view through configured view resources.
Templates and helpers
Pass only the data a view needs and escape dynamic text. Use delegated methods on $this for URLs, translations, assets, and CSRF; $requestHelpers exposes request-local data.
app/Views/articles/detail.php
<?php /** @var array{id:string,title:string,body:string} $article */ ?>
<article>
<h1><?= e($article['title']) ?></h1>
<p><?= e($article['body']) ?></p>
</article>Layouts, partials, and sections remain available through the view object in $this.