1
votes

I'm using the filter blocks.getSaveElement to wrap built-in blocks in a bootstrap container. This works for almost everything except the Paragraph block when that blocks contains a <br> (by using SHIFT+ENTER)

If there are no line breaks within the paragraph everything compiles and renders as expected.

If there are lines breaks, then an abnormal closing quote is used for the content attribute on the element and all subsequent quotes are the non-standard quote for that element.

What causes this?

Filter to add the wrapping elements:

wp.hooks.addFilter('blocks.getSaveElement', 'themes/wisnet/bs-core-blocks', function (element, blockType, attributes) {

    // add the defaults to the attributes if they do not exist
    const defaults = getBlockConfig(blockType.name).attributes;
    for (let key in defaults) {
        if (defaults.hasOwnProperty(key) && typeof attributes[key] === 'undefined') {
            attributes[key] = defaults[key].default;
        }
    }

    if (isValidBlockType(blockType.name) && wp.element.isValidElement(element)) {
        const col = wp.element.createElement('div', assign({
            'class': ['col', (attributes.columns > 0 ? 'col-sm-' + attributes.columns : '')].join(' ')
        }, {}), element);
        const row = wp.element.createElement('div', assign({
            'class': ['row', attributes.equal_height_columns, attributes.alignment_vertical, attributes.alignment_horizontal].join(' ')
        }, {}), col);
        element = wp.element.createElement('div', assign({
            'class': ['wp-block-wrapper', attributes.gutters, (
                typeof element.props.className === 'string' && element.props.className.match(/(^|\s+)wp-block-/) ?
                    element.props.className.replace(/wp-block-/, 'wp-block-wrapper-') :
                    'wp-block-wrapper-' + blockType.name.replace(/\//, '-').replace(/^core-/, '')
            ), attributes.container].join(' '),
            'data-type': blockType.name
        }, attributes), row);

        console.log({element, attributes, row, col});
    }


    return element;
}, 999);

Sample of a good paragraph (no line breaks)

<div class="wp-block-wrapper md-gutters wp-block-wrapper-paragraph container" data-type="core/paragraph" content="This one is good!" container="container" equal_height_columns="" gutters="md-gutters" alignment_horizontal="justify-content-start" alignment_vertical="align-items-start" fluid_items="true" columns="0" items_break_point="col-sm">
    <div class="row  align-items-start justify-content-start">
        <div class="col ">
            <p container="container" equal_height_columns="" gutters="md-gutters" alignment_horizontal="justify-content-start" alignment_vertical="align-items-start" fluid_items="true" items_break_point="col-sm">This one is good!</p>
        </div>
    </div>
</div>

Sample of a BAD paragraph (line break)

<div class="wp-block-wrapper md-gutters wp-block-wrapper-paragraph container" data-type="core/paragraph" content="This one<br>is bad.” container=”container” equal_height_columns=”” gutters=”md-gutters” alignment_horizontal=”justify-content-start” alignment_vertical=”align-items-start” fluid_items=”true” columns=”0″ items_break_point=”col-sm”>
<div class=" row="" align-items-start="" justify-content-start"="">
<div class="col ">
    <p container="container" equal_height_columns="" gutters="md-gutters" alignment_horizontal="justify-content-start" alignment_vertical="align-items-start" fluid_items="true" items_break_point="col-sm">This one<br>is bad.</p>
</div>
</div>
2
where is the html coming from? browser dev tools? please check the sourcecode html and paste it here. sometimes they differ, as browsers try to reformat html with errors. - niklas
Good call niklas. So the source is fine. I think the issue then is that it is not encode and it's just straight HTML in the attribute value (his one<br>is bad.). Thanks! - Michael
I will recommend you to use the ES6 syntax as it will make your code a lot easier. For ES6 whenever you see any code in WordPress docs then you can choose ESNEXT tab from top of snippet that will then shows you ES6 code. - Mehmood Ahmad

2 Answers

1
votes

As @niklas pointed out in the comment, the curly quote was coming from the browser trying to reformat and was not in the source code.

The real issue is the element not encoding the HTML in the content attribute. So to take care of this I needed to encode that value myself which converts the html to This one&lt;br&gt;is bad.:

let content = (() => {
    let elt = document.createElement('span');
    elt.textContent = element.props.content;
    return elt.innerHTML;
})();

element.props.content = content
0
votes

The error most probably comes from the first line of the "BAD paragraph". It says:

content="This one<br>is bad.”

At least this is where the " becomes . It seems you got way too many attributes in your html output. When I inspect my block editor html or frontend html there are no content equal_height_columns ... attributes ever. I did not read your code toooo closely but it seems you are writing all block attributes to html attributes. This is probably not what you should do.