Blog

  • ServerSideRender: Backend und Frontend unterscheiden

    Bei der Registrierung eines Blocks definiert man mit Hilfe der edit() Funktion, wie der Editor den Block rendert und welche Informationen er anzeigt. Mit Hilfe der save() Funktion, legt man fest, wie die Daten gespeichert und im Frontend dargestellt werden sollen.

    Dynamische Blöcke

    Zur Erweiterung der ausschließlich in JavaScript geschriebenen Blöcken gibt es die Komponente ServerSideRender, um PHP Render-Callback Funktionen aufzurufen. Die Komponente bekommt das Ergebnis der PHP Funktion als HTML und rendert es anschießend im Block.

    Diese Komponente ist Hilfreich, wenn es sich um einen dynamischen Block handelt. Erst beim Aufruf der Seite werden die Daten abgerufen und der Block gerendert. Einsatzgebiete sind zum Beispiel das Anzeigen der neusten Beiträge oder beliebtesten Bilder der Seite in einen Block. Diese Werte können sich ständig ändern, daher macht es Sinn die Werte erst beim Abruf der Seite zu laden. In der Datenbank ist nur ein Platzhalter in Form eines HTML Kommentars abgespeichert, der den Namen des Blocks und die ausgewählten Attribute enthält.

    Der Block benötigt also keine save() Funktion, sondern nur ein Render-Callback, der die gespeicherten Attribute als Parameter bekommt und dann den Inhalt beliebig ausgeben kann. In der edit() Funktion wird die oben schon erwähnte ServerSideRender Komponente aufgerufen, um den Inhalt auch im Editor darzustellen.

    Der Editor rendert den Block bei jeder Änderung eines Attributes neu. Um die PHP Render-Funktion innerhalb des JavaScript basierten Editors aufzurufen, greift er auf die REST API zurück. Der Block sendet die Attribute an den Endpoint /wp/v2/block-renderer/:block. Dort wird der PHP Render-Callback aufgerufen und diese liefert das gerenderte HTML zurück.

    Render Funktion im Backend und Frontend unterscheiden

    Doch wie geht man vor, wenn man den Block im Editor und auf der Seite unterschiedlich darstellen möchte? Es wird im beiden Fällen die gleiche Funktion aufgerufen.

    Da die REST API das Rendern übernimmt, kann nicht auf die Funktion is_admin() zurückgegriffen werden, da diese Funktion prüft, ob man sich gerade auf einer Seite im Admin-Backend befindet. Wird allerdings eine Anfrage an die REST-API gesendet, ist dies ein eigenständiger Request und dieser Request ist nicht in einer Admin-Seite. Daher gibt die Funktion is_admin() bei REST API Anfragen immer false zurück, egal ob WordPress die Anfrage aus dem Backend sendet oder nicht. Dieses Problem gab es auch schon bei AJAX Anfragen. Florian Brinkmann hat einen Artikel darüber geschrieben wie man trotzdem prüfen kann ob die Abfrage bei AJAX Requests aus dem Front- oder Backend kommt.

    Um zu prüfen, ob unser Block im Frontend oder im Backend gerendert wird, müssen wir prüfen, ob die PHP Funktion direkt für das Frontend aufgerufen wurde oder über die REST API im Backend aufgerufen wurde.

    Die Prüfung innerhalb des PHP Render-Callbacks kann so aussehen:

    if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
        return 'Backend';
    } else {
        return 'Frontend';
    };

    Wenn der Browser eine Anfrage an die REST API sendet, setzt WordPress die Konstante REST_REQUEST auf true. Somit kann man sicher sein, dass der Block nicht im Frontend gerendert wurde, da hier die Funktion direkt aufgerufen wird und in dem Fall diese Konstante nicht definiert ist.

  • JavaScript Plugins API

    Neben den schon von PHP bekannten Hooks (Action und Filter), gibt es in nun auch eine API um Erweiterungen für den Editor zu erstellen.

    Slot / Fill

    Die JS Plugins API basiert auf Slots, die mit sogenannten Fills erweitert werden können. Unter Slots versteht man erweiterbare Bereiche, denen UI Elemente hinzugefügt werden können. Beispiele für Slots im Editor sind Einträge in Menüs, Buttons in der Toolbar, Elemente in der Sidebar oder zusätzliche Sidebars.

    Man kann also eigene React Komponenten erstellen und diese an den jeweiligen Slots rendern lassen. Ein Slot kann dabei mehrere Fills enthalten.

    Beispiel Post Status Panel

    Zuerst wird mit Hilfe der Funktion createSlotFill ein Fill und ein Slot erstellt (Zeile 3). In Zeile 5 – 11 wird der Fill definiert. Jeder Fill wird mit einem PanelRow Element umgeben und kann eine Klasse als Parameter entgegen nehmen.

    import { createSlotFill, PanelRow } from '@wordpress/components';
    
    export const { Fill, Slot } = createSlotFill( 'PluginPostStatusInfo' );
    
    const PluginPostStatusInfo = ( { children, className } ) => (
    	<Fill>
    		<PanelRow className={ className }>
    			{ children }
    		</PanelRow>
    	</Fill>
    );
    
    PluginPostStatusInfo.Slot = Slot;
    
    export default PluginPostStatusInfo;

    An der Stelle, an der dieser Slot gerendert wird, importiert man diese Komponente. PluginPostStatusInfo.Slot enthält eine Funktion, die ausgeführt wird, sobald ein Fill gerendert wird. In diesem Fall die weiteren Komponenten der Sidebar. Die registrierten Fills werden in Zeile 14 mit Hilde von { fills } ausgegeben.

    import PluginPostStatusInfo from '../plugin-post-status-info';
    
    ... 
    
    <PluginPostStatusInfo.Slot>
    	{ ( fills ) => (
    		<Fragment>
    			<PostVisibility />
    			<PostSchedule />
    			<PostFormat />
    			<PostSticky />
    			<PostPendingStatus />
    			<PostAuthor />
    			{ fills }
    			<PostTrash />
    		</Fragment>
    	) }
    </PluginPostStatusInfo.Slot>
    
    ...
    Position für das Slot Beispiel
    An dieser Position werden die Fills gerendert.

    Plugin registrieren

    const { registerPlugin } = wp.plugins;
    registerPlugin( name: string, settings: Object )

    Um ein eigenes Plugin zu registrieren wird die Funktion registerPlugin aus dem Paket Plugins verwendet.

    Als name wird ein eindeutiger Bezeichner übergeben, um das Plugin zu identifizieren. Das setting Objekt enthält ein optionales Icon für das UI (Dies ist nicht für alle Plugins nötig) und eine React Komponente mit den UI Elementen, die hinzugefügt werden sollen.

    const { PluginPostStatusInfo } = wp.editPost;
    const { registerPlugin } = wp.plugins;
    
    const MyPluginPostStatusInfo = () => (
    	<PluginPostStatusInfo
    		className="my-plugin-post-status-info"
    	>
    		My post status info
    	</PluginPostStatusInfo>
    );
    
    registerPlugin( 'my-plugin-post-status-info', {
    	render: MyPluginPostStatusInfo,
    } );

    Die Render-Komponente im Settings-Objekt enthält einen oder mehrere Fills, in diesem Beispiel das PluginPostStatusInfo Element. Dieses Element enthält den Inhalt (hier: „My post status info„), der in den Slot gerendert werden soll.

    Ergebnis des Beispiel Plugins
    JS Plugin mit Fill/Slot
  • Eigene Bock-Stile erstellen

    In den Block-Einstellungen kannst du im Bereich Erweitert über ein Textfeld ganz einfach einem Block weitere Klassen hinzufügen. Diese Klassen können genutzt werden, um das Aussehen per CSS zu ändern und so bsw. eine andere Button Form und Größe darzustellen. Mit der Block-Style API bekommst du eine weitere Möglichkeit, die es erlaubt Blöcken weitere Klassen zu geben. Der Vorteil dieser API ist es, dass die Klassen vordefiniert werden können, der Editor ein Interface erstellt und eine Vorschau des Stils angezeigt wird.

    Stile für eigene Blöcke

    Ein Beispiel für Block-Stile ist bereits im Zitat-Block vorhanden, hier gibt es die Stile „Normal“ und „Groß“, die jeweils eigene CSS Definition haben. Über das erste Icon in der Block-Toolbar kannst du ein Menü öffnen, über das du die Block-Stile auswählen oder den Block in einen andern Typ umwanden kannst. Auf der rechten Seite erhältst du gleich eine Vorschau, wie die Block mit dem Stil aussehen wird.

    Block-Stile Menü für den Zitate Block
    Block-Stile im Zitat-Block

    In der Block-Definition (/block-library/src/quote/index.js) sind diese wie folgt definiert:

    styles: [
    	{ name: 'default', label: __( 'Regular' ), isDefault: true },
    	{ name: 'large', label: __( 'Large' ) },
    ]

    Styles ist ein Array mit den Stil-Objekten. Jedes Object hat dabei einen Namen, der für die Klasse verwendet wird. Aus name: ‚large‘ wird class=“is-style-large“. Das Label wird im Toolbar Menü angezeigt. Über den Parameter isDefault kannst du festlegen, welcher Stil vorausgewählt sein soll.

    <blockquote class="wp-block-quote is-style-large">
    	<p>Lorem ipsum dolor sit amet...</p>
    	<cite>Das ist ein Beispiel</cite>
    </blockquote>

    Bestehende Blöcke erweitern

    Neben der Stil Deklaration in der Block-Definition kannst du mit Hilfe eines Hooks auch Stile zu bereits bestehenden Blöcken hinzufügen. Wenn du beispielsweise einen eigenen Button-Stil hinzufügen möchtest, reichen die folgende JavaScript und CSS Anweisungen.

    Mit der Funktion registerBlockStyle() registrierst du den Stil im Editor. Der erste parameter ist der registrierte Name des Blocks, bestehend aus namespace/block-name, der zweite Parameter ist ein Objekt mit mit dem Namen und dem Label.

    wp.blocks.registerBlockStyle( 'core/button', { name: 'red-button', label: 'Rot' });

    Der Editor erzeugt nun die Klasse is-style-red-button. Für diese Klasse kannst du eine CSS Anweisung erstellen, um so die Darstellung des Button zu definieren.

    .wp-block-button.is-style-red-button .wp-block-button__link {
    	background: #cf2e2e;
    	text-transform: uppercase;
    	border-radius: 0;
    }

    Im Editor sieht es dann folgendermaßen aus. Der Stil wird im Stil-Menü angezeigt und wenn du nun mit der Maus über den Stil gehst oder per Tastatur diesen auswählst, wird eine große Vorschau auf der rechten Seite dargestellt.

    Block-Stil Menü für einen eigenen Button Stil
    Eigener Block-Stil im Editor
  • Eigene Farben definieren

    Einige Blöcke bieten die Möglichkeit Farben von bestimmten Elementen im Block anzupassen. Dies sind zum Beispiel die Hintergrundfarbe eines Buttons oder die Textfarbe eines Absatzes. Gutenberg liefert schon 11 vordefinierte Farben mit.

    Neben den Farben gibt es auch eine Möglichkeit mit einem Farbmischer eine eigene Farbe zu mischen.

    Farbwähler in Gutenberg

    Mit folgenden Code lässt sich der Farbmicher deaktivieren, sodass nur die vordefinierten Farben verwendet werden können.

    add_theme_support( 'disable-custom-colors' );

    Vordefinierte Farben überschreiben

    Themes haben die Möglichkeit die vordefinierten Farben zu überschreiben, die in der Farbwahl Palette in allen Komponenten angezeigt werden sollen.

    function mytheme_add_custom_colors() {
    	add_theme_support( 'editor-color-palette', array(
    		// Fügt eine goldene Farbe hinzu.
    		array(
    			'name' => __( 'gold', 'themeLangDomain' ),
    			'slug' => 'nitschmahler-gold',
    			'color' => '#ae9a63',
    		),
    	) );
    }
    
    add_action( 'after_setup_theme', 'mytheme_add_custom_colors' );
    Angepasste Farbwahl Komponente
    Farbwahl Komponente

    Man ruft die add_theme_support Funktion auf und übergibt als Parameter den Wert „editor-color-palette“ und ein Array mit den Farbdefinitionen. Jede Farbe ist dabei ein Array, das die Werte „name„, „slug“ und „color“ enthält.

    • Name: Der Name der angezeigt wird, dieser sollte übersetzbar sein.
    • Slug: Der Wert, der abgespeichert wird und aus dem die CSS Klasse generiert wird.
    • Color: Der Hex-Wert der Farbe um eine Vorschau zu zeigen.

    Beim Auswählen einer Farbe wird bsw. im Button ein Attribut mit dem Slug „nitschmahler-gold“ abgespeichert und eine eine Klasse ‚has-nitschmahler-gold-background-color‚ zum Element hinzugefügt

    <!-- wp:button {"backgroundColor":"nitschmahler-gold"} -->
    <div class="wp-block-button alignnone">
    <a class="wp-block-button__link has-background has-nitschmahler-gold-background-color">Mein Button</a>
    </div>
    <!-- /wp:button -->

    Für diese Klasse muss man nun noch eine CSS Definition erstellen. Diese Definition muss im Editor und im direkt in der Seite geladen werden.

    // Für die Hintergrudnfarbe
    .has-nitschmahler-gold-background-color {
    	color: #ae9a63;
    }
    // Für die Textfarbe
    .has-nitschmahler-gold-color {
    	color: #ae9a63;
    }

    Fertig ist der Button:

    Fertiger Button
  • Warum Gutenberg mehr als nur ein Editor ist

    Auf Krautpress.de habe ich einen Artikel zu Gutenberg veröffentlicht, der den Umfang des Projekts und dessen Ziele beschreibt.

  • Gutenberg Linktipps #4

    Voraussetzungen für den Erfolg

    Morten Rand-Hendriksen hat den zweiten Artikel in seiner "Gutenberg and the Future of WordPress"-Reihe veröffentlicht. In Conditions for Success beschreibt Morten, ähnlich wie schon Daniel Bachhuber, was für eine erfolgreiche Einführung von Gutenberg notwendig ist. Er geht dabei auf die Punkte Accessibility, eine lange Test- und Übergangsphase, sowie einen möglichen Fork und was dieser als Konsequenzen hätte, ein.

    WYSIWYG und Accessibility

    Amanda Rush hat sich einige Gedanken zu WYSIWYG-Editoren und Gutenberg im Bezug zu Accessibility gemacht. Sie sieht Gutenberg mittlerweile auf einen guten Weg, bemängelt aber, dass es zu wenig Dokumentation gibt um das Konzept des neuen Editors zu erklären.

    Page Builders in einer Gutenberg Welt

    Robby McCullough von Beaver Builder beschreibt in seinem Artikel Page Builders in a Gutenberg World warum Page Builder auch mit Gutenberg noch gebraucht werden und wie sie Kompatibilität zwischen den Editoren umgehen wollen.

  • Gutenberg 1.9

    Am 11. Dezember wurde die mit Gutenberg 1.9 die 19. Betaversion veröffentlicht. Eine ausführliche Zusammenfassung mit allen Änderungen ist im Core Make-Blog zu finden,

    Die größte Neuerung des Release sind die globalen wiederverwendbaren Blöcke, aber es gibt auch Verbesserungen bei den Templates (diese können nun gesperrt werden), Versionierung von Blockattributen, so dass Markup migriert werden kann, und viele Erweiterungen und Bugfixes.

  • Gutenberg Linktipps #3

    3 Dinge die man über Gutenberg wissen sollte

    Im Artikel WordPress is Changing. Here are 3 Things You Need to Know About Gutenberg beschreibt Morten Rand-Hendriksen wie man sich auf Gutenberg vorbereitet, warum Gutenberg mehr als ein Editor ist und wie man dabei mithelfen kann.

    State of the Word Transcript

    Im TinyMCE Block gibt es das vollständige Transcript der State of the Word Session vom WordCamp US 2017 zum Nachlesen.

    Warum sich Josh Pollock nun auf Gutenberg freut

    Josh Pollock ist Core Contributor und Entwickler des Caldera Forms Plugins. In seinem Artikel Why I Came Back From Nashville All Excited About Gutenberg erklärt warum er vor dem WordCamp US das Gutenberg Projekt sehr skeptisch gesehen hat und was sich daran nun geändert hat. Viele Kritikpunkte wurden behoben, einige neue interessante Funktionen sind hinzugekommen und das Ziel von Gutenberg ist nun besser erkennbar.

  • Gutenberg Linktipps #2

    Wie Gutenberg ein Erfolg werden kann

    Daniel Bachhuber hat sich einige Gedanken gemacht, wie wir es schafften, dass die überwiegende Mehrheit der WordPress Benutzer ab dem ersten Tag von Gutenberg begeistert ist und ihn ohne Probleme nutzen kann. Hierfür sieht er 2 Vorraussetzungen: Gute UX und Kompatibilität. Seine Idee, wie dies erreicht werden könnte, ist im Artikel Landing Gutenberg in WordPress 5.0 nachzulesen.

    Gutenberg und Publishers

    Im August auf dem WordCamp for Publishers hat Aaron Jorbin eine Session zu Gutenberg gehalten. nach einer kurzen Präsentation und Demo gab es eine Diskussion in der die Anforderungen für Publisher an Gutenberg diskutiert wurden. In seinem Blogbeitrag Gutenberg and Publishers fasst Aaron die ausführliche Diskussion zusammen.

    Was WordPress VIPs über Gutenberg wissen müssen

    Das WordPress VIP Programm von Automattic richtet sich an Enterprise Kunden und Agenturen für die Entwicklung, Hosting und Support großer Seiten. Im Artikel The New WordPress Editor: What You Need to Know about Gutenberg fasst Steph Yiu die Konzepte des Editors und den aktuellen Stand zusammen und beschreibt, wie sich die Kunden mit ihren Teams darauf vorbereiten können.

  • Gutenberg Linktipps #1

    Werbung in der Gutenberg Welt

    Im Artikel Ads in a Gutenberg World macht sich Helen Hou-Sandi darüber Gedanken, wie Werbung in Blocks aussehen könnte. Es wäre möglich Werbung automatische in jedem 5. Block auszuspielen oder bereits bei Beginn Werbeanzeigen darzustellen, um die der Inhalt geschrieben wird. Dies ist allerdings nur eine Überlegung was möglich wäre. Ebenfalls nennt sie noch ein paar Schnittstellen, die dafür nötig wären diese Funktionalität in Gutenberg zu integrieren.

    Werbeblöcke in Gutenberg

    Die Strategie hinter Gutenberg

    Der Webworker Torsten Landsiedel hat einige Bedenken zur Einführung von Gutenberg in seinem Artikel State of the word – oder auch Tomorrowland zusammengefasst. Er nennt zum einen den frühzeitigen Merge in den Core, als auch die Kommunikationsstrategie als Probleme. Torsten selbst ist im Supportbereich aktiv und hat hier aus Erfahrungen kein Gutes Gefühl, wenn ein unfertiges Produkt auf den Kunden losgelassen wird. Lesenswert ist auch die Diskussion in den Kommentaren unter dem Beitrag.

    State of the Word

    In seiner jährlichen Keynote "State of the Word" sprach Matt Mullenweg am 2. Dezember beim WordCamp US in Nashville über das vergangene Jahr in der "WordPress-Welt". Dabei gab es neben einer Gutenberg Präsentation von Matias Ventura auch einige Ausblicke auf die Pläne des kommenden Jahres. Matt glaubt, dass es noch ungefähr 12 Iterationen, also rund 4 Monate (April 2018) dauern wird, bis Gutenberg für den Massenmarkt bereit ist. Neben dem Editor sind der Customizer und Themes Gutenberg Entwicklungs-Schwerpunkte, die im nächsten Jahr angegangen werden. In einer Q&A nach dem Talk wurden noch einige Fragen rund um Gutenberg beantwortet.

    Das Video gibt es jetzt online auf WordPress.tv zu sehen. Gute Zusammenfassungen des Talks sind auf Krautpress.de (Deutsch) und Poststatus.com (Englisch) zu finden.