Routing
How Nibiru maps URLs to controllers, actions and parameters — including SEO-friendly URL forms.
Nibiru routing is convention-based with optional regex routes from settings.<env>.ini for special cases. There’s no big route file to maintain.
The default convention
Section titled “The default convention”/<controller>/<action>/<param1>/<param2>/...Examples:
| URL | Controller | Action | $_REQUEST |
|---|---|---|---|
/ | indexController | (none) | — |
/products | productsController | (none) | — |
/products/detail | productsController | detailAction | — |
/products/detail/42 | productsController | detailAction | id => 42 |
/users/edit/42 | usersController | editAction | id => 42 |
Without an _action, only navigationAction() and pageAction() run. With _action, the named action runs in between.
SEO URLs
Section titled “SEO URLs”Nibiru auto-detects SEO-friendly URLs without any configuration. The pattern:
/<controller>/<slug>/<numeric-id>If the second segment is not a method name on the controller and the third segment is numeric, Nibiru rewrites the request internally to:
/<controller>/detail/?id=<numeric-id>&slug=<slug>So a URL like /maschine/marduk-gold-plating/42 reaches maschineController::detailAction() with $_REQUEST['id'] === '42' and $_REQUEST['slug'] === 'marduk-gold-plating'. This is exactly how the production e-commerce site prod.maschinen-stockert.de produces clean URLs without a custom router.
Reading parameters
Section titled “Reading parameters”Anything past the action segment becomes a $_REQUEST key paired by position:
// /users/edit/42 → $_REQUEST['id'] = '42'public function editAction() { $id = (int) ($_REQUEST['id'] ?? 0); / ...}For non-numeric or named parameters, prefer query strings:
/users/search?q=marduk&page=2Custom routes via INI
Section titled “Custom routes via INI”The [NIBIRU_ROUTING] section in settings.<env>.ini lets you map regex URL patterns to controller/action pairs and named params:
[NIBIRU_ROUTING]; Map /api/v1/products/42 to apiController::productsAction with id=42api.v1.products.pattern = "^/api/v1/products/(\d+)$"api.v1.products.controller = "api"api.v1.products.action = "products"api.v1.products.params[] = "id"When a URL matches the pattern, capture groups are assigned to the named params[] keys (in order) as $_REQUEST entries.
Routing helpers
Section titled “Routing helpers”Router::getInstance()->currentPage(); / 'products'Router::getInstance()->tplName(); / 'products' (controller stem for templates)Router::getInstance()->getController(); / alias for currentPage()These are useful inside controllers and templates:
<a href="/products" class="{if Router::currentPage() == 'products'}active{/if}"> Products</a>(In Smarty you’d use a Smarty plugin or a pre-assigned variable; the helper itself is for PHP.)
Forwarding
Section titled “Forwarding”To redirect at the framework level (sets the right HTTP headers and exits):
View::forwardTo('/login');For a JSON response (sets Content-Type: application/json):
View::forwardToJsonHeader();View::assign(['data' => ['ok' => true]]);This pattern is used heavily by API endpoints in production — see the apiController in data.maschinen-stockert.de.
Pagination URLs
Section titled “Pagination URLs”Nibiru’s pagination expects URLs of the form:
/<controller>/<action>/page/<N>The Pageination class parses the trailing page/N segment, so any route format that preserves it is fine.
Trailing slashes & case
Section titled “Trailing slashes & case”URLs are matched case-sensitively. /Users/edit and /users/edit will hit different controllers (the second exists, the first 404s). Trailing slashes are tolerated.
Common pitfalls
Section titled “Common pitfalls”- Action collision with SEO URL. If you name a method
aboutAction()and try to use/products/about/42as an SEO URL, the SEO rewrite won’t trigger, becauseaboutis a known action. Pick slugs that don’t collide with action names. - Action without
_action. Just typing/products/detail/does not calldetailAction()—_actionmust be set. The dispatcher does this automatically when the URL has at least two segments, but a stripped query string won’t. indexis the root controller./→indexController. There is no separate “home” route.