0

I'm making an editable button for gutenberg editor. I wrote below code, but it doesn't allow me to edit a text in a button. Does anybody know what's wrong? Thank you in advance.

themedir/custom-block/block.js

var el = window.wp.element.createElement;
var RichText = window.wp.blockEditor.RichText;

wp.blocks.registerBlockType( 
  'custom-namespace/button',
  {
    title: 'nice_button',
    icon: 'button',
    category: 'layout',
    example: {},
    attributes: {
      text: {
        type: 'string',
        default: '',
        source: 'html',
        selector: 'button'
      },
    },
    edit: function (props) {
      var blockProps = wp.blockEditor.useBlockProps();
      return el(
        RichText, Object.assign(blockProps, {
          onChange: function(text) {
            props.setAttributes({text: text})
          },
          value: props.attributes.text,
          placeholder: 'Input your text',
          tagName: 'button',
          className: props.className,
        })
      );
    },
    save: function (props) {
      var blockProps = wp.blockEditor.useBlockProps.save();
      return el(
        RichText.Content,
        Object.assign(blockProps, {
          value: props.attributes.text,
          tagName: 'button',
        })
      );
    },
  }
);

Edited: Changed name space so that it doesn't contain an underscore. The below file loads block.js

themedir/custom-block/register-block.php

<?php
defined('ABSPATH') || exit;

function custom_gutenberg_block_enqueue() {
  wp_register_script(
    'block-script',
    get_theme_file_uri('/custom-block/block.js'),
    array('wp-block-editor', 'wp-element'),
    filemtime(get_theme_file_path('/custom-block/block.js'))
  );

  wp_register_style(
    'block-editor',
    get_theme_file_uri('/custom-block/editor.css'),
    array('wp-edit-blocks'),
    filemtime(get_theme_file_path('/custom-block/editor.css'))
  );

  wp_register_style(
    'block-front',
    get_theme_file_uri('/custom-block/front.css'),
    array(),
    filemtime(get_theme_file_path('/custom-block/front.css'))
  );

  register_block_type(
    'custom-namespace/button',
    array(
      'editor_script' => 'block-script',
      'editor_style' => 'block-editor',
      'style' => 'block-front',
    )
  );
}
add_action('init', 'custom_gutenberg_block_enqueue');
6
  • The only obvious issue I noticed in your code is the block name which should not use a _ (underscore) and it should be replaced with a - (dash), i.e. custom-namespace/button. The rest should be fine, as long as the script is loaded properly with all the required dependencies like wp-block-editor. How are you loading the script and is that the actual and entire code in your file?
    – Sally CJ
    Jan 20, 2022 at 7:16
  • "it doesn't allow me to edit a text in a button" - does that happen immediately after you added the block to your post, or only after the post is saved (i.e. after a page reload)? Have you checked the browser's console? Is there any errors relevant to your block type - if so, what's the complete error message?
    – Sally CJ
    Jan 20, 2022 at 7:22
  • Thank you for your comment. A name space in my real file doesn't contain an underscore, so I updated my code. Also, I added a loading php code. When I put a block, I can't input any single character into a box. When I click a button to edit, it just behaves like "onClick" is called, so I can't edit a text.
    – Watanabe.N
    Jan 20, 2022 at 7:32
  • 1
    Thank you so much. It partially fixed. When I add a button, I can edit a text. Once I move a focus away, I can't edit without a closure! I didn't know this behavior. Thank you for helping me out. If you post an answer, I'll accept it.
    – Watanabe.N
    Jan 20, 2022 at 8:33
  • 1
    @SallyCJ I'm happy if you have a chance to take a look at wordpress.stackexchange.com/questions/401555/…
    – Watanabe.N
    Jan 21, 2022 at 4:24

1 Answer 1

1

As I said in my comment, your code worked fine for me.

But that's probably because I used the default Twenty Twenty-One theme on a test site running the default WordPress setup (basically, almost no plugins).

And the reason I asked you, "is that the actual and entire code in your file", is because the el and RichText variables in your block.js file are in the global scope (just like the wp object which can be accessed using just "wp" as in wp.blocks as well as window.wp as in window.wp.element), and thus the issue in question happened most likely because one of your variables may have "lost" its original definition which could happen because variables in the global scope can easily be overwritten by other scripts, be they in a plugin or theme, just as with global variables in PHP.

For example, you defined the el like so: var el = window.wp.element.createElement; which is equivalent to doing window.el = window.wp.element.createElement;. Now if a plugin later on redefined the variable in the global scope, e.g. var el = 'foo bar'; or maybe window.el = 'foo bar';, then your edit() and save() functions would be in trouble :) (because the el is no longer a function).

So to prevent such issues from happening, scope your code, e.g. using Immediately-Invoked Function Expression (or IIFE for short), like so:

( ( function () { // <- 1. Add this line
    var el = window.wp.element.createElement;
    var RichText = window.wp.blockEditor.RichText;

    wp.blocks.registerBlockType( ... your code );
} )(); // <- 2. Add this line

And BTW, if you're not already doing so, you should consider developing using ES6/ESNext and JSX, and then follow the JavaScript build setup in the block editor handbook for details on how to transform your ES6+JSX code to "normal" JavaScript (that can be understood by most browsers).

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .