Hyvä CMS-Blöcke und Widgets im Theme gestalten
AI generated
Hyvä
phtml
Hyvä · CMS · Widgets · Magento 2
Hyvä CMS-Blöcke und Widgets im Theme gestalten
ohne Luma-Reste, mit Tailwind statt Inline-Chaos

Redaktionelle Inhalte aus dem Admin landen in Hyvä ohne Knockout.js und ohne UI-Components direkt im Utility-First-Layout, was bedeutet, dass WYSIWYG-Markup gezielt mit Tailwind-Klassen versöhnt werden muss, statt einfach nur eingebunden zu werden. Wer Hyvä CMS-Blöcke und Widgets von Anfang an sauber strukturiert, spart sich CSP-Nacharbeiten, FPC-Invalidierungsprobleme und inkonsistente Typografie im späteren Betrieb.

14 Min. Lesezeit widget.xml · ViewModel · Tailwind Typography · FPC Magento 2.4.x · Hyvä Themes · Tailwind v4

1. Warum CMS-Blöcke und Widgets in Hyvä anders funktionieren als in Luma

Wer aus einem Luma-Projekt kommt, erwartet bei Hyvä CMS-Blöcken eine ähnliche Rendering-Kette wie gewohnt, findet aber ein grundlegend anderes Fundament vor. Hyvä verzichtet vollständig auf Knockout.js und UI-Components, was bedeutet, dass ein CMS-Block nicht länger in ein Geflecht aus data-bind-Attributen, Knockout-Templates und RequireJS-Modulen eingebettet wird. Stattdessen landet der gerenderte WYSIWYG-Content als reines HTML im Server-Side-Markup, direkt neben Tailwind-Utility-Klassen, ohne clientseitige Nachbearbeitung durch JavaScript-Frameworks.

Diese Vereinfachung bringt einen Zielkonflikt mit sich: Redakteure pflegen Inhalte im TinyMCE-Editor mit klassischen Inline-Styles und generischen Luma-CSS-Klassen wie .pagebuilder-column, während das Theme selbst konsequent auf Utility-First mit Tailwind setzt. Ohne gezielte Vorkehrungen prallt WYSIWYG-Markup ungefiltert auf ein Design-System, das keine dieser Legacy-Klassen kennt. Hyvä CMS-Blöcke müssen deshalb entweder über Tailwind-Typography-Klassen normalisiert oder durch eigene Templates ersetzt werden, damit Schriftgrößen, Abstände und Linkfarben zum restlichen Theme passen.

Der praktische Effekt: Wer Hyvä CMS-Blöcke naiv wie in Luma einbindet, bekommt entweder ungestylten Fließtext oder Layout-Brüche, sobald Redakteure Tabellen, Bilder oder verschachtelte Listen einfügen. Die folgenden Abschnitte zeigen, wie man CMS-Blöcke, Widgets und WYSIWYG-Content sauber in ein Hyvä-Theme integriert, von der Basis-Einbindung über eigene Widget-Typen bis zu Cache-Strategie und CSP-Sicherheit.

2. Grundlagen: CMS-Block-Widget in Hyvä einbinden

Der Standardweg, einen CMS-Block in Hyvä darzustellen, führt über das Widget Magento\Cms\Block\Widget\Block, das sowohl im Page-Builder-Content als auch direkt im Layout-XML nutzbar ist. Im Admin-WYSIWYG oder in statischem CMS-Content sieht der Aufruf so aus: {{widget type="Magento\Cms\Block\Widget\Block" block_id="footer-trust-badges"}}. Magento löst diesen Platzhalter zur Laufzeit auf, lädt den referenzierten Block über das BlockRepositoryInterface und rendert dessen Content-Feld als HTML an genau dieser Stelle im Fließtext.

Wichtig für Hyvä CMS-Blöcke ist, dass dieser Rendering-Pfad unabhängig vom Frontend-Framework funktioniert, weil die Widget-Auflösung serverseitig im Magento\Widget\Model\Template\Filter passiert, lange bevor Alpine.js oder Tailwind ins Spiel kommen. Im Theme selbst landet der Block meist über getChildBlock() oder direkt als eingebetteter Widget-Aufruf im CMS-Page-Content, wobei das umgebende phtml-Template dafür verantwortlich bleibt, den richtigen Tailwind-Kontext um den Block herum zu setzen.

Ein häufiger Anfängerfehler: Der Block wird per Layout-XML als eigenständiges cms/block.phtml eingebunden, aber ohne not-prose-Wrapper direkt in ein prose-Element gerendert, wodurch Tailwind Typography ungewollt auch auf Struktur-Divs wirkt, die eigentlich kein Fließtext sind. Für Hyvä CMS-Blöcke, die reine Layout-Elemente wie Banner oder Trust-Badge-Leisten enthalten, sollte deshalb bewusst zwischen Fließtext-Blöcken (mit prose) und Layout-Blöcken (mit not-prose) unterschieden werden.

3. Styling von WYSIWYG-Content mit Tailwind Typography

Das Plugin @tailwindcss/typography ist die zentrale Brücke zwischen redaktionellem WYSIWYG-Content und einem konsistenten Hyvä-Theme. Statt jede mögliche HTML-Struktur, die ein Redakteur im TinyMCE erzeugen könnte, einzeln mit Utility-Klassen zu stylen, wendet man die prose-Klasse auf den Container an und erhält automatisch sinnvolle Standardformatierung für Überschriften, Absätze, Listen, Zitate und Tabellen. Für Hyvä CMS-Blöcke mit gemischtem Content ist das der einzige praktikable Weg, weil Redakteure jederzeit neue Elemente einfügen können, ohne dass ein Entwickler nachträglich Klassen ergänzt.

Die Standard-Prose-Farben passen selten exakt zum Corporate Design, weshalb Theme-spezifische Overrides über die Tailwind-Konfiguration nötig sind. Mit prose-headings:text-slate-900, prose-a:text-orange-700 und prose-a:no-underline lassen sich Linkfarben und Überschriftenfarben gezielt an das Theme anpassen, ohne die restliche Typography-Logik zu verlieren. Für Hyvä CMS-Blöcke im Footer oder in Sidebar-Widgets empfiehlt sich zusätzlich eine kompaktere Variante wie prose-sm, da der volle prose-Umfang für schmale Spalten oft zu große Schriftgrade mitbringt.

Ein Detail, das in der Praxis oft übersehen wird: Bilder aus dem WYSIWYG-Editor kommen ohne max-width-Constraint und ohne height: auto, was in prose zwar meist korrigiert wird, in eigenen not-prose-Wrappern aber explizit nachgezogen werden muss. Die folgende Struktur zeigt ein typisches phtml-Fragment, das einen CMS-Block-Widget-Aufruf in einen typografisch korrekten Container einbettet.


<!-- template: Magento_Cms::block/wysiwyg-wrapper.phtml -->
<!-- Wrap widget-rendered CMS content in Tailwind Typography classes -->
<div class="prose prose-slate max-w-none
            prose-headings:text-slate-900 prose-headings:font-bold
            prose-a:text-orange-700 prose-a:no-underline hover:prose-a:underline
            prose-img:rounded-xl prose-img:shadow-sm
            prose-table:text-sm prose-th:bg-slate-100">
  <?= /* @noEscape */ $block->getChildHtml('cms-content-block') ?>
</div>

<!-- Sidebar variant: compact typography for narrow widget columns -->
<aside class="prose prose-sm prose-slate max-w-none prose-a:text-orange-700">
  <?= /* @noEscape */ $block->getChildHtml('sidebar-trust-block') ?>
</aside>

4. Eigene Widget-Typen für Hyvä registrieren

Der generische Block-Widget-Renderer reicht nicht mehr aus, sobald ein Widget eigene Parameter, eigene Logik oder ein eigenes Template benötigt, etwa ein "Aktuelle Angebote"-Banner mit konfigurierbarer Kategorie-ID. Für solche Fälle registriert man einen eigenen Widget-Typ über widget.xml im Modul-Verzeichnis, definiert dort die Parameter mit Typ, Label und Quelle, und verweist auf ein eigenes phtml-Template statt auf den Standard-Block-Renderer. Für Hyvä CMS-Blöcke und Widgets bedeutet das, dass das Template von Anfang an mit Tailwind-Klassen statt mit Luma-Widget-CSS geschrieben werden kann.

Wichtig ist, dass das Template-Attribut in widget.xml direkt auf das Hyvä-Theme-Template zeigt und keine zusätzliche Fallback-Logik für Luma-Widget-Templates mitgeschleppt wird. Parameter wie category_id oder display_mode werden per source_model mit Optionen befüllt, sodass Redakteure sie im Page-Builder oder WYSIWYG-Widget-Dialog komfortabel auswählen können, ohne IDs manuell eintippen zu müssen.


<!-- File: app/code/Mironsoft/CmsWidgets/etc/widget.xml -->
<!-- Custom widget type for Hyvä: category promo banner -->
<widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Widget:etc/widget.xsd">
    <widget id="mironsoft_category_promo" class="Mironsoft\CmsWidgets\Block\CategoryPromo"
            template="Mironsoft_CmsWidgets::widget/category-promo.phtml"
            is_email_compatible="false">
        <label translate="true">Category Promo Banner (Hyva)</label>
        <description translate="true">Promo banner for a category, styled with Tailwind.</description>
        <parameters>
            <parameter name="category_id" xsi:type="block" required="true" visible="true">
                <label translate="true">Category</label>
                <block class="Magento\Cms\Block\Adminhtml\Wysiwyg\Widget\Chooser">
                    <data>
                        <item name="button" xsi:type="array">
                            <item name="open" xsi:type="string" translate="true">Choose Category...</item>
                        </item>
                    </data>
                </block>
            </parameter>
            <parameter name="display_mode" xsi:type="select" required="true" visible="true">
                <label translate="true">Display Mode</label>
                <options>
                    <option name="banner" value="banner"><label translate="true">Banner</label></option>
                    <option name="card" value="card"><label translate="true">Card</label></option>
                </options>
            </parameter>
        </parameters>
    </widget>
</widgets>

5. CMS-Block per ViewModel injizieren statt Hardcoding im Template

Ein häufiges Antipattern in Hyvä-Projekten ist das direkte Laden eines CMS-Blocks per Magento\Cms\Model\BlockFactory mitten im phtml-Template. Das koppelt die Präsentation fest an die Datenbeschaffung und lässt sich weder unit-testen noch sauber per Layout-XML überschreiben. Stattdessen sollte ein Hyvä CMS-Block über ein ViewModel bereitgestellt werden, das als ArgumentInterface per Layout-XML in den jeweiligen Block injiziert wird, wie es dem Coding-Standard des Projekts entspricht.

Das ViewModel kapselt den Zugriff auf BlockRepositoryInterface, behandelt NoSuchEntityException sauber und liefert dem Template nur die benötigten, bereits aufbereiteten Daten. Das Template selbst bleibt frei von Geschäftslogik und fragt nur noch $viewModel->getBlockContent('trust-badges') ab. Diese Trennung erlaubt außerdem, den Layout-XML-Handle projektspezifisch zu variieren, ohne den ViewModel-Code anzufassen.


<?php
declare(strict_types=1);

namespace Mironsoft\CmsWidgets\ViewModel;

use Magento\Cms\Api\BlockRepositoryInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\View\Element\Block\ArgumentInterface;
use Psr\Log\LoggerInterface;

/**
 * ViewModel providing safe access to a CMS block's content by identifier.
 */
class CmsBlockContent implements ArgumentInterface
{
    /**
     * @param BlockRepositoryInterface $blockRepository CMS block repository
     * @param SearchCriteriaBuilder $searchCriteriaBuilder Builder for identifier-based lookups
     * @param LoggerInterface $logger Logger for missing-block diagnostics
     */
    public function __construct(
        private readonly BlockRepositoryInterface $blockRepository,
        private readonly SearchCriteriaBuilder $searchCriteriaBuilder,
        private readonly LoggerInterface $logger,
    ) {
    }

    /**
     * Returns the rendered HTML content of a CMS block by its identifier.
     *
     * @param string $identifier CMS block identifier
     * @return string Block content or empty string if not found or inactive
     */
    public function getBlockContent(string $identifier): string
    {
        $criteria = $this->searchCriteriaBuilder
            ->addFilter('identifier', $identifier)
            ->addFilter('is_active', 1)
            ->create();

        $items = $this->blockRepository->getList($criteria)->getItems();
        $block = reset($items);

        if ($block === false) {
            $this->logger->warning(sprintf('CMS block "%s" not found or inactive.', $identifier));
            return '';
        }

        return (string) $block->getContent();
    }
}

6. Dynamic und Static Blocks für wiederverwendbare Content-Snippets

Trust-Badges, Versandhinweise, saisonale Banner und rechtliche Hinweistexte ändern sich häufiger als der Code, der sie umgibt, weshalb sie idealerweise als Static Blocks im Admin gepflegt werden statt hartcodiert im Template zu stehen. Für Hyvä CMS-Blöcke dieser Art gilt: Der Block selbst enthält nur den redaktionellen Inhalt, während Layout, Grid-Struktur und responsive Verhalten im umgebenden phtml-Template mit Tailwind-Klassen definiert werden. So kann Marketing den Text im Static Block ändern, ohne dass ein Deployment nötig wird.

Dynamic Blocks, die Magento über den Widget-Mechanismus mit Conditions verknüpft, eignen sich für zielgruppenspezifische Inhalte, etwa unterschiedliche Banner für Neukunden und Bestandskunden. Auch hier bleibt das Grundprinzip erhalten: Die Bedingungslogik liegt im Widget beziehungsweise in der Segment-Regel, nicht im Template. Das Template rendert nur, was ihm über den Widget-Renderer oder das ViewModel geliefert wird, und bleibt dadurch unabhängig von Marketing-Entscheidungen wartbar.

In der Praxis bewährt sich eine klare Konvention: Static Blocks für global gültige, selten wechselnde Snippets wie Footer-Zertifikate, Dynamic Blocks für zeitlich oder zielgruppenbezogen befristete Kampagneninhalte. Wer diese Trennung von Anfang an einhält, vermeidet, dass Redakteure Kampagnentexte versehentlich in global eingebundene Hyvä CMS-Blöcke schreiben, die dann site-weit stehen bleiben, obwohl die Kampagne längst vorbei ist.


<!-- template: Mironsoft_CmsWidgets::block/static-banner.phtml -->
<!-- Static block content is maintained in Admin, layout structure stays fixed -->
<div class="not-prose bg-orange-50 border border-orange-200 rounded-xl px-4 py-3 mb-8 flex items-start gap-3">
  <svg class="w-5 h-5 text-orange-600 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
  </svg>
  <div class="prose prose-sm max-w-none prose-a:text-orange-700">
    <?= /* @noEscape */ $block->getChildHtml('shipping.notice.block') ?>
  </div>
</div>

7. Full Page Cache und Cache-Tags für CMS-Blöcke

CMS-Blöcke werden im Full Page Cache von Magento standardmäßig mit dem Cache-Tag cms_b_<id> versehen, was bedeutet, dass eine Änderung am Block im Admin gezielt nur die Seiten invalidiert, die diesen Tag tragen, statt den kompletten Cache zu leeren. Für Hyvä CMS-Blöcke, die über Widgets in mehreren CMS-Seiten oder in statischem Block-Content eingebunden sind, funktioniert diese Invalidierung transparent, solange der Block über den Standard-Renderer und nicht über eine eigene, ungetaggte Datenquelle geladen wird.

Ein kritischer Punkt bei eigenen Widget-Typen: Wenn ein Custom-Widget Daten aus einem CMS-Block referenziert, aber selbst kein eigenes Cache-Tag setzt, kann es passieren, dass die Seite trotz Block-Änderung im Admin veraltet bleibt, weil das umgebende Full-Page-Cache-Objekt den Tag des referenzierten Blocks nicht kennt. In diesem Fall muss das Widget beziehungsweise das darunterliegende Block-Objekt die Methode getIdentities() so überschreiben, dass sie den relevanten cms_b_<id>-Tag mit ausgibt.

Im Zusammenspiel mit dem clientseitigen Block-Cache von Hyvä, der über ttl-Direktiven in Layout-XML einzelne Blöcke unabhängig vom vollständigen Seiten-Cache hält, ist wichtig zu verstehen, dass beide Mechanismen unabhängig invalidiert werden. Ein Hyvä CMS-Block, der über einen eigenen Hyvä-Block-Cache läuft, braucht deshalb dieselbe Tag-Logik wie der FPC, sonst zeigt der Block-Cache veralteten Content, obwohl der volle Seiten-Cache bereits korrekt invalidiert wurde.


{
  "cache_warmup": {
    "cms_blocks": [
      { "identifier": "footer-trust-badges", "tag": "cms_b_42", "warm_on_deploy": true },
      { "identifier": "shipping-notice", "tag": "cms_b_57", "warm_on_deploy": true },
      { "identifier": "homepage-banner", "tag": "cms_b_12", "warm_on_deploy": false }
    ],
    "warmup_urls": [
      "/",
      "/checkout/cart",
      "/customer/account"
    ]
  }
}

8. Responsive Verhalten von Bildern im WYSIWYG-Content

Bilder, die Redakteure über den WYSIWYG-Editor einfügen, kommen ohne srcset, ohne explizite width/height-Attribute und ohne loading="lazy", weil der TinyMCE-Standard-Bilddialog diese Attribute nicht automatisch setzt. Für Hyvä CMS-Blöcke mit vielen redaktionellen Bildern führt das ohne Nachbearbeitung zu Layout-Shift, weil der Browser vor dem Laden des Bildes keine reservierte Höhe kennt, und zu unnötig großen Bildtransfers auf mobilen Geräten.

Eine robuste Lösung ist ein Plugin auf den WYSIWYG-Renderer beziehungsweise ein Nachbearbeitungsschritt im Template, der loading="lazy" und decoding="async" automatisch auf alle img-Tags innerhalb eines CMS-Blocks anwendet, sofern sie nicht bereits above the fold liegen. Für above-the-fold-Bilder in Hero-Blöcken sollte stattdessen explizit loading="eager" und ein fetchpriority="high" gesetzt werden, damit der Largest Contentful Paint nicht durch Lazy-Loading verzögert wird.

Die Tailwind-Typography-Klasse prose-img:rounded-xl kümmert sich um die visuelle Gestaltung, löst aber nicht das Problem der fehlenden Dimensionsangaben. Deshalb ist es sinnvoll, im Media-Storage-Upload-Workflow oder per Nachbearbeitung die tatsächlichen Bildmaße als Attribute zu injizieren, damit der Browser den Platz reserviert, bevor das Bild geladen ist, und CLS in Hyvä CMS-Blöcken nicht zum wiederkehrenden Performance-Problem wird.

9. CSP-Sicherheit bei CMS-Blöcken und Widgets

Hyvä bringt über das CSP-Modul standardmäßig eine strikte Content-Security-Policy mit, die Inline-Scripts ohne Nonce blockiert und damit viele klassische XSS-Vektoren von vornherein unterbindet. Für Hyvä CMS-Blöcke bedeutet das konkret: Redakteure, die im WYSIWYG-Editor versehentlich ein <script>-Tag oder ein onclick-Attribut einfügen, sehen im Frontend entweder gar nichts oder eine von der Browser-Konsole gemeldete CSP-Verletzung, statt dass der Code unbemerkt ausgeführt wird.

Inline-Styles im WYSIWYG-Content sind von der Standard-CSP zwar meist nicht blockiert, sollten aber trotzdem vermieden werden, weil sie sich nicht über Tailwind-Utility-Klassen versionieren oder theme-weit anpassen lassen. Wer Redakteuren im TinyMCE nur eine begrenzte Auswahl an vordefinierten CSS-Klassen zur Verfügung stellt, statt den freien Inline-Style-Editor freizuschalten, reduziert gleichzeitig das Risiko unsauberer Formatierung und stellt sicher, dass alle Hyvä CMS-Blöcke visuell zum Rest des Themes passen.

Bei eigenen Widget-Parametern ist Vorsicht geboten, sobald ein Parameter direkt in HTML-Attribute oder in href-Werte eingesetzt wird, ohne dass er vorher escaped wird. Parameter, die aus dem Widget-Dialog stammen, sind letztlich redaktionell eingegebene Strings und müssen im Template konsequent mit $escaper->escapeHtml() beziehungsweise $escaper->escapeUrl() behandelt werden, bevor sie im Markup landen, damit auch ein manipulierter Widget-Parameter keine XSS-Lücke öffnet.

Die folgende Übersicht fasst die wiederkehrenden Entscheidungen bei Hyvä CMS-Blöcken und Widgets zusammen: welches Pattern in der Praxis unsauber bleibt und welches sich als robuste Alternative etabliert hat.

Aufgabe Unsicher / Unsauber Empfohlenes Pattern Vorteil
CMS-Block einbinden Direkte BlockFactory-Nutzung im Template ViewModel als ArgumentInterface per Layout-XML Testbar, sauber getrennt, layout-steuerbar
WYSIWYG-Content stylen Inline-Styles je Redakteur individuell gesetzt Tailwind Typography mit prose-Overrides Konsistent, ohne Redakteursschulung
Eigenes Widget bauen Generischen Block-Widget-Renderer zweckentfremden Eigener Typ über widget.xml mit eigenem Template Saubere Parameter, kein Hack
Cache-Invalidierung Custom-Widget ohne eigenes Cache-Tag getIdentities() mit cms_b_<id> überschreiben FPC invalidiert zuverlässig
Bilder im WYSIWYG Ohne width/height, ohne Lazy Loading Dimensionen injizieren, loading gezielt setzen Kein Layout-Shift, besserer LCP
Widget-Parameter ausgeben Ungeprüft direkt ins Markup schreiben $escaper->escapeHtml() / escapeUrl() konsequent Keine XSS-Lücke über Widget-Parameter

Mironsoft

Hyvä-Themes, CMS-Architektur und Magento-2-Entwicklung

CMS-Blöcke und Widgets, die zum Hyvä-Theme passen statt dagegen zu arbeiten?

Wir analysieren bestehende CMS-Strukturen, ersetzen Luma-Reste durch saubere Hyvä CMS-Blöcke, bauen eigene Widget-Typen und sorgen für korrekte Cache-Tags und CSP-Konformität.

CMS-Block-Redesign

Bestehende Blöcke von Luma-CSS auf Tailwind Typography umstellen

Widget-Entwicklung

Eigene widget.xml-Typen mit Hyvä-konformen phtml-Templates

WYSIWYG-Styleguide

Redaktions-Guidelines und CSP-sichere Editor-Konfiguration

10. Zusammenfassung

Der rote Faden bei Hyvä CMS-Blöcken ist immer derselbe: Redaktioneller Content und Utility-First-CSS gehören zusammen gedacht, nicht nacheinander gepatcht. Tailwind Typography normalisiert WYSIWYG-Markup, ohne dass Redakteure Klassen lernen müssen. Eigene Widget-Typen mit dedizierter widget.xml und eigenem Template ersetzen den generischen Renderer dort, wo Parameter und Layout-Logik komplexer werden. ViewModels statt direkter Block-Instanziierung halten Templates testbar und layout-steuerbar.

Cache-Tags wie cms_b_<id> müssen bei eigenen Widgets explizit über getIdentities() weitergereicht werden, sonst bleibt die FPC-Invalidierung lückenhaft. Responsive Bildattribute und CSP-konforme Escaping-Disziplin runden die technische Absicherung ab, damit redaktionell gepflegter Content weder Performance-Probleme noch Sicherheitslücken verursacht.

Wer diese Punkte konsequent umsetzt, bekommt Hyvä CMS-Blöcke und Widgets, die sich anfühlen wie ein natürlicher Teil des Themes, statt wie ein nachträglich eingepflanzter Fremdkörper aus der Luma-Ära. Das reduziert Support-Aufwand im Alltag und macht das Theme für neue Redakteure ohne technisches Detailwissen bedienbar.

Hyvä CMS-Blöcke und Widgets: Das Wichtigste auf einen Blick

Typography statt Luma-CSS

@tailwindcss/typography mit prose-a/prose-headings-Overrides normalisiert WYSIWYG-Content ohne Redakteursschulung.

Eigene Widget-Typen

widget.xml mit dediziertem phtml-Template statt generischem Block-Renderer für komplexe Parameter.

ViewModel statt Hardcoding

ArgumentInterface per Layout-XML injiziert hält Templates frei von Block-Instanziierung.

Cache-Tags & CSP

cms_b_<id> über getIdentities() weiterreichen, Widget-Parameter konsequent escapen.

11. FAQ: Hyvä CMS-Blöcke und Widgets

1Was unterscheidet Hyvä CMS-Blöcke von Luma?
Rendering als reines Server-Side-HTML ohne Knockout.js. Styling erfolgt über Tailwind Typography statt Luma-CSS-Klassen.
2Wie bindet man ein CMS-Block-Widget ein?
Über {{widget type="Magento\Cms\Block\Widget\Block" block_id="..."}} im WYSIWYG oder per Layout-XML, serverseitig aufgelöst im Template Filter.
3Warum sieht WYSIWYG-Content ungestylt aus?
Hyvä kennt keine Luma-CSS-Klassen. Ohne prose-Klasse aus Tailwind Typography bleibt Fließtext unformatiert.
4Wie passt man Tailwind Typography an?
Mit Modifier-Klassen wie prose-headings:text-slate-900, prose-a:text-orange-700 oder prose-img:rounded-xl direkt am Container.
5Wann lohnt sich ein eigener Widget-Typ?
Sobald eigene Parameter oder ein eigenes Template nötig sind. Registrierung über widget.xml statt generischem Block-Widget.
6Warum ViewModel statt Block-Instanziierung?
ArgumentInterface per Layout-XML hält Templates testbar und trennt Präsentation sauber von der Datenbeschaffung.
7Wie funktionieren Cache-Tags bei CMS-Blöcken?
Standardmäßig cms_b_. Eigene Widgets müssen das Tag über getIdentities() weiterreichen, sonst bleibt die FPC-Invalidierung lückenhaft.
8Static Block oder Dynamic Block?
Static Blocks für global gültige, selten wechselnde Inhalte. Dynamic Blocks mit Conditions für zielgruppenspezifische Kampagnen.
9Wie verhindert man Layout-Shift bei Bildern?
Tatsächliche Bilddimensionen als width/height injizieren. Above-the-fold-Bilder brauchen loading="eager" statt lazy.
10Wie sichert man Widget-Parameter gegen XSS ab?
Jeden Parameterwert mit $escaper->escapeHtml() oder $escaper->escapeUrl() behandeln, bevor er im Markup landet.