I am trying to add a select field and a title field to a certain block. I used this example as starting point:
Edited: My code is
const { assign } = lodash;
const { addFilter } = wp.hooks;
const { __ } = wp.i18n;
// Enable contenttype control on the following blocks
const enableBlockContentTypeAttribute = [
'uagb/section',
];
// Available contenttype control options
const contenttypeControlOptions = [
{
label: __( 'None' ),
value: '',
},
{
label: __( 'Exercise' ),
value: 'exercise',
},
{
label: __( 'Workshop' ),
value: 'workshop',
},
{
label: __( 'Something' ),
value: 'something',
},
];
/**
* Add contenttype control attribute to block.
*
* @param {object} settings Current block settings.
* @param {string} name Name of block.
*
* @returns {object} Modified block settings.
*/
const addBlockContentTypeAttribute = ( settings, name ) => {
// Do nothing if it's another block than our defined ones.
if ( ! enableBlockContentTypeAttribute.includes( name ) ) {
return settings;
}
settings.attributes = assign( settings.attributes, {
contenttype: {
type: 'string',
default: contenttypeControlOptions[ 0 ].value,
},
contenttitle: {
type: 'string',
default: '',
}
} );
return settings;
};
addFilter( 'blocks.registerBlockType', 'my-mods/attribute/contenttype', addBlockContentTypeAttribute );
const { createHigherOrderComponent } = wppose;
const { Fragment } = wp.element;
const { InspectorControls, InnerBlocks } = wp.editor;
const { PanelBody, PanelRow, SelectControl, TextControl } = wpponents;
/**
* Create HOC to add content type control to inspector controls of block.
*/
const withContentTypeControl = createHigherOrderComponent( ( BlockEdit ) => {
return ( props ) => {
// Do nothing if it's another block than our defined ones.
if ( ! enableBlockContentTypeAttribute.includes( props.name ) ) {
return (
<BlockEdit { ...props } />
);
}
const { contenttype } = props.attributes;
const { contenttitle } = props.attributes;
function getContentTitle ( content ) {
props.setAttributes({contenttitle: content});
}
return (
<Fragment>
<BlockEdit { ...props } />
<InspectorControls>
<PanelBody
title={ __( 'Choose Content Type' ) }
initialOpen={ true }
>
<SelectControl
label={ __( 'Content Type' ) }
value={ contenttype }
options={ contenttypeControlOptions }
onChange={ ( selectedSpacingOption ) => {
props.setAttributes( {
contenttype: selectedSpacingOption,
} );
} }
/>
<TextControl
label={ __( 'Content Title' ) }
value={ contenttitle }
onChange={ ( getContentTitle ) => {
props.setAttributes( {
contenttitle: getContentTitle,
});
}}
/>
</PanelBody>
</InspectorControls>
</Fragment>
);
};
}, 'withSpacingControl' );
addFilter( 'editor.BlockEdit', 'my-mods/with-contenttype-control', withContentTypeControl );
// do something with these attributes - add header to section if exercise type block
const addContentTypeMarkup = ( element, blockType, attributes ) => {
// Do nothing if it's another block than our defined ones.
if ( ! enableBlockContentTypeAttribute.includes( blockType.name ) ) {
return element;
}
if ( attributes.contenttitle) {
// add header with anchor link and class name
var title_slug = attributes.contenttitle.trim().split(/\s+/).join('-');
const Heading = "h" + 3;
return (
<React.Fragment>
<h3 id = {`${title_slug}`}>{attributes.contenttitle}</h3>
{element}
</React.Fragment>
)
} else {
return element;
}
};
addFilter( 'blocks.getSaveElement', 'my-mods/add-content-type-markup', addContentTypeMarkup);
import classnames from 'classnames';
function applyExtraClass( extraProps, blockType, attributes ) {
if ( ! enableBlockContentTypeAttribute.includes( blockType.name ) ) {
return extraProps;
}
const { contenttype } = attributes;
//add class if content type set
if ( contenttype !== '' ) {
console.log('add class name for content type');
extraProps.className = classnames( extraProps.className, 'sometopictype-'+contenttype );
}
return extraProps;
}
addFilter(
'blocks.getSaveContent.extraProps',
'my-mods/applyExtraClass',
applyExtraClass
);
I am getting this error:
Invariant Violation: Minified React error #130; visit .html?invariant=130&args[]=undefined&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
When I go to the link I see
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.
Can't figure out what is causing this. Everything was working fine when I just had the select control. Then added the text control and it broke. Ideas? I am new to React so probably something I am not understanding about syntax or something.
Note: Now working with edited code.