Seiten-Inhalte

Page

Bisher ist unsere Seite noch sehr leer. Es fehlt an Inhalten. Inhalte werden mit n2n Rocket über Content Items gelöst. Content Items sind Inhalts-Bausteine, aus welchen Inhalte zum Beispiel für unsere Seiten zusammen gebaut werden können.

  1. Content Items erstellen
  2. Content Items registrieren
  3. Panels registrieren
  4. Views anpassen

Früher war es üblich, dass man für Seiten einfach einen HTML Editor zur Verfügung gestellt hat. Darin konnte der Content Editor alles machen: grelle Farben, Tabellen zu Layout-Zwecken missbrauchen, Bilder, Youtube Videos. Wir brauchen dir nicht zu sagen, wie der generierte HTML Code schlussendlich aussah. Kannst du dir vorstellen eine solche Seite responsive anzubieten?

Aus diesem Grund sind wir auf das Konzept der Content Items umgestiegen. Content Items sind Definitionen von bestimmten Inhaltsblöcken. Das Content Item CiArticle, welches wir gleich erstellen werden, besteht beispielsweise immer aus einem Bild, Titel und einer Beschreibung. Dank diesen Inhaltsblöcken kannst du die Funktionen, welche im HTML Editor angeboten werden müssen, deutlich reduzieren. Wir erlauben beispielsweise keine Einbindung mehr von Bilder im HTML-Editor. Den einzelnen Content Items können wir dann Regeln hinterlegen, wie sie auf den verschiedenen Bildschirmgrössen ausgegeben werden sollen.

Content Items gehören zum Konzept von Rocket. Content Items können darum für alle Business Objects verwendet werden, welche mit Rocket verwaltet werden.

Content Items erstellen

Weil Content Items nicht nur für Seiten verwendet werden, erstellen wir ein eigenes Modul. Du wirst dieses für die meisten deiner Projekte verwenden können! Für das neue Modul (Namespace ci) legen wir wieder die drei bekannten Verzeichnisse an:

  • app/ci
  • var/etc/ci
  • public/assets/ci

Content Items speichern wir wie unsere BusinessObjects unter app/ci/bo. Erstelle die Content Items CiArticle, CiAttachment, CiImage, CiWysiwyg. Wir stellen sie dir hier zum Download zur Verfügung:

ContentItems.zip

Alle Content Items in einem ZIP File

Die Content Items erben nicht von EntityAdapter, sondern von ContentItem. Trotzdem funktionieren sie praktisch gleich. Es gibt eine Ausnahme: die Methode createUiComponent(). Diese Methode gibt den HTML Code für die Ausgabe zurück. Dies kann auf zwei verschiedene Arten geschehen:

  1. Das Content Item erstellt selber ein HtmlElement und gibt dieses zurück. CiWysiwyg und CiAttachment sind Beispiele für diese Methode.
  2. Das Content Item ruft eine View auf und gibt diese zurück. Das kannst du in CiImage und CiArticle beobachten.
CiWysiwyg->contentHtml bearbeiten wir in Rocket. Wir können die Eigenschaft nicht direkt ausgeben, weil Rocket Links (zum Beispiel auf Pages) codiert speichert. Darum funktioniert new HtmlElement('div', null, $this->contentHtml) nicht. Um die Links zu decoden, braucht es den WysiwygHtmlBuilder. Dies gilt für jede Html Eigenschaft, welche generierte Links beinhalten kann.

Nun müssen wir noch die Views für CiImage und CiArticle erstellen:

app/ci/view/article.html.php schaut so aus:

<?php
    use n2n\impl\web\ui\view\html\HtmlView;
    use n2n\web\ui\view\View;
    use ci\bo\CiArticle;
    use rocket\spec\ei\component\field\impl\string\wysiwyg\WysiwygHtmlBuilder;
    use n2n\io\managed\img\impl\ThSt;

    $view = HtmlView::view($this);
    $html = HtmlView::html($view);
    
    $article = $view->getParam('article');
    $view->assert($article instanceof CiArticle);
    
    $htmlWysiwyg = new WysiwygHtmlBuilder($view);

?>
<article class="ci ci-article row">
    <div class="col-sm-4">
        <?php $html->image($article->getFileImage(), ThSt::crop(400, 300), array('class' => 'img-fluid')) ?>
    </div>
    <div class="col-sm-8">
        <h2><?php $html->out($article->getTitle()) ?></h2>
        <?php $htmlWysiwyg->out($article->getDescriptionHtml()) ?>
    </div>
</article>

app/ci/view/image.html.php ist nicht komplizierter:

<?php
    use n2n\impl\web\ui\view\html\HtmlView;
    use n2n\web\ui\view\View;
    use ci\bo\CiImage;
    use n2n\io\managed\img\impl\ThSt;

    $view = HtmlView::view($this);
    $html = HtmlView::html($view);
    
    $image = $view->getParam('image');
    $view->assert($image instanceof CiImage);
    
?>
<figure class="ci ci-image">
    <?php $html->image($image->getFileImage(), ThSt::prop(600, 400)) ?>
    <?php if (null !== ($title = $image->getTitle())): ?>
        <figcaption><?php $html->out($title) ?></figcaption>
    <?php endif; ?>
</figure>

Damit die ContentItems auch gespeichert werden können, musst du die entsprechenden Datentabellen auf deiner Datenbank eröffnen. Führe dazu die CREATE Statements aus dem folgenden SQL File aus:

ContentItems.sql

CREATE Statements für die Content Items

Content Items registrieren

Alle Entitäten müssen in n2n registriert werden. Wir eröffnen dazu var/etc/ci/app.ini mit folgendem Inhalt:

[orm]
entities[] = "ci\bo\CiWysiwyg"
entities[] = "ci\bo\CiImage"
entities[] = "ci\bo\CiArticle"
entities[] = "ci\bo\CiAttachment"

EiSpecs erstellen

Dieser Abschnitt wiederholt EiSpec erstellen aus dem Rocket Quickstart. Wir gehen darum nicht nochmals auf die Details ein. Starte den Hangar von deinem Projekt:

http://localhost/[pfad-zu-deinem-projekt]/hangar/

Zuerst müssen wir unter den Entitäten die EiSpecs für Rocket erstellen. Dies machen wir, indem wir in Hangar die Content Item Klassen unter den Entitäten suchen, Rechts-klicken und Generate EiSpec klicken.

Jetzt ist es wichtig, dass du bei jeder EiSpec folgende Schritte ausführst:

  • General: korrekte Labels aussuchen. Beispiel: "Ci Wysiwyg" ist ein schlechtes Label für deine Content Editoren. Wir schlagen "Freitext" vor.
  • Fields: Klicke auf "add auto EiFields", um die Eigenschaften der Content Items zu erkennen
  • Fields: Jetzt kontrolliere alle Eigenschaften der Felder. Welche Felder müssen obligatorisch (mandatory) sein? Beachte, dass CiArticle, CiImage und CiAttachment zwingend ein File brauchen. Wo hast du String Felder mit begrenzten Längen? Beim Attachment könntest du die erlaubten Formate begrenzen.
  • Speichere alles (Save all)
Beachte, dass Content Items nicht wie BusinessObjects in einer Übersicht und Detailansicht angezeigt werden. Einige Konfigurationsmöglichkeiten unter EiSpec sind deshalb irrelevant. Zum Beispiel "Show in overview".

Der Hangar hat dir jetzt var/etc/ci/rocket/specs.json gespeichert. Du kannst sie mit unseren vergleichen:

specs.json

EiSpecs für Rocket

Panels registrieren

Wir wollen mit Content Items Seiteninhalte erfassen. Content Items werden in Panels ausgegeben. Bisher haben wir aber noch keine Panels registriert. Für die Anzeige unserer Seiten haben wir app/template/TemplatePageController erstellt. Um unsere Pannels zu registrieren, kannst du die Annotations-Methode von TemplatePageController wie folgt anpassen:

    private static function _annos(AnnoInit $ai) {
        $ai->m('startPage', new AnnoPage(), new AnnoPageCiPanels('hero', 'main'));
        $ai->m('standardPage', new AnnoPage(), new AnnoPageCiPanels('main'));
    }

Wir fügen einfach eine zweite Annotation AnnoPageCiPanels() hinzu. Als Parameter geben wir die Namen all unserer Panels mit.

Mit n2n kannst du Panels genau konfigurieren. In unserem Hero-Panel auf der Startseite macht beispielsweise nur ein einziges CiWysiwyg Sinn. Über die Konfiguration von Content-Item-Panels kannst du genau bestimmen, wie viele Content Items ein Panel haben darf und welche Content Items erlaubt sind.
Schaffst du es, das Panel 'hero' so zu konfigurieren, dass nur ein Content Item darin platziert werden kann?

Wenn du jetzt ins Rocket gehst und die Startseite oder eine Contentseite bearbeitest, kannst du bei diesen Seiten die Panels mit Content Items befüllen. Damit die Inhalte unserer Panels aber ausgegeben werden, müssen wir die Views anpassen.

Views anpassen

Unsere Seiten werden von app/template/TemplatePageController ausgegeben. Dieser ruft wiederum  app/template/view/startPage.html.php und app/template/view/standardPage.html.php auf. Hier müssen wir die Content Items nun auslesen.

app/template/view/startPage.html.php schaut neu so aus:

<?php
    use n2n\impl\web\ui\view\html\HtmlView;
    use n2n\web\ui\view\View;
    use page\ui\PageHtmlBuilder;

    $view = HtmlView::view($view);
    $pageHtml = new PageHtmlBuilder($view);
    
    $view->useTemplate('boilerplate.html');
?>
<div class="jumbotron">
    <div class="container">
        <h1><?php $pageHtml->title() ?></h1>
        <?php $pageHtml->contentItems('hero') ?>
    </div>
</div>

<div class="container">
    <?php $pageHtml->contentItems('main') ?>
</div>

Das einzige was sich verändert hat, ist dass wir $pageHtml->contentItems() zweimal eingebaut haben. In app/template/view/standardPage.html.php ist die Anpassung analog:

<?php
    use n2n\impl\web\ui\view\html\HtmlView;
    use n2n\web\ui\view\View;
    use page\ui\PageHtmlBuilder;

    $view = HtmlView::view($view);
    $pageHtml = new PageHtmlBuilder($view);
    
    $view->useTemplate('boilerplate.html');
?>
<div class="container">
    <h1><?php $pageHtml->title() ?></h1>
    <?php $pageHtml->contentItems('main') ?>
</div>

Hier müssen wir nur einmal die Content Items einbauen. $pageHtml->contentItems() macht nichts anders, als über die angehängten Content Items zu iterieren und die HTML Ausgaben zusammen zu setzen.

Wenn du soweit bist, kannst du das Page Modul einmal ausführlich testen, indem du den verschiedenen Seiten Inhalte hinzufügst. Ebenfalls ist es natürlich denkbar, dass du eigene Content Items entwickelst und verwendest!

Wenn du das Composer Projekt für den Quickstart Page installiert hast, findest du die Musterlösung für die Content Items unter app\qsci. Jetzt stimmt auch der Stand von qst\controller\QstPageController und den Views überein.
« Seiten und Templates Controller einbinden »

Kommentare

Du musst eingeloggt sein, damit du Beiträge erstellen kannst.

Fragen