Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions php-transformer/src/HtmlToBlocks/HtmlTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -10190,6 +10190,14 @@ private function namePriceRowBlockFromElement(DOMElement $element, array &$fallb
return null;
}

// core/columns is a flex layout; WordPress rejects it with is-layout-grid.
// Decline when the resolved layout is grid so the container demotes to
// core/group, where grid layout is native.
$layout = $this->presentationAttributes($element)['layout'] ?? null;
if ( is_array($layout) && 'grid' === (string) ($layout['type'] ?? '') ) {
return null;
}

$rowFallbacks = array();
$columns = array();
foreach ( $children as $child ) {
Expand Down
11 changes: 11 additions & 0 deletions php-transformer/src/HtmlToBlocks/Patterns/ColumnsPattern.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ public function match(
return null;
}

// core/columns is a flex layout; WordPress rejects it with is-layout-grid.
// The layout resolver stamps layout:{type:grid} from signals this
// recognizer's style-based grid bail cannot see (grid-ish class names,
// class-resolved display:grid), so a would-be columns container whose
// layout resolves to grid must decline here and demote to core/group,
// where grid layout is native.
$layout = ( $presentationAttributes($element) )['layout'] ?? null;
if ( is_array($layout) && 'grid' === (string) ($layout['type'] ?? '') ) {
return null;
}

$elementChildren = array();
foreach ( $element->childNodes as $child ) {
if ( XML_TEXT_NODE === $child->nodeType && '' === trim($child->textContent ?? '') ) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"schema": "blocks-engine/php-transformer/parity-fixture/v1",
"name": "html-split-layout-grid-class-demotes-to-group",
"description": "A two-child container whose class name trips both the split-layout columns heuristic (hero-grid) and the explicit grid class signal must become a core/group with grid layout, never core/columns. core/columns is a flex layout: pairing it with layout:{type:grid} serializes the wp-block-columns + is-layout-grid combo WordPress rejects.",
"source_reference": {
"repo": "php-transformer",
"path": "tests/fixtures/parity/html-split-layout-grid-class-demotes-to-group.json",
"notes": "Derived from a bakery hero where .hero-grid { display:grid } held exactly two panes (copy + plate figure); the split-layout heuristic claimed it as columns while the grid class name stamped is-layout-grid, producing an invalid block."
},
"legacy_comparison": {
"skip": true,
"reason": "This upstream primitive fixture has no downstream legacy comparison."
},
"operation": "html_transformer.transform",
"input": {
"content": "<div class=\"hero-grid\"><div class=\"hero-text\"><h1>Fresh Bread Daily</h1><p>Baked every morning.</p></div><figure class=\"hero-plate\"><img src=\"https://example.com/bread.jpg\" alt=\"Bread\"/></figure></div>"
},
"expected_blocks": [
{ "path": "blocks.0", "name": "core/group", "attrs": { "className": "hero-grid", "layout": { "type": "grid" } } }
],
"expected_fallbacks": [],
"expect": [
{ "path": "status", "assert": "equals", "value": "success" },
{ "path": "fallbacks", "assert": "count", "count": 0 },
{ "path": "blocks", "assert": "count", "count": 1 },
{ "path": "blocks.0.innerBlocks", "assert": "count", "count": 2 },
{ "path": "serialized_blocks", "assert": "contains", "value": "<div class=\"wp-block-group is-layout-grid wp-block-group-is-layout-grid hero-grid\">" },
{ "path": "serialized_blocks", "assert": "contains", "value": "<!-- wp:heading {\"content\":\"Fresh Bread Daily\",\"level\":1} -->" },
{ "path": "serialized_blocks", "assert": "not_contains", "value": "wp:columns" },
{ "path": "serialized_blocks", "assert": "not_contains", "value": "wp-block-columns" }
]
}
Loading