0

I'm trying to do a super simple block with two rich text areas - description and custom cta button. The button is saved with SVG inside, everything seems ok, but when I refresh the edited post, it sreams following:

Content generated by `save` function:

<div class="wp-block-avmc-cta"><p class="wp-block-avmc-cta_label">test</p><button class="wp-block-avmc-cta_button button">tlačítko s ikonou&lt;svg xmlns="http://www.w3.org/2000/svg" width="24" height="20" viewBox="0 0 24 20" class="ico ico__envelope button_ico" role="img" aria-hidden="true">&lt;g>&lt;g>&lt;path d="M13.78 10.188l-1.483 1.329a.593.593 0 0 1-.793.004l-1.444-1.29-5.324 4.978a.596.596 0 0 1-.814-.87L9.166 9.43 3.9 4.725a.592.592 0 0 1-.048-.84.593.593 0 0 1 .84-.049l5.698 5.097a.96.96 0 0 1 .097.083c0 .005.005.01.01.014l1.399 1.25 7.177-6.44a.598.598 0 0 1 .841.045.599.599 0 0 1-.043.84l-5.205 4.666 5.226 4.96a.597.597 0 0 1-.41 1.026.595.595 0 0 1-.409-.163l-5.292-5.026zm10.19 7.258v-15.5c0-1.103-.898-2-2.001-2h-20c-1.103 0-2 .897-2 2v15.5c0 1.103.897 2 2 2h20c1.103 0 2-.897 2-2z">&lt;/path>&lt;/g>&lt;/g>&lt;/svg></button></div>

Content retrieved from post body:

<div class="wp-block-avmc-cta"><p class="wp-block-avmc-cta_label">test</p><button class="wp-block-avmc-cta_button button">tlačítko s ikonou<svg xmlns="http://www.w3.org/2000/svg" width="24" height="20" viewbox="0 0 24 20" class="ico ico__envelope button_ico" role="img" aria-hidden="true"><g><g><path d="M13.78 10.188l-1.483 1.329a.593.593 0 0 1-.793.004l-1.444-1.29-5.324 4.978a.596.596 0 0 1-.814-.87L9.166 9.43 3.9 4.725a.592.592 0 0 1-.048-.84.593.593 0 0 1 .84-.049l5.698 5.097a.96.96 0 0 1 .097.083c0 .005.005.01.01.014l1.399 1.25 7.177-6.44a.598.598 0 0 1 .841.045.599.599 0 0 1-.043.84l-5.205 4.666 5.226 4.96a.597.597 0 0 1-.41 1.026.595.595 0 0 1-.409-.163l-5.292-5.026zm10.19 7.258v-15.5c0-1.103-.898-2-2.001-2h-20c-1.103 0-2 .897-2 2v15.5c0 1.103.897 2 2 2h20c1.103 0 2-.897 2-2z"></path></g></g></svg></button></div>

The SVG content gets HTML encoded which should. It drives me nuts, I've tested what I could, what I'm missing?

Here are my attributes:

attributes: {
    label: {
        type: 'string',
        source: 'html',
        selector: 'p',
    },
    button: {
        type: 'text',
        source: 'html',
        selector: 'button',
    }
},

and here is the save function

export default function save({ attributes }) {
const className = getBlockDefaultClassName('avmc/cta'); //https://github.com/WordPress/gutenberg/issues/7308
return <div className={className}>
    <p className={className + "_label"}>{attributes.label}</p>
    <button className={className + "_button button"}>
        {attributes.button}
        <RawHTML>
            <SVG className="ico ico__envelope button_ico" xmlns="http://www.w3.org/2000/svg" width="24" height="20" viewBox="0 0 24 20"><G><G><Path d="M13.78 10.188l-1.483 1.329a.593.593 0 0 1-.793.004l-1.444-1.29-5.324 4.978a.596.596 0 0 1-.814-.87L9.166 9.43 3.9 4.725a.592.592 0 0 1-.048-.84.593.593 0 0 1 .84-.049l5.698 5.097a.96.96 0 0 1 .097.083c0 .005.005.01.01.014l1.399 1.25 7.177-6.44a.598.598 0 0 1 .841.045.599.599 0 0 1-.043.84l-5.205 4.666 5.226 4.96a.597.597 0 0 1-.41 1.026.595.595 0 0 1-.409-.163l-5.292-5.026zm10.19 7.258v-15.5c0-1.103-.898-2-2.001-2h-20c-1.103 0-2 .897-2 2v15.5c0 1.103.897 2 2 2h20c1.103 0 2-.897 2-2z" /></G></G></SVG>
        </RawHTML>
    </button>
</div >;
}

I've tested

  • using <Icon /> element
  • using simple svg inside the save function
  • using <SVG> component
  • wrapping it up in <RawHTML>

Thanks for your help!

I've solved the issue, but a more general and "right" solution is really appreciated, see my answer for details.

2 Answers 2

0

I was playing around with a couple of more hours it and it seems that type "text" is not equal to inner text, it still grabs innerHTML kind of encoded to entities. I've found that out, but forgot to filter it in the save function, which hasn't had an impact on saving (as expected, since the value was from the input field), but for validation yes.

So my workaround without adding any additional HTML element was:

attributes: {
    button: {
        type: 'string',
        source: 'html',
        selector: 'button',
    }
},

And then strip HTML out of the attributes.button value each time when used - in edit function & on the frontend, which did the trick.

// edit.js
<RichText
    tagName="div"
    className={className + "_button button"}
    onChange={(val) => setAttributes({ button: val })}
    value={attributes.button ? attributes.button.replace(/<[^>]*>?/gm, '') : ''}
    placeholder={__('Add button title', 'avmc-mat')}
    allowedFormats={ }
/>

And

// save.js
export default function save({ attributes }) {
const className = getBlockDefaultClassName('avmc/cta'); //https://github.com/WordPress/gutenberg/issues/7308
    return <div className={className}>
        <p className={className + "_label"}>{attributes.label}</p>
        <button className={className + "_button button"}>
            {attributes.button ? attributes.button.replace(/<[^>]*>?/gm, '') : ''}
            <svg className="ico ico__envelope button_ico" xmlns="http://www.w3.org/2000/svg" width="24" height="20" viewBox="0 0 24 20"><g><g><path d="M13.78 10.188l-1.483 1.329a.593.593 0 0 1-.793.004l-1.444-1.29-5.324 4.978a.596.596 0 0 1-.814-.87L9.166 9.43 3.9 4.725a.592.592 0 0 1-.048-.84.593.593 0 0 1 .84-.049l5.698 5.097a.96.96 0 0 1 .097.083c0 .005.005.01.01.014l1.399 1.25 7.177-6.44a.598.598 0 0 1 .841.045.599.599 0 0 1-.043.84l-5.205 4.666 5.226 4.96a.597.597 0 0 1-.41 1.026.595.595 0 0 1-.409-.163l-5.292-5.026zm10.19 7.258v-15.5c0-1.103-.898-2-2.001-2h-20c-1.103 0-2 .897-2 2v15.5c0 1.103.897 2 2 2h20c1.103 0 2-.897 2-2z" /></g></g></svg>
        </button>
    </div >;
}

Hope it will be helpful for someone else´. If there is a "built in" function for that, I it would really appreciate pointing me the right direction!

-1

I think you need thinking about send open and close tag using HTML Entities (&lt;) instead (<)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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