Block-Editor: Inhaltsposition auch beim Gruppen-Block
Veröffentlicht: – Kommentar hinterlassen
Du kennst vielleicht die Einstellung zur Inhaltsposition in Cover-Blöcken, um den Inhalt innerhalb des Covers horizontal und vertikal zu zentrieren. Da der Gruppen-Block ähnlich verwendet werden kann und wir ihn in einem individuellen Slider-Block verwenden, wollten wir identische Einstellungen für den Gruppen-Block haben.

Dazu benötigen wir als erstes die Option selbst in der Werkzeugleiste des Gruppen-Blocks. Diese erhält man mit folgendem Code:
import assign from 'lodash.assign';
import {
BlockControls,
__experimentalBlockAlignmentMatrixControl as BlockAlignmentMatrixControl,
store as blockEditorStore
} from '@wordpress/block-editor';
import { createHigherOrderComponent } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';
import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
const addAttributes = ( settings, name ) => {
if ( name !== 'core/group' ) {
return settings;
}
settings.attributes = assign( settings.attributes, {
contentPosition: {
default: 'top left',
type: 'string',
},
} );
return settings;
}
addFilter( 'blocks.registerBlockType', 'rh-group/add-attributes', addAttributes );
const addControls = createHigherOrderComponent( ( BlockEdit ) => {
return ( props ) => {
if ( props.name !== 'core/group' ) {
return ( <BlockEdit { ...props } /> );
}
const {
attributes: {
contentPosition,
},
clientId,
setAttributes,
} = props;
const hasInnerBlocks = useSelect(
( select ) =>
select( blockEditorStore ).getBlock( clientId ).innerBlocks.length >
0,
[ clientId ]
);
return (
<>
<BlockEdit
{ ...props }
/>
<BlockControls group="block">
<BlockAlignmentMatrixControl
label={ __( 'Change content position', 'rh-60' ) }
value={ contentPosition }
onChange={ ( nextPosition ) =>
setAttributes( {
contentPosition: nextPosition,
} )
}
isDisabled={ ! hasInnerBlocks }
/>
</BlockControls>
</>
);
};
}, 'addControls' );
addFilter( 'editor.BlockEdit', 'rh-group/add-controls', addControls, 5 );
const addClass = createHigherOrderComponent( ( BlockListBlock ) => {
return ( props ) => {
const {
attributes: {
contentPosition,
},
name,
} = props;
if ( name !== 'core/group' || contentPosition === 'top left' ) {
return ( <BlockListBlock { ...props } /> );
}
return (
<BlockListBlock{ ...props }
className={ 'is-custom-position is-position-' + contentPosition.replace( ' ', '-' ) }
/>
);
};
},
'addClass' );
addFilter( 'editor.BlockListBlock', 'rh-group/add-class', addClass );
Code-Sprache: JavaScript (javascript)
Dies fügt zuerst die Möglichkeit hinzu, die Einstellung zu speichern (Zeile 12 – 27), dann das Kontrollelement in der Werkzeugleiste (Zeile 29 – 72) und dann die Klasse, die wir später in SCSS benutzen, um die Einstellungen, die wir im Kontrollelement vornehmen, im Editor sichtbar zu machen (Zeile 74 – 96).
Dann benötigen wir das besagte Styling in SCSS:
.wp-block-group.is-custom-position {
display: flex;
flex-direction: column;
height: 100%;
margin-left: auto;
margin-right: auto;
// make sure centered aligned content is still centered
> .has-text-align-center {
width: 100%;
}
> .wp-block {
margin-left: 0;
margin-right: 0;
}
&.is-position-top-left {
align-items: flex-start;
justify-content: flex-start;
}
&.is-position-top-center {
align-items: center;
justify-content: flex-start;
}
&.is-position-top-right {
align-items: flex-end;
justify-content: flex-start;
}
&.is-position-center-left {
align-items: flex-start;
justify-content: center;
}
&.is-position-center-center {
align-items: center;
justify-content: center;
}
&.is-position-center-right {
align-items: flex-end;
justify-content: center;
}
&.is-position-bottom-left {
align-items: flex-start;
justify-content: flex-end;
}
&.is-position-bottom-center {
align-items: center;
justify-content: flex-end;
}
&.is-position-bottom-right {
align-items: flex-end;
justify-content: flex-end;
}
}
Code-Sprache: SCSS (scss)
Dieses SCSS kann im Backend als auch im Frontend verwendet werden.
Für das Frontend müssen wir nun noch ebenfalls die Klasse hinzufügen, damit auch dort das SCSS greift:
/**
* Add group block content position class.
*
* @param string $block_content The block content
* @param array $block Block data
* @return string The updated block content
*/
// phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase, WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
function my_add_block_group_content_position( string $block_content, array $block ) {
libxml_use_internal_errors( true );
$dom = new DOMDocument();
$dom->loadHTML(
mb_convert_encoding(
'<html>' . $block_content . '</html>',
'HTML-ENTITIES',
'UTF-8'
),
LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
);
foreach ( $dom->getElementsByTagName( 'div' ) as $div ) {
// check for desired class name
if ( strpos( $div->getAttribute( 'class' ), 'wp-block-group' ) === false ) {
continue;
}
// check if we already processed this div
if ( strpos( $div->getAttribute( 'class' ), 'is-position-' ) !== false ) {
continue;
}
if ( empty( $block['attrs']['contentPosition'] ) ) {
continue;
}
$div->setAttribute( 'class', $div->getAttribute( 'class' ) . ' is-position-' .str_replace( ' ', '-', $block['attrs']['contentPosition'] ) );
}
return str_replace(
[
'<html>',
'</html>',
],
[
'',
'',
],
$dom->saveHTML( $dom->documentElement )
);
}
// phpcs:enable
add_filter( 'render_block_core/group', 'my_add_block_group_content_position', 10, 2 );
Code-Sprache: PHP (php)
Hinweis: Wenn du die individuelle vertikale Ausrichtung verwenden möchtest, musst du deinen Gruppen-Blöcken eine individuelle Höhe geben. Da diese normalerweise nur so hoch sind wie ihr Inhalt, hat das Ändern der vertikalen Ausrichtung keinen Effekt, da es keinen zusätzlichen Platz gibt, der die Ausrichtung verändern kann. Wenn du aber beispielsweise eine Mindesthöhe von 400 px festlegst und der Inhalt der Gruppen-Blöcke nicht so hoch ist, funktioniert die vertikale Ausrichtung wunderbar.