Search code examples
javascriptreactjswordpresswordpress-gutenberg

How to set default variable in JSX for const with selector


I am fairly experienced with PHP and Wordpress theming, but now struggling with the new Gutenberg editor. I have created a custom block plugin, which involves a lot of JS (React). To the latter I am a bit new.

The block is creating a simple wrapper div with a html lang attribute assigned to it based on the input of a selector. The following code is working fine, however only when the selector is changed. By default the langCode variable remains empty. Any idea what goes wrong?

registerBlockType( 'lang-group-block/lang-group', {
    // Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block.
    title: __( 'Language group', 'lang-group-block' ), // Block title.
    icon: 'flag', // Block icon from Dashicons → https://developer.wordpress.org/resource/dashicons/.
    category: 'layout', // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.
    keywords: [
        __( 'Language', 'lang-group-block' ),
        __( 'Group', 'lang-group-block' ),
    ],

    attributes: {
        // Register langCode attribute to save the chosen language
        langCode: {
            type: 'string',         
        },
    },

    edit( { attributes, setAttributes, className } ) {
        const {
            langCode = 'en', 
        } = attributes;


        const groupIndicatorStyle = {
            fontSize: 14,
            color: "#ff0000",
            textAlign: "center",
            paddingTop: "40px",
        }

        return (            
            <Fragment>
                <InspectorControls>
                    <PanelBody
                        title={ __( 'Language', 'rapp2020-lang-group-block' ) }
                        initialOpen={ true }
                    >
                        <SelectControl
                            label={ __( 'Language', 'rapp2020-lang-group-block' ) }                         
                            value={ langCode }
                            options={ [
                                {
                                    value: 'en',
                                    label: __( 'EN', 'rapp2020-lang-group-block' ),
                                },
                                {
                                    value: 'nl',
                                    label: __( 'NL', 'rapp2020-lang-group-block' ),
                                },
                                {
                                    value: 'de',
                                    label: __( 'DE', 'rapp2020-lang-group-block' ),
                                },
                            ] }
                            onChange={ ( selectedOption ) => setAttributes( { langCode: selectedOption } ) }
                        />
                    </PanelBody>
                </InspectorControls>
                <div style={ groupIndicatorStyle }>
                    language group: { langCode }
                </div>
                <div
                    className={ className }
                    lang={ langCode }
                >
                    <InnerBlocks />
                </div>
            </Fragment>
        );      
    },

    save( { attributes, className } ) {
        const {
            langCode = '',
        } = attributes;

        let classes = className;
        if ( '' == langCode ) {
            { langCode: 'en' }
        }   

        return (
            <div
                className={ classes }
                lang={ langCode }
            >
                <InnerBlocks.Content />
            </div>
        );
    },
} );

Solution

  • This should be working:

    save( { attributes, className } ) {
        const { langCode } = attributes;
        let classes = className;
    
        return (
            <div
                className={ classes }
                lang={ langCode || 'en' }
            >
                <InnerBlocks.Content />
            </div>
        );
    },
    

    EDIT: Couldn't reproduce the still existing error. So here's the complete block already with createElements. Another suggestion: you're setting using 'en' as default. Why not setting it as such?

    ;( function ( wp ) {
    
        const el = wp.element.createElement;
        const __ = wp.i18n.__;
    
        const { Fragment } = wp.element;
        const { InspectorControls , InnerBlocks } = wp.blockEditor;
        const { PanelBody , SelectControl } = wp.components;
    
        wp.blocks.registerBlockType( 'lang-group-block/lang-group', {
            // Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block.
            title: __( 'Language group', 'lang-group-block' ), // Block title.
            icon: 'flag', // Block icon from Dashicons → https://developer.wordpress.org/resource/dashicons/.
            category: 'layout', // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.
            keywords: [
                __( 'Language', 'lang-group-block' ),
                __( 'Group', 'lang-group-block' ),
            ],
    
            attributes: {
                // Register langCode attribute to save the chosen language
                langCode: {
                    type: 'string', 
                    default : 'en'       
                },
            },
    
            edit( { attributes, setAttributes, className } ) {
    
                const groupIndicatorStyle = {
                    fontSize: 14,
                    color: '#ff0000',
                    textAlign: 'center',
                    paddingTop: '40px',
                }
    
                return el( Fragment, null , 
                    el( InspectorControls, null,
                      el( PanelBody,
                        { title: __('Language', 'rapp2020-lang-group-block'), initialOpen: true },
                        el(SelectControl, {
                          label: __('Language', 'rapp2020-lang-group-block'),
                          value: attributes.langCode,
                          options: [
                            { value: 'en', label: __('EN', 'rapp2020-lang-group-block') },
                            { value: 'nl', label: __('NL', 'rapp2020-lang-group-block') },
                            { value: 'de', label: __('DE', 'rapp2020-lang-group-block') }
                          ],
                          onChange: function onChange(selectedOption) { return setAttributes({ langCode: selectedOption }); }
                        })
                      )
                    ),
                    el( 'div', { style: groupIndicatorStyle }, 'language group: ', attributes.langCode  ),
                    el( 'div', { className: className, lang: attributes.langCode }, el(InnerBlocks, null) )
                  );
            },
    
            save( { attributes, className } ) {
                return el( 'div', { className: className, lang: attributes.langCode || 'en' }, el(InnerBlocks.Content, null) );
            },
        } );
    
    } )( window.wp );