-
Notifications
You must be signed in to change notification settings - Fork 0
Views and 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.
-
$uri— the current normalized path, injected automatically byview(). Used byhead.phpto highlight the active nav item. - Any key you pass in the
$dataarray toview()or$this->view(). - All global helpers (
e(),url(),old(),t(),flash(), etc.), since they're plain functions.
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.
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).
$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.
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.
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