Last active
June 21, 2019 07:52
-
-
Save desaiuditd/c6ef602b86afa8f22034ab043766517f to your computer and use it in GitHub Desktop.
Dynamic Template in InnerBlocks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { Component, Fragment } = wp.element; | |
// This is going to add block controls to switch the state between preview and search. | |
import ItemControls from './controls'; | |
// Preview is going to show users how items are going to look like. | |
import Preview from './preview'; | |
// Search is allowing to search for items. | |
import Search from './search'; | |
/** | |
* The Edit Component for the Block. | |
* | |
* @export | |
* @class | |
* @extends {Component} | |
*/ | |
export default class extends Component { | |
/** | |
* The 2 states in which the Edit component works. | |
* - Search: Autocomplete functionality to allow users to search for items. | |
* - Preview: Allow users to preview the item and see how it's going to look like. | |
*/ | |
editStates = { | |
preview: Preview, | |
search: Search | |
}; | |
constructor() { | |
super( ...arguments ); | |
const { attributes } = this.props; | |
const { id: itemId = false } = attributes; | |
let itemDetails = null; | |
let editState = 'search'; | |
// Decide whether to show the preview state for the existing item or the search state to add new item. Just check for the ID. | |
if ( itemId ) { | |
itemDetails = { ...attributes }; | |
try { | |
itemDetails.featuredImages = JSON.parse( itemDetails.featuredImages ); | |
} catch ( e ) { | |
itemDetails.featuredImages = {}; | |
console.log( 'Error in parsing the featured images.' ); | |
} | |
editState = 'preview'; | |
} | |
this.state = { editState, itemDetails }; | |
} | |
/** | |
* Change the edit state of the Edit component. | |
* | |
* @param {String} editState The edit state to be changed to. | |
*/ | |
switchEditState = editState => this.setState( { editState } ); | |
/** | |
* Set the asset information to preview for the block. | |
* | |
* @param {Object} itemDetails The asset details for the story (id, heading, intro, featuredImage etc.) | |
*/ | |
setItemDetails = itemDetails => this.setState( { itemDetails } ); | |
/** | |
* Update the block attributes required to save the item. | |
* | |
* @param {Object} prevItem Previous values of item. | |
* @param {Object} curItem New values of item. | |
* @returns {null} | |
*/ | |
updateBlockAttributes( prevItem, curItem ) { | |
// Bail, if the item is not changed. | |
if ( prevItem === curItem ) { | |
return; | |
} | |
const { id, heading, intro, featuredImages } = curItem; | |
this.props.setAttributes( { id, heading, intro, featuredImages: JSON.stringify( featuredImages ) } ); | |
} | |
/** | |
* Perform tasks whenever the Component is updated (i.e., either the state or the props are updated) | |
* | |
* @param {Object} prevProps Previous values for props. | |
* @param {Object} prevState Previous values for state. | |
*/ | |
componentDidUpdate( prevProps, prevState ) { | |
const { itemDetails: prevItem } = prevState; | |
const { itemDetails: curItem } = this.state; | |
// Save attributes. | |
this.updateBlockAttributes( prevItem, curItem ); | |
} | |
render() { | |
const { editState, itemDetails } = this.state; | |
const StateView = this.editStates[ editState ]; | |
return ( | |
<Fragment> | |
<ItemControls | |
editState={ editState } | |
itemDetails={ itemDetails } | |
switchEditState={ this.switchEditState } /> | |
<StateView | |
itemDetails={ itemDetails } | |
setItemDetails={ this.setItemDetails } | |
switchEditState={ this.switchEditState } /> | |
</Fragment> | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'my-custom-block.css'; | |
const { registerBlockType } = wp.blocks; | |
const { __ } = wp.i18n; | |
import edit from './edit'; | |
/** | |
* Register my custom block. | |
*/ | |
registerBlockType( 'mcb/block', { | |
title: __( 'My Custom Block' ), | |
description: __( 'Performing amazing stuff.' ), | |
icon: 'welcome-add-page', | |
category: 'common', | |
/** | |
* Attributes required. | |
*/ | |
attributes: { | |
id: { type: 'string' }, | |
heading: { type: 'string' }, | |
intro: { type: 'string' }, | |
featuredImages: { type: 'string' } | |
}, | |
/** | |
* The edit component. | |
*/ | |
edit, | |
/** | |
* The save component. | |
*/ | |
save: props => ( <InnerBlocks.Content /> ) | |
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { | |
blockEditor: { InnerBlocks }, | |
i18n: { __, sprintf } | |
} = wp; | |
const { getImageURL } = ffx.imageUtils; | |
/** | |
* The Preview component for the item. | |
* Responsible for showing how the item is going to look like. | |
* | |
* @export | |
* @class | |
* @extends {Component} | |
*/ | |
export default ( { itemDetails: { id, heading, intro, featuredImages }} ) => { | |
const imgData = featuredImages[0] || {}; | |
const { | |
alt, | |
caption = '', | |
id, | |
url | |
} = imgData; | |
const template = [ | |
[ | |
'core/image', | |
{ alt, caption, id, url } | |
], | |
[ | |
'core/heading', | |
{ | |
content: heading, | |
placeholder: ! heading ? sprintf( __( 'There\'s no heading for this item. ID - %s' ), id ) : undefined | |
} | |
], | |
[ | |
'core/paragraph', | |
{ | |
content: intro, | |
placeholder: ! intro ? sprintf( __( 'There\'s no Intro for this item. ID - %s' ), id ) : undefined | |
} | |
] | |
]; | |
const ALLOWED_BLOCKS = [ 'core/paragraph' ]; | |
return ( | |
<div className="ink-blocks-asset-preview"> | |
<InnerBlocks template={ template } allowedBlocks={ ALLOWED_BLOCKS } /> | |
</div> | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment