Views
Introduction
Views separate presentation logic from application logic. Lighthouse uses plain PHP templates — no new syntax to learn.
Configuration
Configure the views directory:
php
$app->useViews(__DIR__ . '/../views');Basic Usage
Create a view file:
php
// views/welcome.php
<h1>Welcome, <?= $view->e($name) ?>!</h1>Render it:
php
$app->get('/', function () use ($app) {
return $app->view('welcome', ['name' => 'John']);
});Or from a controller:
php
return $this->view('welcome', ['name' => 'John']);Escaping Output
Always escape user data with $view->e():
php
<p><?= $view->e($userInput) ?></p>This prevents XSS attacks by converting <script> to <script>.
For JSON in JavaScript:
php
<script>
const data = <?= $view->json($data) ?>;
</script>Layouts
Create a layout:
php
// views/layouts/main.php
<!DOCTYPE html>
<html>
<head>
<title><?= $view->yield('title', 'My App') ?></title>
</head>
<body>
<header>
<nav><!-- Navigation --></nav>
</header>
<main>
<?= $view->yield('content') ?>
</main>
<footer>
<p>© 2025 My App</p>
</footer>
</body>
</html>Extend it in child views:
php
// views/home.php
<?php $view->extends('layouts.main'); ?>
<?php $view->section('title'); ?>
Home
<?php $view->endSection(); ?>
<?php $view->section('content'); ?>
<h1>Welcome Home!</h1>
<p>This is the homepage.</p>
<?php $view->endSection(); ?>Sections
Define sections in child views:
php
<?php $view->section('sidebar'); ?>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
<?php $view->endSection(); ?>Output in layouts:
php
<aside>
<?= $view->yield('sidebar') ?>
</aside>Default content:
php
<?= $view->yield('sidebar', '<p>No sidebar</p>') ?>Check if section exists:
php
<?php if ($view->hasSection('sidebar')): ?>
<aside><?= $view->yield('sidebar') ?></aside>
<?php endif; ?>Partials
Extract reusable components:
php
// views/partials/user-card.php
<div class="user-card">
<h3><?= $view->e($user['name']) ?></h3>
<p><?= $view->e($user['email']) ?></p>
</div>Include them:
php
<?php foreach ($users as $user): ?>
<?php $view->include('partials.user-card', ['user' => $user]); ?>
<?php endforeach; ?>Or capture the output:
php
<?= $view->partial('partials.user-card', ['user' => $user]) ?>Shared Data
Share data across all views:
php
// In public/index.php
$app->getView()->share('appName', 'My App');
$app->getView()->share([
'currentYear' => date('Y'),
'user' => $currentUser,
]);Access in any view:
php
<title><?= $view->e($appName) ?></title>
<p>© <?= $currentYear ?></p>Dot Notation
Use dots for subdirectories:
php
return $this->view('users.index');
// Loads: views/users/index.php
return $this->view('admin.users.edit');
// Loads: views/admin/users/edit.phpFull Example
Layout:
php
// views/layouts/app.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><?= $view->yield('title', $appName) ?></title>
<?= $view->yield('head') ?>
</head>
<body>
<?php $view->include('partials.nav'); ?>
<main class="container">
<?= $view->yield('content') ?>
</main>
<footer>
<p>© <?= date('Y') ?> <?= $view->e($appName) ?></p>
</footer>
<?= $view->yield('scripts') ?>
</body>
</html>Page:
php
// views/users/index.php
<?php $view->extends('layouts.app'); ?>
<?php $view->section('title'); ?>
Users - <?= $view->e($appName) ?>
<?php $view->endSection(); ?>
<?php $view->section('content'); ?>
<h1>Users</h1>
<?php if (empty($users)): ?>
<p>No users found.</p>
<?php else: ?>
<ul>
<?php foreach ($users as $user): ?>
<li><?= $view->e($user['name']) ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php $view->endSection(); ?>