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>
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<br>is bad.
:
let content = (() => {
let elt = document.createElement('span');
elt.textContent = element.props.content;
return elt.innerHTML;
})();
element.props.content = content