admin管理员组

文章数量:1277362

I am extending a core WP block (core/group), so that it has some added div's enabling me to display the block as I desire on front end.

In addition to the display customization (which is not possible with style properties alone - hence the added markup), the point of my extending the block with this added markup is so that on front end I can do jQuery actions, based on an id I am adding to my container div, as well as create a dynamic navigation menu with anchor links to the blocks based on presence of my extended blocks.

First, let me say up front, everything is already working precisely how I want on front end, and in the block editor, everything seems to be working great, except for one validation issue, which doesn't seem to be a show stopper, but nonetheless, I want to get rid of the validation error.

I am noticing that Wordpress is automatically adding an id to the core/group outer div: <div class="wp-block-group" id="an-exercise-111"></div>. This is causing the validation error, and I can't figure out how to stop it from doing so.

In my code, I don't see anyplace where this id could be getting added.

Here is my code that generates the custom block markup:

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) {
        var post_id = wp.data.select("core/editor").getCurrentPostId();
        var title_slug = attributes.contenttitle.trim().split(/\s+/).join('-');
        var anchorid = title_slug+'-'+attributes.contentid;
        var iconclassbase='contenticon ';
        var iconclass='';
        switch(attributes.contenttype) {
            case 'exercise':
                iconclass =  'fas fa-guitar';
                break;
            case 'concept':
                iconclass = 'fas fa-atom';
                break;
            default:
                iconclass = 'fas fa-atom';
        }
        iconclass = iconclassbase + iconclass;

        return (
            <React.Fragment>
                <div id = {`${anchorid}`} className = {`contenttype-wrapper sometopictype-${attributes.contenttype} navanchor`} data-id = {`${attributes.blockId}`}>
                    <div className = "heading d-flex flex-row">
                        <i className={`${iconclass} fa-7x`}></i>
                        <div className = "col">
                            <div className = "row"><span className="content-name">{attributes.contentname}</span></div>
                            <div className = "row"><h3 className="topictype-title" dangerouslySetInnerHTML={ { __html: attributes.contenttitle } }></h3></div>
                        </div>
                    </div>
                    {element}
                </div>
            </React.Fragment>
        )
    } else {
        return element;
    }
};

addFilter( 'blocks.getSaveElement', 'my-blockmods/add-content-type-markup', addContentTypeMarkup);

Here is the message I get in admin panel, if I view console in Developer Tools:

<div id="an-exercise-111" class="contenttype-wrapper sometopictype-exercise navanchor" data-id="be3d05d6-a048-41c9-8dcf-5fcf121dd4a8"><div class="heading d-flex flex-row"><i class="contenticon fas fa-guitar fa-7x"></i><div class="col"><div class="row"><span class="content-name">Exercise</span></div><div class="row"><h3 class="topictype-title">an exercise</h3></div></div></div><div class="wp-block-group" id="an-exercise-111"></div></div>

Content retrieved from post body:

<div id="an-exercise-111" class="contenttype-wrapper sometopictype-exercise navanchor" data-id="be3d05d6-a048-41c9-8dcf-5fcf121dd4a8"><div class="heading d-flex flex-row"><i class="contenticon fas fa-guitar fa-7x"></i><div class="col"><div class="row"><span class="content-name">Exercise</span></div><div class="row"><h3 class="topictype-title">an exercise</h3></div></div></div><div class="wp-block-group"></div></div>

I see the nature of the problem - Wordpress Block Editor, upon save, is creating this element:

div class="wp-block-group" id="an-exercise-111"></div>

This element, shown above in the markup function simply as {element} contains the content of the block. I don't need it to have an id. Maybe Wordpress requires its blocks to have an id? So it seems the block editor is automatically setting it with an id that is the same as the id I set manually in the block markup function, where I have <div id="an-exercise-111" class="contenttype-wrapper...

Any ideas?

thanks!

NOTE If I don't use the id attribute in my custom div then everything validates. For example, if I use someid then all is fine. But the whole point to me needing to use id is so that anchor links work the way I want. So this gets back to original question - why is WP even adding the id to the div <div class="wp-block-group" id="an-exercise-111">? In block editor, I don't add an id to the core/group block, and in my filter, I don't set that id. Really, this is a mystery. Even if I could do this differently (and I will probably switch to render_block and do server side render), I would still like to understand why WP is doing what it is doing...

I am extending a core WP block (core/group), so that it has some added div's enabling me to display the block as I desire on front end.

In addition to the display customization (which is not possible with style properties alone - hence the added markup), the point of my extending the block with this added markup is so that on front end I can do jQuery actions, based on an id I am adding to my container div, as well as create a dynamic navigation menu with anchor links to the blocks based on presence of my extended blocks.

First, let me say up front, everything is already working precisely how I want on front end, and in the block editor, everything seems to be working great, except for one validation issue, which doesn't seem to be a show stopper, but nonetheless, I want to get rid of the validation error.

I am noticing that Wordpress is automatically adding an id to the core/group outer div: <div class="wp-block-group" id="an-exercise-111"></div>. This is causing the validation error, and I can't figure out how to stop it from doing so.

In my code, I don't see anyplace where this id could be getting added.

Here is my code that generates the custom block markup:

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) {
        var post_id = wp.data.select("core/editor").getCurrentPostId();
        var title_slug = attributes.contenttitle.trim().split(/\s+/).join('-');
        var anchorid = title_slug+'-'+attributes.contentid;
        var iconclassbase='contenticon ';
        var iconclass='';
        switch(attributes.contenttype) {
            case 'exercise':
                iconclass =  'fas fa-guitar';
                break;
            case 'concept':
                iconclass = 'fas fa-atom';
                break;
            default:
                iconclass = 'fas fa-atom';
        }
        iconclass = iconclassbase + iconclass;

        return (
            <React.Fragment>
                <div id = {`${anchorid}`} className = {`contenttype-wrapper sometopictype-${attributes.contenttype} navanchor`} data-id = {`${attributes.blockId}`}>
                    <div className = "heading d-flex flex-row">
                        <i className={`${iconclass} fa-7x`}></i>
                        <div className = "col">
                            <div className = "row"><span className="content-name">{attributes.contentname}</span></div>
                            <div className = "row"><h3 className="topictype-title" dangerouslySetInnerHTML={ { __html: attributes.contenttitle } }></h3></div>
                        </div>
                    </div>
                    {element}
                </div>
            </React.Fragment>
        )
    } else {
        return element;
    }
};

addFilter( 'blocks.getSaveElement', 'my-blockmods/add-content-type-markup', addContentTypeMarkup);

Here is the message I get in admin panel, if I view console in Developer Tools:

<div id="an-exercise-111" class="contenttype-wrapper sometopictype-exercise navanchor" data-id="be3d05d6-a048-41c9-8dcf-5fcf121dd4a8"><div class="heading d-flex flex-row"><i class="contenticon fas fa-guitar fa-7x"></i><div class="col"><div class="row"><span class="content-name">Exercise</span></div><div class="row"><h3 class="topictype-title">an exercise</h3></div></div></div><div class="wp-block-group" id="an-exercise-111"></div></div>

Content retrieved from post body:

<div id="an-exercise-111" class="contenttype-wrapper sometopictype-exercise navanchor" data-id="be3d05d6-a048-41c9-8dcf-5fcf121dd4a8"><div class="heading d-flex flex-row"><i class="contenticon fas fa-guitar fa-7x"></i><div class="col"><div class="row"><span class="content-name">Exercise</span></div><div class="row"><h3 class="topictype-title">an exercise</h3></div></div></div><div class="wp-block-group"></div></div>

I see the nature of the problem - Wordpress Block Editor, upon save, is creating this element:

div class="wp-block-group" id="an-exercise-111"></div>

This element, shown above in the markup function simply as {element} contains the content of the block. I don't need it to have an id. Maybe Wordpress requires its blocks to have an id? So it seems the block editor is automatically setting it with an id that is the same as the id I set manually in the block markup function, where I have <div id="an-exercise-111" class="contenttype-wrapper...

Any ideas?

thanks!

NOTE If I don't use the id attribute in my custom div then everything validates. For example, if I use someid then all is fine. But the whole point to me needing to use id is so that anchor links work the way I want. So this gets back to original question - why is WP even adding the id to the div <div class="wp-block-group" id="an-exercise-111">? In block editor, I don't add an id to the core/group block, and in my filter, I don't set that id. Really, this is a mystery. Even if I could do this differently (and I will probably switch to render_block and do server side render), I would still like to understand why WP is doing what it is doing...

Share Improve this question edited Nov 24, 2021 at 8:30 Brian asked Nov 23, 2021 at 13:27 BrianBrian 3372 silver badges11 bronze badges 8
  • what are you trying to do here that lead you to creating this filter that has this problem? You've asked how to fix your solution rather than how to solve your original problem, and I'm almost certain that you are seeing this because you've built it wrong, not because you just need to remove an extra bit and need to know how. What is it supposed to do if it was working ok? This looks like something that should have been a wrapper block not a filter – Tom J Nowell Commented Nov 23, 2021 at 14:52
  • I am extending core/group block to create in backend, say, an exercise, block, which will have certain formatting. I place them on a custom post. So you can imagine a custom post guitar_lesson and within that post you have exercises, etc. These exercises are not posts - they are just blocks. Upon save_post, I detect these blocks in post_content and update some post meta so that I keep track of these blocks for use in a nav menu. All works great on front end. Just this validation error - no idea how this id is being added. – Brian Commented Nov 23, 2021 at 15:31
  • So your filter is what's adding the navigation menu? I'm trying to figure out how what you described in your comment would lead to the code in your question and I do not see the link. Even if you succeed it will not give you a navigation menu like you hoped as the individual parts will be spread throughout the entire post. Even if it did, this is a very complicated way to achieve that goal. What you're describing is essentially a document outline or table of contents though, there are far easier ways to do that, and they look nothing like the code you've shared – Tom J Nowell Commented Nov 23, 2021 at 19:21
  • Is this filter trying to modify the blocks to add section headings automatically based on a block attribute? If so why aren't those headings a part of the block itself? Or a wrapper block that contains them? That would be the recommended way, not a filter. If you have a "step" then you need to create a step block that contains the other blocks. It should show up that way in the outliner sidebar too, it would greatly simplify your frontend code, eliminate this filter entirely as well as the problem you're asking about. – Tom J Nowell Commented Nov 23, 2021 at 19:29
  • The nav menu I build dynamically via jQuery. It works because of the markup I add to the block: <div id = {${anchorid}} className = {contenttype-wrapper sometopictype-${attributes.contenttype} navanchor} content-id = {${attributes.contentid}} data-id = {${attributes.blockId}}> I suppose I wasn't clear - the block editing is so that I have custom version of a core/group block, whose added markup allows me to do some jQuery actions on front end. Everything is working - I just can't figure out why WP adds to the block {element} the same id I add to my custom div. – Brian Commented Nov 24, 2021 at 8:06
 |  Show 3 more comments

1 Answer 1

Reset to default 1

You don't, rather the approach taken is incorrect, and this particular situation is not fixable.

The group blocks anchor attribute for the ID is stored in the markup itself not the HTML comment, so by introducing an ID at the top level you are changing its value. Once this is done, the output of the save component of the group block changes and that is where your ID is coming from.

Fundamentally, what you're doing is not how it should be done, and this approach is the wrong approach.

Instead, you should use containing blocks and compose your structure. Much in the same way that you can group blocks together in a group block, and give it an ID, you would be better off creating a dedicated block with a title and icon selection that has an ID.

If a container block isn't suitable, a step heading block would also work just as well.

The bonus would be that you could build the navigation trivially in PHP by parsing the blocks, either through parse_blocks then looping through to find these "step" blocks, or by adding a filter to the_content, or even a template function if you wanted to do it that way. Likewise, any question about building outliners for block based content would also be super useful to you.

Likewise a filter similar to what you have right now in PHP could be implemented using the block rendering filters at runtime to achieve this.

本文标签: How to prevent Block Editor from adding id to block markup in save function