I am absolutely new to Gutenberg and trying to learn it. Today I have created a custom block with multiple fields.
Here is the code:
const { __ } = wp.i18n; // Import __() from wp.i18n
const { registerBlockType } = wp.blocks; // Import registerBlockType() from wp.blocks
const { RichText } = wp.editor;
registerBlockType( 'ss-events/event-info', {
title: __( 'Event Info' ),
icon: 'welcome-view-site',
category: 'common',
keywords: [
__( 'Event' ),
__( 'New Event' ),
__( 'Manage Event' ),
],
attributes: {
teaser: {
type: 'array',
source: 'children',
selector: 'p',
},
ev_date:{
type: 'array',
source: 'children',
selector: 'p',
},
ev_time: {
type: 'array',
source: 'children',
selector: 'p',
},
venue: {
type: 'array',
source: 'children',
selector: 'p',
},
ev_nature: {
type: 'array',
source: 'children',
selector: 'p',
},
organizer: {
type: 'array',
source: 'children',
selector: 'p',
},
},
edit: function( props ) {
/* define variables */
let teaser = props.attributes.teaser;
let ev_date = props.attributes.ev_date;
let ev_time = props.attributes.ev_time;
let ev_nature = props.attributes.ev_nature;
let venue = props.attributes.venue;
let organizer = props.attributes.organizer;
/* define functions */
function onChangeTeaser( content ) {
props.setAttributes( { teaser: content } );
}
function onChangeEventDate( content ) {
props.setAttributes( { ev_date: content } );
}
function onChangeEventTime( content ) {
props.setAttributes( { ev_time: content } );
}
function onChangeVenue( content ) {
props.setAttributes( { venue: content } );
}
function onChangeEventNature( content ) {
props.setAttributes( { ev_nature: content } );
}
function onChangeOrganizer( content ) {
props.setAttributes( { organizer: content } );
}
return (
<div id="ss-event-info">
<label><b>Event Information</b></label>
<p>
<label>Short Description</label>
<RichText
tagName = "p"
className = { props.className }
value = { props.attributes.teaser }
onChange = { onChangeTeaser }
role = "textbox"
aria-multiline = "true"
/>
</p>
<p>
<label>Event Date</label>
<RichText
tagName="p"
className={ props.className }
value={ ev_date }
onChange={ onChangeEventDate }
role="textbox"
aria-multiline="true"
/>
</p>
<p>
<label>Event Time</label>
<RichText
tagName="p"
className={ props.className }
value={ ev_time }
onChange={ onChangeEventTime }
role="textbox"
aria-multiline="true"
/>
</p>
<p>
<label>Venue</label>
<RichText
tagName="p"
className={ props.className }
value={ venue }
onChange={ onChangeVenue }
role="textbox"
aria-multiline="true"
/>
</p>
<p>
<label>Nature of Event</label>
<RichText
tagName="p"
className={ props.className }
value={ ev_nature }
onChage={ onChangeEventNature }
role="textbox"
aria-multiline="true"
/>
</p>
<p>
<label>Organized by</label>
<RichText
tagName="p"
clasName={ props.className }
value={ organizer }
onChange={ onChangeOrganizer }
role="textbox"
aria-multiline="true"
/>
</p>
</div>
);
},
save: function( props ) {
return (
<RichText.content tagName="p" value={ props.attributes.teaser }/>
);
},
} );
The block appears fine in the editor when I click it from the inserter dialog but information I put in block's field are not getting saved at all!
I am using create-guten-block
tool to create the block structure:
npx create-guten-block ss-events
Gutenberg is a completely new world for me and I have no idea what I am doing wrong.
Your content is not saving because your save function only specified for teaser
<RichText.content tagName="p" value={ props.attributes.teaser }/>
and will save teaser attribute nothing else. Take a look at this Gutenberg block See how pcontent also needs to be called in the save function? That's what you need to do. For every new attributes you need to call them inside save function as well.
<div>
<RichText.content tagName="p" value={ props.attributes.teaser }/>
<RichText.content tagName="p" value={ props.attributes.ev_date}/>
<RichText.content tagName="p" value={ props.attributes.ev_time}/>
<RichText.content tagName="p" value={ props.attributes.ev_nature}/>
<RichText.content tagName="p" value={ props.attributes.venue}/>
<RichText.content tagName="p" value={ props.attributes.organizer}/>
</div>
What did I do? I added RichText content for every new attributes and then wrapped them in a parent DIV, because React components must return as a single element (we're using a div in this case). Although, I haven't tested the code but should save and work from your end.