How-To

WordPress 5.0: Das hat der neue Editor „Gutenberg“ zu bieten

Seite 2 / 2

Einbindung von Skript und Stylesheets

Neben dem Plugin-Header wird in der PHP-Datei nur noch die Einbindung verschiedener Dateien geregelt. Alles Weitere läuft dann über JavaScript. Zunächst wird das Skript zur Registrierung des Blocks und eine Stylesheet-Datei für das Backend eingebunden – die Be­nennung der Dateien ist von Zac Gordons Gutenberg-Kurs inspiriert:

add_action( 'enqueue_block_editor_assets', function() {
    wp_enqueue_script(
      't3n53-editor-script',
      plugins_url( 'assets/js/editor.blocks.js', __FILE__ ),
      [ 'wp-blocks', 'wp-element' ]
    );
    wp_enqueue_style(
      't3n53-editor-style',
      plugins_url( 'assets/css/editor.blocks.css', __FILE__ )
    );
} );

enqueue_block_editor_assets ist ein neuer Action-Hook, um Dateien für Blöcke in der Editoransicht bereitzustellen. Über ­wp_enqueue_script() wird das Skript assets/js/­editor.blocks.js eingebunden. Als Abhängigkeiten werden die ­Skripte wp-blocks und wp-element definiert, damit wir in dem Blockskript auf Bestandteile dieser Skripte des neuen Editors ­zugreifen können. Über wp_enqueue_style() wird an­schließend die CSS-Datei assets/css/editor.blocks.css eingebunden. Anschließend werden Styles für Frontend und Backend bereitgestellt:

add_action( 'enqueue_block_assets', function() {
    wp_enqueue_style(
      't3n53-frontend-style',
      plugins_url( 'assets/css/frontend.blocks.css', __FILE__ )
    );
} );

Auch hier kommt mit enqueue_block_assets ein neuer Action-­Hook zum Einsatz. Unterschied zu enqueue_block_­editor_­assets ist, dass er im Frontend und Backend läuft.

Wenn hierüber also ein Skript oder Stylesheet nur für das ­Frontend eingebunden werden sollte, müsste dafür mit ! is_admin() geprüft werden, ob es sich um einen Frontend-Aufruf handelt.

Die drei Dateien, die in den zwei Code-Blöcken eingebunden werden, sind jeweils das Ergebnis der Kompilierung des JavaScripts via Babel und vom Sass zu CSS. Erzeugt werden müssen die Dateien mit dem korrekten Namen und im richtigen Verzeichnis der eingesetzten Taskrunner.

Registrierung des Blocks

Innerhalb des t3n-gutenberg-block-Ordners wird ein Ordner blocks und darin ein Verzeichnis author-box erstellt. Darin ­finden die ganzen Dateien für den Block Platz. Es werden benötigt:

  • index.js, die nach Babel-Kompilierung als assets/js/editor.blocks.js gespeichert wird.
  • frontend.scss, die nach der Kompilierung zu CSS als ­assets/css/frontend.blocks.css gespeichert wird.
  • editor.scss, die nach der Kompilierung als assets/css/editor.blocks.css gespeichert wird.

Damit sind alle notwendigen Dateien angelegt. Der Taskrunner muss dafür sorgen, dass die Kompilierungsergebnisse mit den angegebenen Namen in den entsprechenden Verzeichnissen ausgegeben werden, von wo aus sie mit wp_enqueue_style() und wp_enqueue_script() eingebunden werden.

Importieren der notwendigen Komponenten

In der index.js werden zunächst die notwendigen Komponenten aus dem neuen Editor importiert:

const { Fragment } = wp.element;
const { registerBlockType } = wp.blocks;
const {
        MediaPlaceholder,
        BlockControls,
        RichText
} = wp.editor;
const {
        IconButton,
        Toolbar,
        TextControl
} = wp.components;
  • wp.element ist ein Abstraktionslayer für React, es wird hier also quasi React.Fragment importiert.
  • registerBlockType ist die Funktion zur Registrierung des Blocks.
  • Die übrigen Komponenten werden genutzt, um den Block ­abzubilden.

Um herauszufinden, welche Komponenten vorhanden sind, lohnt sich ein Blick in das Github-Repo des Editors. Im ­ackages/components/src-Verzeichnis liegen generische React-Komponenten, die zur Erstellung gängiger UI-Elemente genutzt werden können, wie beispielsweise IconButton. packages/editor/src/components beinhaltet über Komponenten, die spezifisch zur ­Erstellung eigener Editorlayouts gedacht sind, wie etwa RichText.

Aufruf der Registerblocktype-Funktion

Die entscheidende Funktion, damit der neue Editor den eigenen Block erkennt, ist registerBlockType(). So sieht der erste Teil dieser Registrierung aus:

registerBlockType( 't3n53/author-box', {
    title: 'Autorenbox',
    icon: 'admin-users',
    category: 'common',
    attributes: {
      name: {
          type: 'string',
          source: 'text',
          selector: '.author-name',
          default: ",
      },
      imgSrc: {
          type: 'string',
          source: 'attribute'‘,
          attribute: 'src',
          selector: 'img',
     },
      imgId: {
          type: 'number',
      },
      imgAlt: {
          type: 'string'‘,
          source: 'attribute',
          attribute: 'alt',
          selector: 'img',
      },
      description: {
          type: 'array',
          source: 'children',
          selector: '.author-description',
      },
  },

Als erster Parameter wird ein eindeutiger Bezeichner des Blocks angegeben, der sich aus einem Namespace (hier: t3n53) und dem Namen des Blocks zusammensetzt. Der zweite Parameter ist ein Objekt mit Einstellungen, von denen hier nicht alle genutzt werden:

  • title gibt den Blocktitel an.
  • icon ist das Icon des Blocks. Hier kann der Name eines ­Dash­icons oder ein SVG-Icon angegeben werden.
  • category ist die Kategorie, in der der Block aufgelistet werden soll.
  • attributes sind quasi die Daten des Blocks. Das sind für diesen Block der Autorenname (name), die URL des Bildes ­(imgSrc), die ID des Bildes (imgID), der Alternativtext des Bildes (imgAlt) sowie die Autorenbeschreibung (description).

Für die Attribute wird angegeben:

  • welchen Typ das Attribut hat,
  • optional mit source, wie der Attributwert vom ­ge­speicherten Beitragsinhalt extrahiert werden soll, (children heißt, dass Kindknoten des Elements extrahiert und als Array ­zurückgegeben werden, sodass zum Beispiel bei einem ­Absatz mit einer Verlinkung auch der Link mit gespeichert wird),
  • optional, welches HTML-Attribut genutzt werden soll, ­­­­falls ­es sich um einen Wert aus einem Attribut handelt,
  • optional, welcher Selektor den Wert enthält.

Wenn kein source angegeben ist, wird der Wert im Block­kommentar gespeichert, der in der post_content-­Datenbanktabelle jeden Block umschließt und von WordPress für das Blockparsing genutzt wird. Das sieht beispielsweise so aus:

<!-- wp:t3n53/author-box {"imgId":1573} -->
BlockMarkup
<!-- /wp:t3n53/author-box -->

Die Ansicht des Blocks im Backend

Über den edit-Key des Setting-Objekts der registerBlockType-Funktion wird angegeben, wie der Block im Backend dar­gestellt wird (um Platz zu sparen, wurden hier ein paar ­HTML-Elemente und Attribute von Komponenten weggelassen – den kompletten Code gibt es im Github-Repo):

 
edit: props => {
    const { attributes: { name, imgSrc, imgId, imgAlt, description }, className, setAttributes, isSelected } = props;
    const onSelectImg = ( img ) =>  {
      if ( ! img || ! img.url ) {
        setAttributes( { imgSrc: undefined, imgId: undefined } );
        return;
      }
      setAttributes( { imgSrc: img.url, imgId: img.id, imgAlt: img.alt } );
}
    return (
      <div className={ className }> 
        { ! imgId ? (
          <MediaPlaceholder /* […] */
            onSelect={ onSelectImg }
          /> 
        ) : (
          <Fragment> 
            <img src={ imgSrc } alt={ imgAlt } /> 
            { isSelected ? (
              <IconButton /* […] */
                onClick={ () => setAttributes( { imgSrc: null, imgId: null, imgAlt: null  } ) }
              /> 
            ) : " }
          </Fragment> 
        ) }
        <TextControl /* […] */
          value={ name }
          onChange={ ( name ) => setAttributes( { name } ) }
          /> 
          <RichText /* […] */
            value={ description }
            onChange={ ( description ) => setAttributes( { description } ) }
          /> 
        </div> 
    );
},

Zunächst werden notwendige Konstanten definiert. Aus dem props.attributes-Objekt werden die eigenen Attribute und der von WordPress generierte Klassenname für den Block (className) geholt, und aus props die Funktion zum Ändern der Attribute (setAttributes) sowie isSelected. onSelectImg prüft, ob ein Bild gewählt ist, und setzt die Bildattribute für das Bild entsprechend. Innerhalb des return-Teils wird der Block erstellt, der im Backend angezeigt wird. Wenn keine imgId gesetzt ist, wird die MediaPlaceholder-Komponente dargestellt, über die der Nutzer ein Bild hochladen oder aus der Mediathek wählen kann. Wenn ein Bild gewählt wird, wird onSelectImage ausgeführt. Ist ein Bild ausgewählt, wird es angezeigt. Wenn der Block dann aktiv ist (isSelected ist true), wird ein Iconbutton angezeigt, der bei einem Klick die Bildattribute auf Null setzt und so wieder die Anzeige von MediaPlaceholder triggert. Über eine TextControl-Komponente wird ein einfaches Textfeld angezeigt, das das name-Attribut befüllt. Des Weiteren wird für die Autoren­beschreibung ein RichText-Feld angezeigt, in dem der Nutzer auch grundlegende Formatierungen und Verlinkungen verwenden kann.

Die Funktion zum Speichern des Blockinhalts

Jetzt fehlt noch die save-Funktion, die festlegt, wie der Block­inhalt gespeichert wird. Im Gegensatz zu der edit-Funktion ist sie recht kurz:

save: props =>  {
    const { className, imgSrc, imgAlt, description, name } = props.attributes;
    return (
      < div className={ className }> 
        < div className='author-avatar'> 
          < img src={ imgSrc } alt={ imgAlt } /> 
        < /div> 
        < div className='author-meta'> 
          < p className='author-name'>{ name }</p> 
          < div className='author-description'> 
            { description }
          < /div> 
        < /div> 
      < /div> 
    );
},

Zuerst werden wieder die nötigen Attribute geholt und an­schließend mit return das Markup definiert, das gespeichert wird. Nach ein paar Zeilen Styling in den beiden CSS-Dateien sieht das Ergebnis im ­Backend aus wie in der Abbildung oben – einmal ohne Inhalt und einmal mit, jeweils im ausgewählten Zustand.

Fazit

Der Release-Zyklus für die neue Version startete im Dezember letzen Jahres. Er war eine große Umstellung für die ­WordPress-Nutzer aber auch Entwickler von Plugins und ­Themes. Trotzdem ­bietet der neue Editor mehr Freiheiten bei der Gestaltung von ­Inhalten in WordPress, ohne dass umständliche Shortcode­syntax genutzt, ein Pagebuilder installiert oder ­HTML-Kenntnisse erlernt werden müssen. Vorab sollte der neue Editor über das ­Plugin aber getestet werden, um Kompatibilitätsprobleme frühzeitig auszuschließen.

Für die Einarbeitung in die Entwicklung mit dem neuen Editor sind das Gutenberg-Repo sowie das Handbuch aus den Readme-­Dateien des Repos eine gute Anlaufstelle. Der Code der Core-­Blöcke (in core-blocks) liefert Informationen darüber, mit welchen Komponenten Standardblöcke umgesetzt wurden, ­worüber sich mindestens der Lösungsansatz für viele Anwendungsfälle ergibt.

Mehr Infos zu WordPress 5:

Bitte beachte unsere Community-Richtlinien

Wir freuen uns über kontroverse Diskussionen, die gerne auch mal hitzig geführt werden dürfen. Beleidigende, grob anstößige, rassistische und strafrechtlich relevante Äußerungen und Beiträge tolerieren wir nicht. Bitte achte darauf, dass du keine Texte veröffentlichst, für die du keine ausdrückliche Erlaubnis des Urhebers hast. Ebenfalls nicht erlaubt ist der Missbrauch der Webangebote unter t3n.de als Werbeplattform. Die Nennung von Produktnamen, Herstellern, Dienstleistern und Websites ist nur dann zulässig, wenn damit nicht vorrangig der Zweck der Werbung verfolgt wird. Wir behalten uns vor, Beiträge, die diese Regeln verletzen, zu löschen und Accounts zeitweilig oder auf Dauer zu sperren.

Trotz all dieser notwendigen Regeln: Diskutiere kontrovers, sage anderen deine Meinung, trage mit weiterführenden Informationen zum Wissensaustausch bei, aber bleibe dabei fair und respektiere die Meinung anderer. Wir wünschen Dir viel Spaß mit den Webangeboten von t3n und freuen uns auf spannende Beiträge.

Dein t3n-Team

Schreib den ersten Kommentar!

Melde dich mit deinem t3n Account an oder fülle die unteren Felder aus.

Bitte schalte deinen Adblocker für t3n.de aus!

Hey du! Schön, dass du hier bist. 😊

Bitte schalte deinen Adblocker für t3n.de aus, um diesen Artikel zu lesen.

Wir sind ein unabhängiger Publisher mit einem Team bestehend aus 65 fantastischen Menschen, aber ohne riesigen Konzern im Rücken. Banner und ähnliche Werbemittel sind für unsere Finanzierung sehr wichtig.

Danke für deine Unterstützung.

Digitales High Five,
Stephan Dörner (Chefredakteur t3n.de) & das gesamte t3n-Team

Anleitung zur Deaktivierung