---
title: "Schnellstart"
description: "Erstellen Sie eine minimale Produkte-Seite in fünf Minuten – Controller, Ansicht, Navigations-Eintrag."
---

Am Ende dieser Seite haben Sie eine funktionierende `/products`-Seite, die von Smarty gerendert wird, die durch einen Controller gefüttert und im Seitenleisten-Menü aufgelistet ist.

## 1. Erstellen Sie einen Controller
```bash
./nibiru -c products
```
Dies erstellt zwei Dateien:
```
application/controller/productsController.php
application/view/templates/products.tpl
```
## 2. Verbinden Sie den Controller

Öffnen Sie `productsController.php` und ersetzen Sie den Inhalt durch:
```php
<?php
namespace Nibiru;
use Nibiru\Adapter\Controller;

class productsController extends Controller
{
    public function pageAction()
    {
        View::assign([
            'title'    => 'Products — Nibiru',
            'products' => [
                ['id' => 1, 'name' => 'Marduk Gold Plating', 'price' => 99.0],
                ['id' => 2, 'name' => 'Tiamat Hull Sealant', 'price' => 49.0],
                ['id' => 3, 'name' => 'Anu Stardust Polish', 'price' => 19.5],
            ],
            'css' => Config::getInstance()->getConfig()[View::NIBIRU_SETTINGS]['smarty.css'],
            'js'  => Config::getInstance()->getConfig()[View::NIBIRU_SETTINGS]['smarty.js'],
        ]);
    }

    public function navigationAction()
    {
        JsonNavigation::getInstance()->loadJsonNavigationArray();
    }
}
```
Zwei Methoden sind konventionell und werden **immer aufgerufen** durch den [Dispatcher](/core/dispatcher/):

- `navigationAction()` — füllt das globale Navigationsmenü auf.
- `pageAction()` — rendert die Seite selbst.

Alles, was `?_action=foo` entspricht, wird zusätzliche eine `fooAction()`-Methode aufrufen.

## 3. Schreiben Sie die Ansicht

Öffnen Sie `application/view/templates/products.tpl`:
```smarty
{include 'shared/header.tpl'}
<body>
{include file="navigation.tpl"}

<main class="container">
  <h1>{$title}</h1>

  <table class="table">
    <thead>
      <tr><th>#</th><th>Name</th><th>Price</th></tr>
    </thead>
    <tbody>
      {foreach $products as $p}
        <tr>
          <td>{$p.id}</td>
          <td><a href="/products/detail/{$p.id}">{$p.name|escape}</a></td>
          <td>{$p.price|string_format:"%.2f"} €</td>
        </tr>
      {/foreach}
    </tbody>
  </table>
</main>

{include 'shared/footer.tpl'}
</body>
```
Variablen, die an `View::assign()` übergeben werden, erscheinen als `{$variable}` in Smarty.

## 4. Fügen Sie einen Navigationseintrag hinzu

Bearbeiten Sie `application/settings/config/navigation/main.json` und fügen Sie hinzu:
```json
{
  "label": "Products",
  "href":  "/products",
  "icon":  "shopping-bag"
}
```
Die Navigation wird von `JsonNavigation` geladen und mit `navigation.tpl` gerendert.

## 5. Führen Sie es aus

Falls Sie den eingebauten Server von PHP zur Verfügung haben:
```bash
APPLICATION_ENV=development php -S localhost:8080 -t .
```
Besuchen Sie <http://localhost:8080/products/>. Sie sollten Ihre drei Produkte mit dem kosmischen Thema Ihres CSS sehen.

## Eine Detailseite hinzufügen

Im gleichen Controller:
```php
public function detailAction()
{
    $id = (int) ($_REQUEST['id'] ?? 0);
    View::assign([
        'title' => "Product #$id",
        'id'    => $id,
    ]);
}
```
`Router` versteht bereits `/products/detail/42` und `/products/marduk-gold-plating/42` (SEO-URL-Form – `id` und `slug` werden automatisch in `$_REQUEST` aufgefüllt).

Erstellen Sie `application/view/templates/products/detail.tpl` mit beliebiger Markupsprache, und Sie haben eine zweiseitige Anwendung.

## Wo geht's weiter?

- [Architektur (MMVC)](/core/architecture/) — wie alle beweglichen Teile zusammenpassen.
- [Module](/core/modules/) — wann man von Controllern und Traits zu einem echten Modul wechselt.
- [Datenbank & Migrationen](/core/database/) — verbinde die Seite mit einer tatsächlichen `products` Tabelle.
