create a custom editable block that really works
-
Hello
I’m really not able to add an editable custom block. I’ve read a lot of tutorials and used some boilerplate plug-ins. But no one is working.
I would like to create a custom editable block, with the editable parameters on the right sidebar. I’m struggling a lot, but I’m not able to see the right sidebar working.
If I look at the documentation at https://ww.wp.xz.cn/gutenberg/handbook/blocks/block-controls-toolbars-and-inspector/ I see an example for Toolbars but no examples for the Inspector. Is it possible to have a working simple example including a couple of parameters editable on the right sidebar? Checking in the Gutenberg plug-in is too much, I’m sure it could be possible to provide a more simple example that works. Thank you in advance
-
Hi,
The edit function returns a description of your block.
– Everything wrapped in a InspectorControls component will appear on the right sidebar.
– Everything wrapped in a BlockControls component will appear in the block-toolbar on top of the block. Well, components have to be ‘kind of special’ to fit in there.
– Everything else will appear inside the block.An example block:
/** * WordPress dependencies */ const { __ } = wp.i18n; const { registerBlockType } = wp.blocks; const { ColorPalette, PanelBody } = wp.components; const { RichText, InspectorControls, BlockControls, AlignmentToolbar } = wp.editor; registerBlockType( 'tstg/my-block', { title: __( 'My Block' ), category: 'common', // [ common | formatting | layout | widgets | embed ] attributes: { content: { type: 'array', source: 'children', selector: 'p', }, color: { type: 'string', // default: '#000000', }, alignment: { type: 'string', // default: 'left', }, }, edit( { attributes, setAttributes } ) { const { content, color, alignment } = attributes; // let's return an array of components return ([ /* RichText component as example with style property */ <RichText tagName='p' placeholder={__('Example RichText Component ... is empty')} value={ content } style={{color, textAlign: alignment}} onChange={ ( content ) => setAttributes({content}) } />, /* Everything wrapped in an InspectorControls component will appear in the right sidebar and not within the block. */ <InspectorControls> {/* ColorPalette wrapped in a PanelBody. onChange: set the color attribute */} <PanelBody title={__('Font Color')}> <ColorPalette value={ color } onChange={ (newHex) => setAttributes({color:newHex}) } /> </PanelBody> </InspectorControls>, /* This is exactly same like above, but not wrapped in an InspectorControls components. So it will just appear inside the block. */ <PanelBody title={__('Font Color')}> <ColorPalette value={ color } onChange={ (newHex) => setAttributes({color:newHex}) } /> </PanelBody>, /* Everything wrapped in an BlockControls component will appear in the block-toolbar on top of the block */ <BlockControls key="controls"> {/* AlignmentToolbar component see https://ww.wp.xz.cn/gutenberg/handbook/blocks/block-controls-toolbars-and-inspector/#toolbar */} <AlignmentToolbar value={ alignment } onChange={ (newAlignment) => setAttributes({alignment: newAlignment}) } /> {/* // Well, you could have the ColorPalette component in your toolbar as well // it works, but breaks the style <ColorPalette value={ color } onChange={ (newHex) => setAttributes({color:newHex}) } /> */} </BlockControls>, ]); }, save( { attributes } ) { const { content, color, alignment } = attributes; return ( <RichText.Content style={{color, textAlign: alignment}} tagName='p' value={ content } /> ); } });Does that answer your question?
Really thanks for your answer!
In the console I get this error: Uncaught SyntaxError: Unexpected token <
It’s related to the line where you have <RichText
The script where I’ve written the example you have provided, is enqueued after the following core scripts:
‘wp-blocks’, ‘wp-i18n’, ‘wp-element’,’wp-components’,’underscore’Should I enqueue additional core scripts? Or should I compile something?
Thank you very much in advance
Hi,
mmmmm, I don’t get that error.WordPress v4.9.7
Gutenberg v3.3.0I enqueue the script with this dependencies: ‘wp-blocks’, ‘wp-i18n’, ‘wp-element’
And hooked into: ‘enqueue_block_editor_assets’I use following class to register the ‘My Block’ and enqueue the scripts/styles.
Looks little different to most examples, hope it’s not to confusing. But it’s same same, just wrapped in a class.
The public function enqueue_editor_assets in line 122, enqueues assets for the editor.<?php // If this file is called directly, abort. if ( ! defined( 'WPINC' ) ) { die; } class Tstg_Block_My_block { protected static $instance = null; protected $namspace = 'tstg/my-block'; protected $handles = array( 'editor' => 'tstg_block_my_block_editor', 'frontend' => 'tstg_block_my_block_frontend', ); public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); self::$instance->hooks(); } return self::$instance; } protected function __construct() { // ... silence } public function hooks() { add_action( 'init', array( $this, 'register_block' ) ); add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_editor_assets' ) ); add_action( 'enqueue_block_assets', array( $this, 'enqueue_frontend_assets' ) ); } public function register_block() { if ( function_exists( 'register_block_type' ) ) { register_block_type( $this->namspace, array( 'editor_script' => $this->get_handle( 'editor' ), 'editor_style' => $this->get_handle( 'editor' ), // 'style' => 'tstg_block_my_block', // dont set a style here. use hook instead and check if post_has_block // 'script' => 'tstg_block_my_block', // dont set a style here. use hook instead and check if post_has_block 'render_callback' => array( $this, 'render' ), ) ); } } protected function get_handle( $key ){ $handles = $this->handles; if ( array_key_exists( $key, $handles ) ){ return $handles[$key]; } } protected function post_has_block(){ global $post; if ( strlen( $post->post_content ) === 0 ) return false; $block_pattern = ( '/<!--\s+wp:(' . str_replace( '/', '\/', // Escape namespace, not handled by preg_quote. preg_quote( $this->namspace ) ) . ')(\s+(\{.*?\}))?\s+(\/)?-->/' ); return preg_match( $block_pattern, $post->post_content, $block_matches ) === 1; } protected function get_localize_data(){ // global $post; // $current_user = wp_get_current_user(); // return array( // 'pluginDirUrl' => Tstg_Testing::plugin_dir_url(), // 'user' => array( // 'id' => $current_user->ID, // ), // 'post' => array( // 'id' => $post->ID, // ) // ); return array(); } // hooked on enqueue_block_assets. So function will run in admin and frontend. // But we will use it only on frontend if the post has this block public function enqueue_frontend_assets() { // check if we are on frontend and the post has a block // ... Might be a bad way in future wp versions. Nowadays works well, Let's see. if ( is_admin() || ! $this->post_has_block() ) return; $handle = $this->get_handle( 'frontend' ); wp_enqueue_style( $handle, Tstg_Testing::plugin_dir_url() . '/css/' . $handle . '.min.css', array( 'wp-blocks' ), filemtime( Tstg_Testing::plugin_dir_path() . 'css/' . $handle . '.min.css' ) ); wp_register_script( $handle, Tstg_Testing::plugin_dir_url() . '/js/' . $handle . '.min.js', array( // 'wp-backbone', // 'wp-api', // 'utils', ), filemtime( Tstg_Testing::plugin_dir_path() . 'js/' . $handle . '.min.js' ) ); wp_localize_script( $handle, 'tstgData', $this->get_localize_data() ); wp_enqueue_script( $handle ); } // hooked on enqueue_block_editor_assets. So function will only run in admin public function enqueue_editor_assets() { $handle = $this->get_handle( 'editor' ); wp_register_script( $handle, Tstg_Testing::plugin_dir_url() . '/js/' . $handle . '.min.js', array( 'wp-blocks', 'wp-i18n', 'wp-element', ), filemtime( Tstg_Testing::plugin_dir_path() . 'js/' . $handle . '.min.js' ) ); wp_localize_script( $handle, 'tstgData', $this->get_localize_data() ); wp_enqueue_script( $handle ); wp_enqueue_style( $handle, Tstg_Testing::plugin_dir_url() . '/css/' . $handle . '.min.css', array( 'wp-edit-blocks' ), filemtime( Tstg_Testing::plugin_dir_path() . 'css/' . $handle . '.min.css' ) ); } } function tstg_block_my_block_init() { return Tstg_Block_My_block::get_instance(); } tstg_block_my_block_init(); ?>
The topic ‘create a custom editable block that really works’ is closed to new replies.