Letztes Update am
Ein Gutenberg-Block ohne JSX, Babel, ES6 und weitere dicke Entwickler-Libraries
Der Block color-block bringt eine RichText-Komponente mit zwei Einstellungen unter der rechten Sidebar Block (InspectorControls): Hintergrundfarbe und Textfarbe.
Das Plugin besteht aus drei Dateien:
+—— color-block | +—— color-block.php | +—— color-block.js | +—— color-block.css
Block mit register_block_type() registrieren
Das Block-Plugin beginnt wie immer mit dem mehrzeiligen Kommentar.
<?php /** * Plugin Name: Color Block * Description: Creates a Gutenberg Block to add a colored text component to the page. * Author: Emma und Ulrike * Author URI: https://colofon.de * Text Domain: jscolorblock * Version: 1.0.0 */
Die PHP-Datei lädt den Block und die Stile aus color-block.js bzw. color-block.css mittels register_block_type.
wp_register_script
Wichtig:
wp_register_script lädt an keiner Stelle die Javascript-Datei. Die JS-Datei wird nur unter dem Handle verfügbar gemacht, damit sie an anderer Stelle später eingereiht – enqueue – werden kann.
$block_path = '/color-block.js'; // Registriert das Editor-Script des Blocks wp_register_script( 'jscolorblock-color-block', plugins_url( $block_path , __FILE__ ), [ 'wp-i18n', 'wp-element', 'wp-blocks', 'wp-components', 'wp-editor' ], filemtime( plugin_dir_path( $block_path , __FILE__ ) ) );
WordPress bevorratet Pakete, die im Block ausgeführt werden können, aber sie müssen vor dem Javascript geladen werden.
Im Beispiel bestehen die folgenden Abhängigkeiten:
- wp-i18n – Wird für die Übersetzungen benötigt
- wp-element – React & ReactDOM
- wp-blocks – Mitsamt registerBlockTypes
- wp-components – WP UI Component Library
- wp-editor – Die RichText-Komponenten des Editors
Header
- wp-i18n – Wird für die Übersetzungen benötigt
Absatz mit etwas Text
Header 2
- wp-element – React & ReactDOM
Absatz mit etwas mehr Text als in eine Zeile passt
wp_register_style
Im Unterschied zu wp_register_script kann in der letzten Eigenschaft eine Funktion angegeben werden und es müssen keine Abhängigkeiten eingebaut werden. Ansonsten sind wp_register_style und wp_register_script ähnlich aufgebaut.
// creating a variable for our css file path $style_path = '/color-block.css'; wp_register_style( 'jscolorblock-color-block-styles', plugins_url( $style_path , __FILE__ ), [], filemtime( plugin_dir_path( $style_path , __FILE__ ) ) );
register_block_type
Genereller Aufbau
register_block_type( $name:String, $args:Array );
Der erste Parameter ist der Name des Blocks, i.d.R. besteht der Name aus textdomain/block-name.
// Den Block registrieren und die Handles für das Editor-Script und CSS übergeben. register_block_type( 'jscolorblock/color-block', array( 'editor_script' => 'jscolorblock-color-block', 'style' => 'jscolorblock-color-block-styles', ) );
Block-Namen können nur aus Kleinbuchstaben und Bindestrichen bestehen und müssen mit einem Buchstaben anfangen.
Der zweite Parameter übergibt zusätzliche Argumente in einem Array von Key und Wert:
Das Javascript wird mit editor_script übergeben, die CSS-Datei mit style.
Ein weiterer Key wäre editor_style, um eine CSS einzubinden und render_callback für dynamische Blöcke, wenn PHP den Block rendert.
Das vollständige PHP-Script
add_action('init', 'jscolorblock_register_block_assets'); function jscolorblock_register_block_assets() { // Pfad zur Javascript-Datei $block_path = '/color-block.js'; // Javascript des Blocks registrieren wp_register_script( 'jscolorblock-color-block', plugins_url( $block_path , __FILE__ ), [ 'wp-i18n', 'wp-element', 'wp-blocks', 'wp-components', 'wp-editor' ], filemtime( plugin_dir_path( $block_path , __FILE__ ) ) ); // Pfad zur CSS-Datei $style_path = '/color-block.css'; wp_register_style( 'jscolorblock-color-block-styles', plugins_url( $style_path , __FILE__ ), [], filemtime( plugin_dir_path( $style_path , __FILE__ ) ) ); // Block registrieren und die Handles für das Script und die CSS-Datei übergeben. register_block_type( 'jscolorblock/color-block', array( 'editor_script' => 'jscolorblock-color-block', 'style' => 'jscolorblock-color-block-styles', ) ); }
Das Javascript Block-Script
Da das PHP-Plugin-Script Abhängigkeiten aufgeführt hat, müssen diese Abhängigkeiten über das globale wp-Objekt zugegriffen werden, das von WordPress zum Windows-Objekt hinzufügt.
So ist z.B. registerBlockType ein Teil der wp-blocks-Library und darum verfügbar unter wp.blocks.registerBlockType.
wp.blocks.registerBlockType( name:String, typeDefinition:Object );
registerBlockType hat zwei Argumente:
- name ist ein String mit dem Block-Namen gefolgt von der der Block-Namen-Konvention „uniquenamespace/block-name“
- typeDefinition ist ein Objekt mit der Block-Konfiguration
Ein Block braucht bestimmte Eigenschaften, damit er registriert werden kann. Diese Eigenschaften werden in einem Konfigurations-Objekt als zweiter Parameter an registerBlockType übergeben.
Diese Eigenschaft sind
- title
- String (*required)
- description
- String
- category
- String (*required)
- icon
- string | WPElement | Function | Object
- keywords
- Array
- styles
- Array
- attributes
- Object
- transforms
- Array
- parent
- String
- supports
- Object
- edit
- WPElement (*required)
- save
- WPElement (*required)
Gutenberg-Blöcke bestehen aus zwei Elementen – auf der einen Seite die Gutenberg-Ansicht des Editors und auf der anderen Seite der Inhalt, der als post_content in der Datenbank gespeichert wird.
Diese beiden Komponenten kommunizieren miteinander und teilen sich Daten über Attribute auf einer Abstraktionsebene über dem REACT-State. Alle Eigenschaften dieses Objekts werden entweder in HTML-Kommentaren über dem Block oder im Block-Markup gespeichert.
WordPress übergibt ein Objekt mit den Attributen (und anderen nützlichen Eigenschaften wie eine Funktion zum Updaten der Attribut-Werte) an die edit und save-Funktionen des Javascripts.
edit: function (props) { }
Innerhalb der edit-Funktion kann auf Attribute mit attributeName werden:
props.attributes.attributeName // Update von Attribut-Werten isSelected: Boolean // Block momentan aktiviert className: String // Der Name, der dem Block im Frontend zugewiesen ist
Das Argument von setAttributes ist ein Objekt, das den namen des Attributs und den neuen Wert enthält. Um die Hintergrundfarbe zu ändern
attributes: { backgroundColor: { value: "#442283", type: "string" } }, edit: function(props) { props.setAttributes({ backgroundColor: "#39ab00" }) }
führt ein Update der Attribut-Werte in der edit-Funktion durch. Später werden die Werte als Teil von the_content mit der save-Funktion gespeichert.
registerBlockType
Zusätzlich zum Block-Namen wird das Options-Objekt als zweiter Parameter übergeben, und zwar mit
- title
- wird angezeigt, wenn der Block im Editor aktiviert wird
- icon
- die einfachste Variante ist der Name eines Icons aus den WordPress Dashicons, ohne das führende dashicon. Allerdings kann auch SVG direkt für ein eigenes Icon verwendet werden.
- category
- common, formatting, layout, widgets, embed. Zusätzlich können eigene Kategorien erzeugt werden
- attributes
- Die Attribute des Color Blocks sind der Inhalt, Textfarbe und Hintergrundfarbe.
wp.blocks.registerBlockType( 'jsforwp/callout-block', { title: 'Color Block', icon: 'art', category: 'common', attributes: { content: { source: 'html', selector: 'h2', }, backgroundColor: { type: 'string', default: '#F1EFBA', }, textColor: { type: 'string', default: '#999999', } },
Attribute
Attribute werden als Eigenschaften im attributes-Objekt gesetzt. Jede dieser Eigenschaften ist wieder ein Objekt mit einem Wert.
- type
- Datentyp wie string, boolean, array, …
- source
- Woher die Daten kommen (z.B. meta oder html). Wird als Kommentar gespeichert, wenn das Attribute leer bleibt
- selector
- Ein CSS-Selektor, der angibt, woher der Block die Daten bekommt (wird nur gebraucht, wenn source html ist)
- meta
- Name des Meta-Werts, nur wenn der Block als Meta gespeichert wird
- default
- Ein Default, Vorgabewert
Die Gutenberg-Erfahrung
Als „Erfahrung“ bezeichnet Gutenberg das Look & Feel des Editors – eine völlig neue Erfahrung nach all den Jahren der Editoren wie TinyMCE.
WordPress enthält eine Vielzahl von Komponenten, die direkt benutzt werden können.
WordPress Block Editor Component Reference
Dazu noch ein Wort zu den edit- und save-Funktionen: Nur ein Element kann zurückgegeben werden. Wenn mehrere Elemente zurückgegeben werden sollen, müssen sie in ein Elemente gepackt werden.
(Fragment im wp-Element-Paket)
createElement
Das wp-element-Paket ist im Grunde genommen REACT gebündelt in WordPress. wp.element.createElement ist dasselbe wie React.createElement von REACT.
createElement nimmt den Element-Typ, der erzeugt werden soll – ein Objekt mit den Eigenschaften und Einstellungen.
wp.element.createElement( type, props, children... )
Gutenberg Block mit RichText
Der Inhalt des Blocks wird als RichText-Komponente angelegt, direkt aus dem wp-Editor-Paket. RichText hat eine Reihe von Argumenten, die im zweiten Parameter der createElement-Funktion übergeben werden können.
Jetzt soll der Inhalt in einem h2-Element sitzen, also wird als tagName der Wert h2 übergeben. Weitere Element, die hier eingesetzt werden können, sind z.B.:
className, value, style, onChange …
Block-Editor Handbuch wordPress / rich-text
Das Script für die Gutenberg-Erfahrung des Color Block sieht dann wie folgt aus
edit: function(props) { wp.element.createElement( wp.editor.RichText, { tagName: 'h2', className: props.className, value: props.attributes.content, style: { backgroundColor: props.attributes.backgroundColor, color: props.attributes.textColor }, onChange: function( newContent ) { props.setAttributes( { content: newContent } ); } } ) … }
save-Funktion
Die Elemente, die in der save-Funktion zurückgegeben werden, werden in HTML-Elemente umgewandelt und dann in der Datenbank gespeichert.
save: function( props ) { return wp.element.createElement( wp.editor.RichText.Content, { tagName: 'h2', value: props.attributes.content, style: { backgroundColor: props.attributes.backgroundColor, color: props.attributes.textColor }, } ); }
Color Block als Plugin installieren
An dieser Stelle sollte das Plugin bereits funktionieren. In den Plugins-Ordner laden und aktivieren.
Block Sidebar mit InspectorControls für die Block-Einstellungen
InspectorControls werden zusammen mit dem RichText-Element als ein Fragment-Element gepackt.
edit: function( props ) { return wp.element.createElement( wp.element.Fragment, null, wp.element.createElement( wp.editor.InspectorControls, null, null ), wp.element.createElement( wp.editor.RichText, { tagName: 'h2', className: props.className, value: props.attributes.content, style: { backgroundColor: props.attributes.backgroundColor, color: props.attributes.textColor }, onChange: function( newContent ) { props.setAttributes( { content: newContent } ); } } ) ) }
Hier kann PanelColorSettings als ein Child-Element der InspectorControls eingesetzt werden. Diese Komponente erzeugt den Color Picker.
wp.element.createElement( wp.editor.InspectorControls, null, wp.element.createElement( wp.editor.PanelColorSettings, { ... } ) ),
Den PanelColorSettings werden ein Titel und ein Array mit den Farbeinstellungen übergeben. Jede Farbeinstellung ist ein Objekt mit den Eigenschaften label, value und onChange.
{ label: wp.i18n.__("Text Color", "jsforwp"), value: props.attributes.textColor, onChange: function( newColor ) { props.setAttributes({ textColor: newColor }); } }
Damit wären alle Zutaten für den Color Block zusammengetragen. Das komplette Javascript sieht so aus:
wp.blocks.registerBlockType( 'jscolorblock/color-block', { title: 'Color Block', icon: 'art', category: 'common', attributes: { content: { source: 'html', selector: 'h2', }, backgroundColor: { type: 'string', default: '#F1EFBA', }, textColor: { type: 'string', default: '#999999', } }, edit: function( props ) { return wp.element.createElement( wp.element.Fragment, null, wp.element.createElement( wp.editor.InspectorControls, null, wp.element.createElement( wp.editor.PanelColorSettings, { title: wp.i18n.__("Color Settings", "jscolorblock"), colorSettings: [ { label: wp.i18n.__("Background Color", "jscolorblock"), value: props.attributes.backgroundColor, onChange: function( newBackgroundColor ) { props.setAttributes({ backgroundColor: newBackgroundColor }); } }, { label: wp.i18n.__("Text Color", "jscolorblock"), value: props.attributes.textColor, onChange: function( newColor ) { props.setAttributes({ textColor: newColor }); } } ] } ) ), wp.element.createElement( wp.editor.RichText, { tagName: 'h2', className: props.className, value: props.attributes.content, style: { backgroundColor: props.attributes.backgroundColor, color: props.attributes.textColor }, onChange: function( newContent ) { props.setAttributes( { content: newContent } ); } } ) ); }, save: function( props ) { return wp.element.createElement( wp.editor.RichText.Content, { tagName: 'h2', value: props.attributes.content, style: { backgroundColor: props.attributes.backgroundColor, color: props.attributes.textColor }, } ); } } );
Noch die CSS-Datei für Color Block
Gutenberg nutzt den Namen, der in der registerBlockType-Funktion übergeben wurde, und erzeugt daraus eine CSS-Klasse. Die Klasse unterliegt den folgenden Namenskonventionen:
wp-block-namespace-block-name
also für dieses Beispiel
wp-block-jscolorblock-color-block
In die CSS-Datei kommt dann noch
.wp-block-jscolorblock-color-block { padding: 20px; font-weight:300; }
Quellen: WordPress Package Reference
Gutenberg Block Tutorial
InspectorControls – How to Add Settings to Custom Gutenberg Blocks