Skip to content

PageModel

Das PageModel ist das zentrale Datenmodell für Seiten in CrispyCMS. Es repräsentiert eine einzelne Seite mit allen ihren Eigenschaften, Metadaten und Beziehungen zu anderen Entitäten wie Templates und Kategorien.

Namespace

Crispy\Models\PageModel

JSON-Repräsentation in Templates

In Twig-Templates ist das PageModel als JSON-Variable Page verfügbar und enthält folgende Struktur:

{
    "id": 0,
    "name": "Initial Page",
    "content": "CrispCMS has been installed!",
    "author": 0,
    "isPrivate": false,
    "properties": 5,
    "coverImage": "/assets/ugc/uploaded/foo.jpg",
    "template": {
        "id": 0,
        "name": "Initial Template",
        "content": "*** TEMPLATE CONTENT ***",
        "author": 0,
        "directory": "",
        "properties": null,
        "layout": {
            "id": 0,
            "name": "Initial Layout",
            "content": "*** LAYOUT CONTENT ***",
            "author": 0,
            "slug": "initial",
            "createdAt": 1738498649,
            "updatedAt": 1755720601
        },
        "slug": "test",
        "path": "test.twig",
        "createdAt": 1738498762,
        "updatedAt": 1755720601
    },
    "slug": "initial-page-0",
    "updateEmbedding": true,
    "computedUrl": "foo/initial-page-0",
    "fullUrl": "https://example.com/foo/initial-page-0",
    "category": {
        "id": 1,
        "name": "Foo",
        "properties": 1,
        "slug": "foo",
        "parent": null,
        "createdAt": 1755713361,
        "updatedAt": 1755720601
    },
    "createdAt": 1738498942,
    "updatedAt": 1755720570
}

Verfügbare Getter-Methoden

getId() Integer|null

Gibt die eindeutige ID der Seite zurück.

Die ID wird automatisch von der Datenbank vergeben und ist null für noch nicht gespeicherte Seiten.

Beispiel
{% if Page.id %}
    <p>Seiten-ID: {{ Page.id }}</p>
{% else %}
    <p>Neue Seite (noch nicht gespeichert)</p>
{% endif %}
<?php

$pageId = $pageModel->getId();

if ($pageId !== null) {
    echo "Seiten-ID: " . $pageId;
} else {
    echo "Neue Seite";
}
getName() String

Gibt den Namen/Titel der Seite zurück.

Der Name wird als Seitentitel in der Administration und in Templates verwendet.

Beispiel
<h1>{{ Page.name }}</h1>
<title>{{ Page.name }} - {{ config.CMSControl_SiteName }}</title>
<?php

$pageTitle = $pageModel->getName();
echo "<h1>" . htmlspecialchars($pageTitle) . "</h1>";
getContent() String|null

Gibt den HTML-Inhalt der Seite zurück.

Der Inhalt kann HTML-Tags enthalten und wird normalerweise durch einen Rich-Text-Editor erstellt.

Beispiel
<div class="page-content">
    {{ Page.content|raw }}
</div>

{# Textversion ohne HTML #}
<meta name="description" content="{{ Page.content|striptags|truncate(160) }}">
<?php

$content = $pageModel->getContent();

if ($content) {
    echo '<div class="content">' . $content . '</div>';
} else {
    echo '<p>Kein Inhalt verfügbar</p>';
}
getAuthor() Integer

Gibt die Benutzer-ID des Autors zurück.

Diese ID referenziert einen Benutzer in der Benutzertabelle.

Beispiel
<p>Erstellt von Benutzer-ID: {{ Page.author }}</p>
<?php

$authorId = $pageModel->getAuthor();
$user = UserModel::getById($authorId);

echo "Autor: " . $user->getName();
getCoverImage() String

Gibt das Cover Image der Seite zurück.

Beispiel
<img src="{{ Page.coverImage }}"></img>
<?php
$coverImage = $pageModel->getCoverImage();
getSlug() String

Gibt den URL-Slug der Seite zurück.

Der Slug ist der URL-freundliche Bezeichner für die Seite (ohne Kategorie-Pfad).

Beispiel
<link rel="canonical" href="{{ Page.fullUrl }}">

{# Nur der Slug #}
<p>Seiten-Slug: {{ Page.slug }}</p>
<?php

$slug = $pageModel->getSlug();
echo "URL-Slug: " . $slug;
getComputedUrl() String

Gibt die vollständige relative URL der Seite zurück.

Diese URL enthält den gesamten Kategorie-Pfad plus den Seiten-Slug.

Beispiel
<a href="/{{ Page.computedUrl }}">Link zur Seite</a>

{# Breadcrumb aus URL erstellen #}
{% set segments = Page.computedUrl|split('/') %}
{% for segment in segments %}
    <span class="breadcrumb-item">{{ segment }}</span>
{% endfor %}
<?php

$relativeUrl = $pageModel->getComputedUrl();
echo '<a href="/' . $relativeUrl . '">Zur Seite</a>';
getFullUrl() String

Gibt die vollständige absolute URL der Seite zurück.

Diese URL enthält Protokoll, Domain und den vollständigen Pfad.

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

{# Für Social Media Sharing #}
<a href="{{ Page.fullUrl }}" target="_blank">Seite in neuem Tab öffnen</a>
<?php

$absoluteUrl = $pageModel->getFullUrl();
echo '<meta property="og:url" content="' . $absoluteUrl . '">';
getTemplate() TemplateModel|null

Gibt das zugewiesene Template-Objekt zurück.

Das Template bestimmt das Layout und die Struktur der Seite. Das Template-Objekt enthält auch Informationen über das zugeordnete Layout.

Beispiel
{% if Page.template %}
    <p>Template: {{ Page.template.name }}</p>
    <body class="template-{{ Page.template.slug }}">

    {# Zugriff auf Template-Inhalte #}
    <div class="template-info">
        <p>Template-Pfad: {{ Page.template.path }}</p>
        <p>Verzeichnis: {{ Page.template.directory }}</p>
    </div>

    {# Layout-Informationen #}
    {% if Page.template.layout %}
        <body class="layout-{{ Page.template.layout.slug }}">
        <p>Layout: {{ Page.template.layout.name }}</p>
    {% endif %}
{% endif %}
<?php

$template = $pageModel->getTemplate();

if ($template) {
    echo "Template: " . $template->getName();
    echo "Template-Slug: " . $template->getSlug();
    echo "Template-Pfad: " . $template->getPath();

    $layout = $template->getLayout();
    if ($layout) {
        echo "Layout: " . $layout->getName();
        echo "Layout-Slug: " . $layout->getSlug();
    }
}
getCategory() CategoryModel|null

Gibt die zugewiesene Kategorie zurück.

Kategorien organisieren Seiten hierarchisch und beeinflussen die URL-Struktur. Kategorien können Unterkategorien haben (parent-child Beziehung).

Beispiel
{% if Page.category %}
    <nav class="breadcrumb">
        {# Übergeordnete Kategorie anzeigen falls vorhanden #}
        {% if Page.category.parent %}
            <a href="/{{ Page.category.parent.slug }}">{{ Page.category.parent.name }}</a>
            <span> / </span>
        {% endif %}

        <a href="/{{ Page.category.slug }}">{{ Page.category.name }}</a>
        <span> / {{ Page.name }}</span>
    </nav>

    {# Kategorie-Eigenschaften #}
    <div class="category-info">
        <p>Kategorie-ID: {{ Page.category.id }}</p>
        <p>Eigenschaften: {{ Page.category.properties }}</p>
        <p>Erstellt: {{ Page.category.createdAt|date('d.m.Y') }}</p>
    </div>
{% endif %}
<?php

$category = $pageModel->getCategory();

if ($category) {
    echo "Kategorie: " . $category->getName();
    echo "Kategorie-Slug: " . $category->getSlug();
    echo "Eigenschaften: " . $category->getProperties();

    $parent = $category->getParent();
    if ($parent) {
        echo "Übergeordnete Kategorie: " . $parent->getName();
    }
}
getProperties() Integer

Gibt die Eigenschaften der Seite als Bitmaske zurück.

Eigenschaften sind kombinierbare Flags wie Sichtbarkeit, Startseite, etc.

Beispiel
<p>Eigenschaften-Wert: {{ Page.properties }}</p>

{# Prüfung auf spezielle Eigenschaften #}
{% if Page.isPrivate %}
    <span class="badge bg-warning">Privat</span>
{% endif %}
<?php

$properties = $pageModel->getProperties();
echo "Eigenschaften: " . $properties;

// Prüfung auf spezifische Eigenschaften
if ($pageModel->hasProperty(PageProperties::VISIBILITY_PRIVATE)) {
    echo "Diese Seite ist privat";
}
getCreatedAt() Carbon|null

Gibt das Erstellungsdatum der Seite zurück.

Verwendet die Carbon-Bibliothek für erweiterte Datums-/Zeitfunktionen.

Beispiel
{# Unix-Timestamp aus JSON verwenden #}
<p>Erstellt am: {{ Page.createdAt|date('d.m.Y H:i') }}</p>

{# Relative Zeit anzeigen #}
<time datetime="{{ Page.createdAt|date('c') }}">
    vor {{ "now"|date('U') - Page.createdAt }} Sekunden
</time>
<?php

$createdAt = $pageModel->getCreatedAt();

if ($createdAt) {
    echo "Erstellt: " . $createdAt->format('d.m.Y H:i');
    echo "Vor " . $createdAt->diffForHumans();
}
getUpdatedAt() Carbon|null

Gibt das letzte Änderungsdatum der Seite zurück.

Wird automatisch aktualisiert, wenn die Seite bearbeitet wird.

Beispiel
<p>Zuletzt geändert: {{ Page.updatedAt|date('d.m.Y H:i') }}</p>

{# Nur anzeigen wenn unterschiedlich zum Erstellungsdatum #}
{% if Page.updatedAt != Page.createdAt %}
    <small class="text-muted">Bearbeitet am {{ Page.updatedAt|date('d.m.Y') }}</small>
{% endif %}
<?php

$updatedAt = $pageModel->getUpdatedAt();
$createdAt = $pageModel->getCreatedAt();

if ($updatedAt && !$updatedAt->eq($createdAt)) {
    echo "Zuletzt bearbeitet: " . $updatedAt->format('d.m.Y H:i');
}
getEmbedding() Array|null

Gibt den AI-Embedding-Vektor der Seite zurück.

Embeddings werden für semantische Suche und AI-Features verwendet (OpenAI Integration).

Beispiel
{% if Page.embedding %}
    <p>AI-Embedding verfügbar ({{ Page.embedding|length }} Dimensionen)</p>
{% else %}
    <p>Kein AI-Embedding verfügbar</p>
{% endif %}
<?php

$embedding = $pageModel->getEmbedding();

if ($embedding) {
    echo "Embedding-Dimensionen: " . count($embedding);
    // Für AI-basierte Ähnlichkeitssuche verwenden
}

Status-Prüfungen

isPrivate() Boolean

Prüft, ob die Seite privat ist.

Eine Seite ist privat, wenn sie selbst als privat markiert ist oder ihre Kategorie privat ist.

Beispiel
{% if not Page.isPrivate %}
    <!-- Öffentliche Inhalte anzeigen -->
    <div class="public-content">{{ Page.content|raw }}</div>
{% else %}
    <div class="alert alert-warning">
        Diese Seite ist nicht öffentlich zugänglich.
    </div>
{% endif %}
<?php

if (!$pageModel->isPrivate()) {
    // Seite für alle Benutzer anzeigen
    renderPublicContent($pageModel);
} else {
    // Zugriffskontrolle prüfen
    checkUserPermissions();
}
hasProperty(PageProperties $property) Boolean

Prüft, ob die Seite eine bestimmte Eigenschaft besitzt.

Eigenschaften werden als Bitflags gespeichert und können kombiniert werden.

Beispiel
{# In Template nicht direkt verfügbar, aber über JSON-Daten abfragbar #}
{% if Page.properties == 1 %}
    <span class="badge bg-info">Startseite</span>
{% endif %}
<?php

use Crispy\Enums\PageProperties;

if ($pageModel->hasProperty(PageProperties::OPTION_FRONTPAGE)) {
    echo '<span class="badge">Startseite</span>';
}

if ($pageModel->hasProperty(PageProperties::VISIBILITY_PRIVATE)) {
    echo '<span class="badge">Privat</span>';
}

if ($pageModel->hasProperty(PageProperties::OPTION_NOT_FOUND)) {
    echo '<span class="badge">404-Seite</span>';
}

Verwendung in Templates

Das PageModel ist in Templates als JSON-Variable verfügbar:

{# Vollständige Seiten-Metadaten #}
<head>
    <title>{{ Page.name }} - {{ config.CMSControl_SiteName }}</title>
    <meta name="description" content="{{ Page.content|striptags|truncate(160) }}">
    <meta property="og:title" content="{{ Page.name }}">
    <meta property="og:url" content="{{ Page.fullUrl }}">
    <link rel="canonical" href="{{ Page.fullUrl }}">
</head>

{# Breadcrumb Navigation #}
<nav aria-label="breadcrumb">
    <ol class="breadcrumb">
        <li class="breadcrumb-item"><a href="/">Home</a></li>
        {% if Page.category %}
            <li class="breadcrumb-item">
                <a href="/{{ Page.category.slug }}">{{ Page.category.name }}</a>
            </li>
        {% endif %}
        <li class="breadcrumb-item active">{{ Page.name }}</li>
    </ol>
</nav>

{# Hauptinhalt #}
<article>
    <header>
        <h1>{{ Page.name }}</h1>
        <time datetime="{{ Page.createdAt|date('c') }}">
            {{ Page.createdAt|date('d.m.Y') }}
        </time>
    </header>

    <div class="content">
        {{ Page.content|raw }}
    </div>

    <footer>
        {% if Page.updatedAt != Page.createdAt %}
            <p><small>Zuletzt bearbeitet: {{ Page.updatedAt|date('d.m.Y') }}</small></p>
        {% endif %}
    </footer>
</article>

{# Bedingte Anzeige basierend auf Eigenschaften #}
{% if Page.isPrivate %}
    <div class="alert alert-info">
        <i class="fas fa-lock"></i> Diese Seite ist nur für angemeldete Benutzer sichtbar.
    </div>
{% endif %}

{# Template-spezifische Styles #}
{% if Page.template %}
    <body class="template-{{ Page.template.slug }}">
{% endif %}

Hinweise

  • JSON-Format: In Templates ist das PageModel als JSON verfügbar, nicht als PHP-Objekt
  • Zeitstempel: Datums-/Zeitwerte werden als Unix-Timestamps übertragen
  • Embedding: AI-Embeddings sind optional und nur bei aktivierter OpenAI-Integration verfügbar
  • URLs: Die computedUrl wird automatisch aus Kategorie-Hierarchie und Slug berechnet
  • Eigenschaften: Properties sind Bitflags und können kombiniert werden
  • Sicherheit: Private Seiten sollten serverseitig validiert werden