Search Documentation

Search for pages and headings in the documentation

PageModel

Das PageModel ist das Herzstück der Inhaltsverwaltung in CrispyCMS. Es repräsentiert eine einzelne Seite (Page) und bündelt sämtliche relevanten Daten – vom eigentlichen HTML-Inhalt über SEO-Metadaten bis hin zu komplexen Beziehungen wie verknüpften Templates oder Kategorien.

In der Backend-Logik (PHP) arbeiten Sie mit einer Instanz der Klasse. Im Frontend (Twig) wird dieses Modell automatisch in ein performantes JSON-Objekt umgewandelt, das direkten Zugriff auf alle Eigenschaften bietet.

Namespace

Crispy\Models\PageModel

Datenstruktur in Templates

In Ihren Twig-Templates steht das PageModel standardmäßig als globale Variable Page zur Verfügung. Anders als in PHP handelt es sich hierbei nicht um ein Objekt mit Methoden, sondern um ein strukturiertes JSON-Objekt.

Das folgende Beispiel zeigt die typische Struktur eines solchen Objekts:

{
    "id": 105,
    "name": "Willkommen",
    "content": "<h1>CrispyCMS ist installiert!</h1><p>Starten Sie jetzt...</p>",
    "author": 1,
    "isPrivate": false,
    "properties": 5,
    "coverImage": "/assets/ugc/header.jpg",
    "template": {
        "id": 12,
        "name": "Standard Layout",
        "path": "default.twig",
        "layout": {
            "slug": "full-width"
        }
    },
    "slug": "willkommen",
    "computedUrl": "home/willkommen",
    "fullUrl": "[https://example.com/home/willkommen](https://example.com/home/willkommen)",
    "category": {
        "id": 1,
        "name": "Home",
        "slug": "home"
    },
    "createdAt": 1738498942,
    "updatedAt": 1755720570
}

Identifikation & Inhalt

Diese Methoden dienen dem Zugriff auf die primären Inhalte und Identifikationsmerkmale einer Seite.

getId Integer | null

Liefert die eindeutige Datenbank-ID der Seite. Bei neu instanziierten, noch nicht gespeicherten Objekten ist dieser Wert null.

getName String

Gibt den Titel der Seite zurück. Dieser wird sowohl für die Darstellung in der Navigation als auch für den <title>-Tag verwendet.

getContent String | null

Liefert den eigentlichen HTML-Inhalt der Seite, der meist über den WYSIWYG-Editor gepflegt wird.

getCoverImage String

Gibt den relativen Pfad zum konfigurierten Titelbild der Seite zurück.

{% if Page.coverImage %}
    <div class="hero-image" style="background-image: url('{{ Page.coverImage }}');"></div>
{% endif %}

Routing & URLs

CrispyCMS berechnet URLs automatisch basierend auf der Kategorie-Hierarchie.

getSlug String

Der URL-freundliche Bezeichner der Seite selbst (z.B. kontakt), ohne übergeordnete Pfade.

getComputedUrl String

Die vollständige relative URL, zusammengesetzt aus dem Kategorie-Pfad und dem Seiten-Slug. Ideal für interne Verlinkungen.

getFullUrl String

Die absolute URL inklusive Protokoll (https) und Domain. Wichtig für SEO (Canonical Tags) und Social Sharing (OpenGraph).

<link rel="canonical" href="{{ Page.fullUrl }}">
<meta property="og:url" content="{{ Page.fullUrl }}">

Beziehungen

Seiten existieren selten isoliert. Diese Methoden geben Zugriff auf verknüpfte Objekte.

getCategory CategoryModel

Gibt das verknüpfte Kategorie-Objekt zurück. Dies ermöglicht den Zugriff auf die Hierarchie (Parent-Category).

{% if Page.category %}
    <nav aria-label="breadcrumb">
        <ol>
            {% if Page.category.parent %}
                <li>{{ Page.category.parent.name }}</li>
            {% endif %}
            <li><a href="/{{ Page.category.slug }}">{{ Page.category.name }}</a></li>
            <li aria-current="page">{{ Page.name }}</li>
        </ol>
    </nav>
{% endif %}

getTemplate TemplateModel

Liefert das zugewiesene Template. Dies ist besonders nützlich, um Layout-Entscheidungen im Frontend basierend auf dem Template-Typ zu treffen.

{% if Page.template.slug == 'landing-page' %}
    {% include 'partials/hero-header.twig' %}
{% else %}
    {% include 'partials/standard-header.twig' %}
{% endif %}

Metadaten & Status

isPrivate Boolean

Prüft die Sichtbarkeit der Seite. Eine Seite gilt als “Privat”, wenn entweder sie selbst oder ihre zugewiesene Kategorie als privat markiert wurde.

{% if Page.isPrivate %}
    <Badge variant="destructive">
        <Icon name="lock" class="size-3 mr-1" /> Intern
    </Badge>
{% endif %}

getCreatedAt / getUpdatedAt Timestamp

In PHP geben diese Methoden Carbon-Objekte zurück. In der JSON-Repräsentation für Twig handelt es sich um Unix-Timestamps (Integer), die mit dem date-Filter formatiert werden müssen.

<footer>
    Erstellt: {{ Page.createdAt|date('d.m.Y') }}
    {% if Page.updatedAt > Page.createdAt %}
        (Aktualisiert: {{ Page.updatedAt|date('d.m.Y') }})
    {% endif %}
</footer>

getEmbedding Array

Gibt den Vektor (Embedding) der Seite zurück, falls die OpenAI-Integration aktiv ist.

$embedding = $pageModel->getEmbedding();
// Array mit Float-Werten, z.B. [0.0123, -0.234, ...]

Vollständiges Template-Beispiel

Hier sehen Sie, wie die verschiedenen Datenpunkte des PageModel in einem typischen HTML5-Gerüst zusammenkommen:

<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <title>{{ Page.name }} | Meine Website</title>
    
    {# SEO #}
    <meta name="description" content="{{ Page.content|striptags|truncate(160) }}">
    <link rel="canonical" href="{{ Page.fullUrl }}">
    
    {# Open Graph #}
    <meta property="og:title" content="{{ Page.name }}">
    <meta property="og:url" content="{{ Page.fullUrl }}">
    {% if Page.coverImage %}
        <meta property="og:image" content="{{ Page.coverImage }}">
    {% endif %}
</head>
<body class="page-{{ Page.id }} template-{{ Page.template.slug }}">

    <header>
        <h1>{{ Page.name }}</h1>
        {% if Page.isPrivate %}
            <span class="private-badge">Geschützter Bereich</span>
        {% endif %}
    </header>

    <main>
        {# Inhalt sicher ausgeben #}
        <div class="content-wrapper">
            {{ Page.content|raw }}
        </div>
    </main>

    <aside>
        <h3>Details</h3>
        <ul>
            <li>Kategorie: {{ Page.category.name }}</li>
            <li>Autor-ID: {{ Page.author }}</li>
            <li>Erstellt am: {{ Page.createdAt|date('d.m.Y H:i') }}</li>
        </ul>
    </aside>

</body>
</html>