Hello World
There are three ways to handle a request in TrueFramework, in order of how much code you have to write. Pick the smallest one that fits.
For a request to /hello this:
- Tries to include
app/controllers/hello.php— silently skipped if it doesn't exist. - Renders
app/views/hello.phtmlwith whatever$varsthe controller (if any) set.
That means most pages need no route registration at all. Pick the pattern that fits the request you're building.
1. View only — no controller, no route
For purely informational pages — home, about, terms, anything where the URL just needs to render a template — drop a .phtml file in app/views/ and you're done.
app/views/hello.phtmltitle = "Hello"
description = "This is the hello description."
{endmeta}
<h1>Hello, world!</h1>
Visit http://localhost:8000/hello and the page renders inside your layout. No route, no controller, no boilerplate.
Folders work too. app/views/about/team.phtml is reachable at /about/team. The catch-all uses the URL path verbatim to find the template.
2. View + controller — when the page needs data
Once a page has logic — reading the query string, hitting the database, deciding what to show — promote it to a controller. The controller is a flat PHP file at app/controllers/<path>.php with the same name as the URL. Anything you put into $vars is unpacked into the template's local scope.
app/controllers/hello.php
$vars['who'] = $request->get->name('name') ?: 'world';
app/views/hello.phtml
title = "Hello"
{endmeta}
<h1>Hello, <?=esc($who)?>!</h1>
Now /hello?name=Daniel reads and sanitizes the query string, passes it to the view, and renders. Still no explicit route — the catch-all wires the controller and view together by URL.
3. Explicit route — when verbs and shapes matter
For anything that isn't "render an HTML page" — APIs, form posts, webhooks, anything that needs a specific HTTP verb or returns JSON — register a route in app/routes.php. Routes go above the catch-all so they match first.
app/routes.php
Add ABOVE the catch-all
$App->router->get('/api/hello/:name', function($request) use ($App) {
$App->response([
'message' => 'Hello, ' . $request->route->name . '!',
'time' => date('c'),
], 'json');
});
A GET to /api/hello/Daniel returns:
{
"message": "Hello, Daniel!",
"time": "2026-04-30T15:42:11+00:00"
}
Use the same approach for post(), put(), patch(), delete(), or multi-verb any() handlers. Route placeholders like :name land on $request->route. See Route Patterns for the full set.
Which one should I use?
| If you're building… | Use… |
|---|---|
| A static or near-static page (about, services, FAQ) | View only |
| A page that reads input, hits a DB, or branches on state | View + controller |
| An API endpoint, webhook, JSON return, or dynamic urls | Explicit route |
| A form POST handler tied to a page | Either — controller for the page, explicit route for the POST, or both in the controller checking $request->method |