Bestimmte Blöcke in InnerBlocks-Kom­po­nente verbieten

Bei der Entwicklung von Gutenberg-Blöcken ist die InnerBlocks-Komponente ein (zumindest bei mir) oft eingesetztes Mittel. Diese Komponente ermöglicht es, innerhalb eines Blocks weitere Blöcke einzufügen – bei den Core-Blöcken ist sie beispielsweise beim Spalten- und Cover-Block im Einsatz.

Dieser Komponente kann über das Attribut allowedBlocks ein Array von Blocknamen übergeben werden, um festzulegen, welche Blöcke eingefügt werden dürfen. Das ist zum Beispiel bei Wrapper-Blöcken hilfreich, wie dem Spalten-Block, der als direkten Kindblock nur den Block Spalte erlaubt.

Etwas komplizierter wird es, wenn nur bestimmte Blöcke nicht erlaubt sein sollen, denn etwas wie disallowedBlocks gibt es nicht.

Auf der Suche nach einer Lösung bin ich bei einer Antwort auf StackOverflow gelandet, die auf den ersten Blick genau das tut, was ich will. Nach Tests hat sich aber herausgestellt, dass die Lösung einen Nachteil hat: sie ignoriert die parent-Angabe von Blöcken, das heißt, es konnten auch Blöcke eingefügt werden, die normalerweise nur als Kindblöcke von bestimmten anderen Blöcken erlaubt sind.

Also habe ich den Code angepasst und herausgekommen ist die folgende Lösung, die ein Array mit den Namen aller Blöcke erstellt, die ohne die Angabe von allowedBlocks erlaubt wären, abgesehen vom Spalten-Block:

const ALLOWED_BLOCKS = wp.blocks.getBlockTypes().filter(block => { if (block.parent !== undefined) { return false; } if (block.name === 'core/columns') { return false; } return true; }).map(block => block.name);
Code-Sprache: JavaScript (javascript)

Zuerst holen wir uns über wp.blocks.getBlockTypes() ein Array mit allen registrierten Blöcken, das wir nach bestimmten Kriterien filtern müssen. Dafür nutzen wir die filter()-Methode, die jedes Array-Element an eine Funktion übergibt und ein neues Array aus den Werten erstellt, für die diese Funktion true zurückgibt (block enthält im Beispiel den aktuellen Array-Eintrag).

Wir prüfen in der Funktion zunächst, ob block.parent vorhanden ist, also der Block nur als Kind-Block eines bestimmten Blocks erlaubt ist. In diesem Fall geben wir false zurück, weil wir diese Blöcke nicht über unsere InnerBlocks-Komponente einfügen können wollen. Als nächstes prüfen wir, ob der Blockname core/columns ist, und geben in diesem Fall ebenfalls false zurück. In allen anderen Fällen gibt die Funktion true zurück, sodass wir an dieser Stelle ein Array mit allen Blöcken haben, die keine parent-Angabe haben und nicht core/columns sind.

Nun müssen wir aus diesem Array von Block-Objekten ein Array mit den Blocknamen machen und nutzen dafür die map()-Methode. Diese Methode übergibt jedes Array-Element an eine Funktion und erstellt ein neues Array aus den Rückgabewerten. Mit map(block => block.name) bekommen wir also ein Array von Blocknamen, wie es für allowedBlocks notwendig ist.

Dieses Ergebnis wird in ALLOWED_BLOCKS gespeichert und kann wie folgt an InnerBlocks übergeben werden:

<InnerBlocks allowedBlocks={ALLOWED_BLOCKS} />
Code-Sprache: JavaScript (javascript)

Damit haben wir eine InnerBlocks-Komponente, die alle ohne allowedBlocks-Angabe erlaubten Blöcke zulässt, außer den Spalten-Block.

Wenn es sich bei dem Block mit der InnerBlocks-Komponente um einen Block handelt, der für andere Blöcke der parent-Wert ist, muss die erste Prüfung angepasst werden, damit diese Blöcke weiter erlaubt sind:

if (block.parent !== undefined && !block.parent.includes('slug/blockname')) {
Code-Sprache: JavaScript (javascript)

slug/blockname ist dabei der Name des Blocks, der die InnerBlocks-Komponente enthält.

2 Reaktionen zu »Bestimmte Blöcke in InnerBlocks-Kom­po­nente verbieten«

Reposts

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert