1

I'm creating a custom block plugin and I've had a bit of trouble getting the class name to appear on a tag output from the save function.

My edit function uses return() and passes in this:

<>
    <div className={className}>
        <RichText
            tagName="a"
            //
            placeholder={__("Add text…", plugin.slug)}
            value={text}
            //
            formattingControls={["bold", "italic", "strikethrough"]}
            //
            onChange={this.onChangeContent}
            //
        />
    </div>
</>

And in my save function I also use return() and have tried passing in a number of variations described below.

Passing RichText.Content directly:

<RichText.Content
    tagName="a"
    value={text}
    className={className}
/>

With or without the className line, it saves <a class="…">Demo Text</a> to the database. This is expect, however, I need to wrap the anchor tag in something else.

Using a wrapper shortcut:

<>
    <RichText.Content
        tagName="a"
        value={text}
        className={className}
    />
</>

Above, I have wrapped the a tag in <> and </> but with or without the className line, the class name isn't populated in the save function. <a>Demo text</a> is always saved to the database.

Using a div:

<div>
    <RichText.Content
        tagName="a"
        value={text}
        className={className}
    />
</div>

Above, I have wrapped the a tag in <div> and </div> but with or without the className line in the RichText tag, the class name is only ever populated in the div tag when saving tot the database. <div class="…"><a>Demo Text</a></div> is always saved to the database.

The same thing happens when I switch from an a tag to a p tag.

  • Is there a way to get the className to populate tags wrapped in other tags?
  • Or does anyone have a link to more information about how className works?

Thankyou! Dale.

3
  • Where is className coming from? It may help to include the entire function being passed to the edit property. – Welcher May 29 '20 at 19:42
  • 1
    className is a default attribute from the components props. ie. const { attributes } = this.props; const { className } = attributes; – Dale de Silva Jun 4 '20 at 12:24
  • 1
    While I can't find this documented anywhere, I've since concluded that when using the save function, the className is placed on the root node by default (and probably by design). I"m not sure why it won't let me force it to also be placed in child nodes, but I'm no longer worried because I realised that using the className on the root node and relying on other selectors to find child nodes within that probably creates better CSS patterns anyway. But it sure would be nice if this was explained in the docs! – Dale de Silva Jun 4 '20 at 12:25
0

I was trying to figure this out all afternoon as well and figured out as well that the className is passed along by default in the save function for the root of certain elements.

e.g. in the following code example where className is warning

return (
<div className="other-class-name" value={ props.attributes.content } />;

will return an element on the front end of

<div class="wp-block-block-name is-warning other-class-name">

https://developer.wordpress.org/block-editor/developers/block-api/block-registration/#supports-optional has some more information

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.