• Resolved HU ist Sebastian

    (@kuchenundkakao)


    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!

Viewing 10 replies - 1 through 10 (of 10 total)
  • Plugin Support David Smith

    (@get_dave)

    Hi @kuchenundkakao

    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.
    Plugin Support David Smith

    (@get_dave)

    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'
            }
        } 
    );
    Thread Starter HU ist Sebastian

    (@kuchenundkakao)

    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.

    Plugin Support David Smith

    (@get_dave)

    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

    Thread Starter HU ist Sebastian

    (@kuchenundkakao)

    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!

    Plugin Support David Smith

    (@get_dave)

    Hi there

    Sorry I should have explained that. There’s a great guide on how to test a PR here

    Testing a Gutenberg Pull Request (PR)

    I hope that helps.

    Thread Starter HU ist Sebastian

    (@kuchenundkakao)

    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…

    Thread Starter HU ist Sebastian

    (@kuchenundkakao)

    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!

    Plugin Support David Smith

    (@get_dave)

    @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

    Thread Starter HU ist Sebastian

    (@kuchenundkakao)

    @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
    );
Viewing 10 replies - 1 through 10 (of 10 total)
  • The topic ‘Cannot add Top, Left etc. styles with blocks.getSaveContent.extraProps Filter’ is closed to new replies.