Cannot add Top, Left etc. styles with blocks.getSaveContent.extraProps Filter
-
Hi!
I’m using a filter to add some attributes for positioning absolute-positioned images on the page. But while i can add inline styles for background-color like described in https://developer.www.ads-software.com/block-editor/reference-guides/filters/block-filters/, styles like top, bottom, or even inset are stripped from the styles and are not saved.
This is my code:
addFilter( 'blocks.getSaveContent.extraProps', 'huishu/uniiique-lab-image-addition', applyExtraClass ); function applyExtraClass( extraProps, blockType, attributes ) { const { huliaAbsolutePositioning, huliaTop, huliaLeft, huliaRight, huliaBottom } = attributes; if( ! allowedBlocks.includes( blockType.name ) ){ return extraProps; } //check if attribute exists for old Gutenberg version compatibility //add class only when visibleOnMobile = false //add allowedBlocks restriction if ( typeof huliaAbsolutePositioning !== 'undefined' && huliaAbsolutePositioning && allowedBlocks.includes( blockType.name ) ) { const myTop = huliaTop || 'auto'; const myRight = huliaRight || 'auto'; const myBottom = huliaBottom || 'auto'; const myLeft = huliaLeft || 'auto'; const myStyle = myTop + ' ' + myRight + ' ' + myBottom + ' ' + myLeft; return lodash.assign( extraProps, { className: classnames( extraProps.className, 'has-absolute-positioning' ), style: { inset: "10px 10px auto auto" } } ); } return extraProps; }
Please help!
-
Thanks for raising this.
It looks like you’re working with your own custom block, is that correct?
Have you tried doing the same with one of the Core blocks? I ask because it would be useful to have a reduced test case to work with as this one has lots of other logic which it would be better to omit when testing the specific requirement of altering style attributes in the
blocks.getSaveContent.extraProps
filter.I’ll see what I can do to look into this. If you are able to produce a reduced test case that would be greatly appreciated.
Many thanks
- This reply was modified 2 years, 10 months ago by David Smith.
I just noticed that here you are trying to set a CSS property called
inset
.return lodash.assign( extraProps, { className: classnames( extraProps.className, 'has-absolute-positioning' ), style: { inset: "10px 10px auto auto" } } );
As far as I know that doesn’t exist in the CSS spec.
Can you try setting a really simple, valid property such as
backgroundColor: red
?return lodash.assign( extraProps, { className: classnames( extraProps.className, 'has-absolute-positioning' ), style: { backgroundColor: 'red' } } );
Hi Dave,
actually, i’m trying to extend the core/image Block.
You can reduce it to this:
addFilter( 'blocks.getSaveContent.extraProps', 'huishu/image-style-addition', applyExtraClass ); function applyExtraClass( extraProps, blockType, attributes ) { if( ! (blockType.name == 'core/image') ){ return extraProps; } return lodash.assign( extraProps, { style: { top: "10px" } } ); } return extraProps; }
The “inset” is supposed to be a shorthand for the 4 attributes top, left, right and bottom and works in browsers.
However i resorted to using inset because i thought maybe that will work. Tried with top, left, etc too.
CSS Style attributes like
backgroundColor: 'red'
do work (tried that too).It seems as if the style attribute of the extra Props get parsed and only some will get echoed into the inline style. I could find no information about it anywhere.
I looked into this some more. I was able to get the
style
attribute to appear within the editor but when published it is removed on the front end of the site.After some debugging I believe this is due to overzealous block validation marking changes to style attributes as making the block invalid. This causes the block to be serialized to the database without the style attribute.
Indeed I checked the post in the database and no style attribute was there despite my having seen it in the editor prior to saving.
There is a PR open for this very scenario. I applied it and it appears to fix the problem. I left a comment there to see if folks think the problem you raise is related.
Could you try testing out the PR and see if it works for you then?
Many thanks
Wow thank you so much!
I would really like to try to apply the fix. However, i am not sure i understand how to do so…
Do i just download the https://github.com/WordPress/gutenberg/tree/try/ignore-style-validation-errors branch and use it as the Gutenberg Plugin? Or do i have to do something first, like run an npm build or anything like this? (As is develop and use the “integrated” block editor version of Gutenberg instead of the standalone plugin, i am not used to this ?? )
Thanks again!
Hi there
Sorry I should have explained that. There’s a great guide on how to test a PR here
I hope that helps.
Okay, thanks for that.
But i think something is seriously messed up in the Block Editor in 5.9. All the Class Names i add by the filter editor.BlockEdit are not inserted into the editor anymore.
For Instance (simplified):
const withInspectorControls = createHigherOrderComponent( ( BlockEdit ) => { return ( props ) => { const { name, attributes, setAttributes, isSelected, } = props; props.className = classnames( props.className, 'i-want-to-get-added' ); return ( <Fragment> <BlockEdit {...props} /> </Fragment> ); }; }, 'withInspectorControls'); addFilter( 'editor.BlockEdit', 'huishu/block-font-picker', withInspectorControls );
Whatever i try, the damn classes don’t get added anymore. Before 5.9 this worked… Any Idea? This not working would mean a lot of stuff breaks in my backends…
Hey @get_dave, thanks for all the help.
Somehow, through rewriting the code, i managed to get it right. I didn’t rewrite the “interesting” parts though, so i am not quite sure why it didn’t work before but now does.
Thanks again!
@kuchenundkakao Glad to hear you managed to get it sorted. Any chance you could post the working code so others can learn?
Much appreciated
Dave
@get_dave I am so sorry for the back and forth. But i found out today that NO, it did not magically fix itself, but a php filter i put on the Block to add the styles that i forgot about at rendering.
So the real answer is here: not only does the adding styles to ExtraProps per blocks.getSaveContent.extraProps Filter with the Block Editor in WordPress 5.9, it also doesn’t work with the Pull Request you linked me to.
I’m pasting the complete code of my index.js for more context:
/** * External Dependencies */ import classnames from 'classnames'; /** * WordPress Dependencies */ const { __ } = wp.i18n; const { addFilter } = wp.hooks; const { Fragment } = wp.element; import { InspectorControls, useBlockProps } from '@wordpress/block-editor'; const { createHigherOrderComponent } = wp.compose; import { Panel, PanelBody, PanelRow, ToggleControl, TextControl, SelectControl } from '@wordpress/components'; import './index.scss'; //restrict to specific block names const allowedBlocks = [ 'core/image' ]; /** * * @param {Object} settings Settings for the block. * * @return {Object} settings Modified settings. */ function addAttributes( settings ) { if( allowedBlocks.includes( settings.name ) ){ const { attributes } = settings; return { ...settings, attributes: { ...attributes, huliaAbsolutePositioning:{ type: 'boolean', default: false, }, huliaScaleDown:{ type: 'boolean', default: false, }, huliaTransformDirection:{ type: 'string', default: 'top-left' }, huliaTop:{ type: 'string' }, huliaBottom:{ type: 'string' }, huliaLeft:{ type: 'string' }, huliaRight:{ type: 'string' } } } } return settings; } /** * Add controls on Advanced Block Panel. * * @param {function} BlockEdit Block edit component. * * @return {function} BlockEdit Modified block edit component. */ const withInspectorControls = createHigherOrderComponent( ( BlockEdit ) => { return ( props ) => { const { name, attributes, setAttributes, isSelected } = props; const { huliaAbsolutePositioning, huliaTop, huliaLeft, huliaRight, huliaBottom, huliaScaleDown, huliaTransformDirection } = attributes; if( ! allowedBlocks.includes( name )){ return ( <Fragment> <BlockEdit {...props} /> </Fragment> ) } return ( <Fragment> <BlockEdit {...props}/> { isSelected && allowedBlocks.includes( name ) && <InspectorControls> <Panel> <PanelBody title="Positionierung" initialOpen={ false }> <PanelRow> <ToggleControl label={ !! huliaAbsolutePositioning ? __( 'Absolut positioniert' ) : __( 'normale Positionierung' ) } checked={ !! huliaAbsolutePositioning } onChange={ () => setAttributes( { huliaAbsolutePositioning: ! huliaAbsolutePositioning } ) } /> </PanelRow> { !! huliaAbsolutePositioning && <Fragment> <PanelRow> <TextControl onChange={ e => setAttributes( { huliaTop : e } ) } label="Abstand von oben" value={ huliaTop } /> </PanelRow> <PanelRow> <TextControl onChange={ e => setAttributes( { huliaRight : e } ) } label="Abstand von rechts" value={ huliaRight } /> </PanelRow> <PanelRow> <TextControl onChange={ e => setAttributes( { huliaLeft : e } ) } label="Abstand von links" value={ huliaLeft } /> </PanelRow> <PanelRow> <TextControl onChange={ e => setAttributes( { huliaBottom : e } ) } label="Abstand von unten" value={ huliaBottom } /> </PanelRow> </Fragment> } <PanelRow> <ToggleControl label={ !! huliaScaleDown ? __( 'Auf die h?lfte Skalieren' ) : __( 'nicht runterskalieren' ) } checked={ !! huliaScaleDown } onChange={ () => setAttributes( { huliaScaleDown: ! huliaScaleDown } ) } /> </PanelRow> { !! huliaScaleDown && <Fragment> <PanelRow> <SelectControl label={ __( 'Ausrichtung' ) } value={ huliaTransformDirection } // e.g: value = [ 'a', 'c' ] onChange={ ( newDirection ) => { setAttributes({huliaTransformDirection: newDirection}); } } options={ [ { value: null, label: 'Bitte ausw?hlen', disabled: true }, { value: 'top-left', label: 'Oben links' }, { value: 'top-right', label: 'Oben rechts' }, { value: 'bottom-left', label: 'Unten links' }, { value: 'bottom-right', label: 'Unten rechts' }, ] } /> </PanelRow> </Fragment> } </PanelBody> </Panel> </InspectorControls> } </Fragment> ); }; }, 'withInspectorControls'); /** * Use BlockList Filter to show the correct styles and classes within the Block Editor */ const showInEditor = createHigherOrderComponent( ( BlockListBlock ) => { return ( props ) => { const { name, block, attributes, setAttributes, isSelected, className } = props; const { huliaAbsolutePositioning, huliaTop, huliaLeft, huliaRight, huliaBottom, huliaScaleDown, huliaTransformDirection } = attributes; let wrapperProps = props.wrapperProps ? props.wrapperProps : {}; if( ! allowedBlocks.includes( name ) ){ return <BlockListBlock {...props} /> } const mystyle = ( !! huliaAbsolutePositioning ) ? { 'top': huliaTop || 'auto', 'left': huliaLeft || 'auto', 'right': huliaRight || 'auto', 'bottom': huliaBottom || 'auto' } : {}; const classes = (!! huliaAbsolutePositioning) ? 'has-absolute-positioning' + ( !! huliaScaleDown ? ' is-scale-half' + ( !! huliaTransformDirection ? ' has-transform-origin-'+huliaTransformDirection : '' ) : '' ) : ''; const newClassName = classnames( className, classes ); wrapperProps.className = newClassName; wrapperProps.style = mystyle; return <BlockListBlock {...props} className={ newClassName } wrapperProps={ wrapperProps } /> }; }); /** * Add custom element class and styles in save element. * * @param {Object} extraProps Block element. * @param {Object} blockType Blocks object. * @param {Object} attributes Blocks attributes. * * @return {Object} extraProps Modified block element. */ function applyExtraClass( extraProps, blockType, attributes ) { const { huliaAbsolutePositioning, huliaTop, huliaLeft, huliaRight, huliaBottom, huliaScaleDown, huliaTransformDirection } = attributes; if( ! allowedBlocks.includes( blockType.name ) ){ return extraProps; } const mystyle = ( !! huliaAbsolutePositioning ) ? { 'top': huliaTop || 'auto', 'left': huliaLeft || 'auto', 'right': huliaRight || 'auto', 'bottom': huliaBottom || 'auto' } : {}; const classes = (!! huliaAbsolutePositioning) ? 'has-absolute-positioning' + ( !! huliaScaleDown ? ' is-scale-half' + ( !! huliaTransformDirection ? ' has-transform-origin-'+huliaTransformDirection : '' ) : '' ) : ''; return lodash.assign( extraProps, { className: classnames( extraProps.className, classes ), style: mystyle } ); } //add filters addFilter( 'blocks.registerBlockType', 'huishu/uniiique-lab-image-addition', addAttributes ); addFilter( 'editor.BlockEdit', 'huishu/uniiique-lab-image-addition', withInspectorControls ); addFilter( 'blocks.getSaveContent.extraProps', 'huishu/uniiique-lab-image-addition', applyExtraClass ); wp.hooks.addFilter( 'editor.BlockListBlock', 'huishu/uniiique-lab-image-addition', showInEditor );
- The topic ‘Cannot add Top, Left etc. styles with blocks.getSaveContent.extraProps Filter’ is closed to new replies.