In den letzten zwei Kapiteln haben wir uns angeschaut, wie wir Gutenberg Blöcke programmieren und Einstellungen in die Seitenleiste verlagern können. Auf dieser Seite geht es nun darum, wie sich Blöcke transformieren können.
Gutenberg Block-Transformation
Die Frage ist: was ist eine Transformation und warum benötigt man sie überhaupt?
Zum einen gibt uns Gutenberg die Möglichkeit, bereits bestehende Blöcke in andere über das Menü umzuwandeln. Das geht nur, wenn eine solche Regel erstellt wurde:
Zum zweiten kann es sein, dass wir unseren Block in Zukunft ändern und er deswegen transformiert werden muss. Damit ein Benutzer am Ende nicht mit einem defekten Block da steht, sollte eine Regel für eine Transformation definiert werden.
Beispiel-Plugin
Ich habe ein Beispiel-Plugin vorbeireitet, bin dabei vorgegangen, wie im Kapitel “Einen Gutenberg Block programmieren” beschrieben und das ist entstanden:
<?php
/**
* Plugin Name: mm Legend Block
* Plugin URI: https://wp-plugin-erstellen.de/ebook/block-apis/bloecke-transformieren/
* Description: An easy Gutenberg Block for generating HTML legends.
* Version: 0.1.0
* Author: Florian Simeth
*/
add_action('init', 'mmfb_init');
function mmfb_init()
{
wp_register_script(
'mmfb-fieldset-block',
plugin_dir_url(__FILE__) . 'js/fieldset.js',
['wp-blocks', 'wp-data', 'wp-editor', 'wp-i18n', 'wp-components'],
filemtime(plugin_dir_path(__FILE__) . '/js/fieldset.js')
);
wp_enqueue_script('mmfb-fieldset-block');
wp_register_style(
'mmfb-fieldset-block',
plugin_dir_url(__FILE__) . 'css/layout.css',
[],
filemtime(plugin_dir_path(__FILE__) . '/css/layout.css')
);
if (!is_admin() && is_singular()) {
global $wp_query;
$post = $wp_query->get_queried_object();
if ($post instanceof WP_Post && has_block($post->post_content)) {
#wp_enqueue_style('mmfb-fieldset-block');
}
}
register_block_type(
'mm/fieldset',
[
'style' => 'mmfb-fieldset-block',
]
);
}
const {__} = wp.i18n;
const {registerBlockType} = wp.blocks;
const {RichText} = wp.blockEditor;
registerBlockType(
'mm/fieldset',
{
title: 'Fieldset',
category: 'widgets',
icon: 'editor-kitchensink',
keywords: [
'MM',
'Fieldset',
'Label'
],
supports: {
multiple: true,
align: true,
className: true
},
attributes: {
legend: {
source: 'text',
type: 'string',
selector: 'legend'
},
content: {
source: 'html',
type: 'string',
selector: 'div.content'
}
},
edit: props => {
const {attributes, setAttributes} = props;
return <fieldset className="mm-fieldset">
<RichText
tagName="legend"
value={attributes.legend}
placeholder={__('Enter a label', 'mfb')}
multiline={false}
onChange={(value) => {
setAttributes({legend: value})
}} /> <RichText
tagName="div"
className="content"
value={attributes.content}
placeholder={__('Enter some content', 'mfb')}
multiline={false}
onChange={(value) => {
setAttributes({content: value})
}} />
</fieldset>;
},
save: props => {
const {attributes} = props;
return <fieldset className="mm-fieldset">
<RichText.Content tagName="legend" value={attributes.legend} /> <RichText.Content tagName="div"
className="content" value={attributes.content} />
</fieldset>
}
}
);
.mm-fieldset {
border: 2px solid gray;
padding: .5rem;
}
.mm-fieldset legend {
box-sizing: border-box;
color: inherit;
display: table;
max-width: 100%;
white-space: normal;
margin-top: -1.7rem;
background-color: #fff;
padding: 0 1rem;
}
.mm-fieldset .content {
padding: 0 1rem;
}
Sie können das Beispiel-Plugin hier herunterladen.
Transformieren
Dem Beispiel oben können wir entnehmen, dass der Block folgenden Code erzeugt:
<fieldset class="mm-fieldset">
<legend>Label 1</legend>
<div class="content">Inhalt 1</div>
</fieldset>
Fall 1: Ändern des Ausgabe-Codes
Nehmen wir an, wir müssen aus irgend einem Grund, den Ausgabecode des Blocks verändern:
registerBlockType(
'mm/fieldset',
{
...
save: props => {
const {attributes} = props;
return <div className="mm-fieldset">
<fieldset className="mm-fieldset">
<RichText.Content tagName="legend" value={attributes.legend} /> <RichText.Content tagName="div"
className="content" value={attributes.content} />
</fieldset>
</div>
}
}
);
Es kommt also ein umrahmendes <div>
drumherum. Ein Reload unserer erzeugt einen Fehler im Block:
Nach der Aktualisierung der Seite in der der Block integriert wurde, sehen wir in der JavaScript-Konsole eine Meldung:
Block successfully updated for `mm/fieldset` (...).
New content generated by `save` function:
<div class="wp-block-mm-fieldset mm-fieldset"><fieldset class="mm-fieldset"><legend>Label 1</legend> <div class="content">Enter 1</div></fieldset></div>
Content retrieved from post body:
<fieldset class="wp-block-mm-fieldset mm-fieldset"><legend>Label 1</legend> <div class="content">Enter 1</div></fieldset>
Fall 2: In andere Blöcke transformieren
Nun schauen wir den zweiten Fall an: wir wollen dem Benutzer die Möglichkeit geben, Blöcke in andere Umzuwandeln. Das schaffen wir mit der transform
-Eigenschaft:
Im obigen Beispiel definieren wir, dass unser Block in einen Paragraph-Block umgewandelt werden kann. Wir erhalten dann die Option, den Block in einen Paragraph-Block umzuwandeln:
Fall 3: Von anderen Blöcken transformieren
Natürlich funktioniert das auch genau anders herrum. Beispielsweise Paragraph-Blöcke in den Fieldset-Block zu transformieren:
Easy, oder? Gutenberg zeigt uns nun im Absatz-Block die Möglichkeit, in unseren Fieldset-Block umzuwandeln: