Skip to content

Views and Layout

Technomantus Corvi edited this page Sep 5, 2026 · 1 revision

Views & Layout

Views are plain PHP files under views/. They're always rendered inside the shared layout (includes/head.php + view content + includes/footer.php).

// Controller
$this->view('article/show', [
    'title'   => 'Article detail',
    'article' => $article,
]);
<!-- views/article/show.php -->
<h1><?= e($article['title']) ?></h1>
<p><?= e($article['body']) ?></p>

Golden rule: always use e() to print data. Never echo $var directly — it's how XSS gets in.

What's available inside every view

  • $uri — the current normalized path, injected automatically by view(). Used by head.php to highlight the active nav item.
  • Any key you pass in the $data array to view() or $this->view().
  • All global helpers (e(), url(), old(), t(), flash(), etc.), since they're plain functions.

Styling and assets

All shared styles live in public/assets/css/app.css, loaded once from head.php. Avoid inline style="..." attributes in new views — add a class to app.css instead, so the whole project stays visually consistent and themeable from one file.

public/assets/js/app.js currently only auto-dismisses flash messages after 5 seconds and toggles the user menu dropdown (if tanuki_login is active). Add new interactive behavior there rather than inline <script> blocks in views.

The nav

config/nav.php declares the entries shown in includes/head.php:

return [
    ['label' => 'nav.home', 'href' => '/',      'match' => '/'],
    ['label' => 'nav.about', 'href' => '/about', 'match' => '/about'],
];

label is a translation key resolved through t() — see Internationalization. match decides when the item gets the active class (exact match for /, prefix match for everything else).

Flash messages

$this->flash('success', 'Task created!');
$this->redirect('/todo');

head.php reads and displays any pending success/error/warning flash message once, then it's cleared — app.js fades it out automatically after 5 seconds.

Error pages

views/errors/404.php, 500.php, 503.php — plain PHP, styled with .error-page classes in app.css. App::configureErrors() shows the detailed exception instead when APP_DEBUG=true.

Rendering flow (what view() does)

view($name, $data)
  │
  ├── extract($data)              → makes $title, etc. available
  ├── ob_start() + require view   → captures the view's HTML in a buffer
  ├── require includes/head.php   → has access to $title, $uri (from extract)
  ├── echo the captured content
  └── require includes/footer.php

Clone this wiki locally