Closed madebyfabian closed 1 year ago
Hey @madebyfabian. Thanks for the report.
This is the default behavior. As per the core-list-item block.json the contents of the list item is the innerHTML
content of the first <li>
selector.
This is how the block editor saves the content of inner lists in the database. It stores a new list under the current list item.
So each list-item html contents will contain the html content
of the inner list components hence you are seeing that result.
For example given the following list:
This is how it is saved in the database:
<!-- wp:list -->
<ul>
<!-- wp:list-item -->
<li>
Example List 1<!-- wp:list -->
<ul>
<!-- wp:list-item -->
<li>Nested List 1</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
<li>
Nested List 2<!-- wp:list -->
<ul>
<!-- wp:list-item -->
<li>Inner Nested List 3</li>
<!-- /wp:list-item -->
</ul>
<!-- /wp:list -->
</li>
<!-- /wp:list-item -->
</ul>
<!-- /wp:list -->
</li>
<!-- /wp:list-item -->
</ul>
<!-- /wp:list -->
So when you query the following CoreList
and CoreListItem
component s you get:
"editorBlocks": [
{
"apiVersion": 2,
"name": "core/list",
"renderedHtml": "\n<ul>\n<li>Example List 1\n<ul>\n<li>Nested List 1</li>\n\n\n\n<li>Nested List 2\n<ul>\n<li>Inner Nested List 3</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n",
"clientId": "64d222aabcdf2",
"parentClientId": null,
"attributes": {
"ordered": false,
"start": null
}
},
{
"apiVersion": 2,
"name": "core/list-item",
"renderedHtml": "\n<li>Example List 1\n<ul>\n<li>Nested List 1</li>\n\n\n\n<li>Nested List 2\n<ul>\n<li>Inner Nested List 3</li>\n</ul>\n</li>\n</ul>\n</li>\n",
"clientId": "64d222aabcdf6",
"parentClientId": "64d222aabcdf2",
"attributes": {
"content": "Example List 1\n<ul>\n<li>Nested List 1</li>\n\n\n\n<li>Nested List 2\n<ul>\n<li>Inner Nested List 3</li>\n</ul>\n</li>\n</ul>\nNested List 1Nested List 2\n<ul>\n<li>Inner Nested List 3</li>\n</ul>\nInner Nested List 3"
}
},
{
"apiVersion": 2,
"name": "core/list",
"renderedHtml": "\n<ul>\n<li>Nested List 1</li>\n\n\n\n<li>Nested List 2\n<ul>\n<li>Inner Nested List 3</li>\n</ul>\n</li>\n</ul>\n",
"clientId": "64d222aabcdf7",
"parentClientId": "64d222aabcdf6",
"attributes": {
"ordered": false,
"start": null
}
},
{
"apiVersion": 2,
"name": "core/list-item",
"renderedHtml": "\n<li>Nested List 1</li>\n",
"clientId": "64d222aabcdf8",
"parentClientId": "64d222aabcdf7",
"attributes": {
"content": "Nested List 1"
}
},
{
"apiVersion": 2,
"name": "core/list-item",
"renderedHtml": "\n<li>Nested List 2\n<ul>\n<li>Inner Nested List 3</li>\n</ul>\n</li>\n",
"clientId": "64d222aabcdf9",
"parentClientId": "64d222aabcdf7",
"attributes": {
"content": "Nested List 2\n<ul>\n<li>Inner Nested List 3</li>\n</ul>\nInner Nested List 3"
}
},
{
"apiVersion": 2,
"name": "core/list",
"renderedHtml": "\n<ul>\n<li>Inner Nested List 3</li>\n</ul>\n",
"clientId": "64d222aabcdfa",
"parentClientId": "64d222aabcdf9",
"attributes": {
"ordered": false,
"start": null
}
},
{
"apiVersion": 2,
"name": "core/list-item",
"renderedHtml": "\n<li>Inner Nested List 3</li>\n",
"clientId": "64d222aabcdfb",
"parentClientId": "64d222aabcdfa",
"attributes": {
"content": "Inner Nested List 3"
}
}
]
},
Since the contents of the first list item <li>
for the Example List 1
is another CoreList
block then the content
will be the innerHTML of it.
<li>
------------------------------------------innerHTML Start
Example List 1\n
<ul>
\n
<li>Nested List 1</li>
\n\n\n\n
<li>
Nested List 2\n
<ul>
\n
<li>Inner Nested List 3</li>
\n
</ul>
\n
</li>
\n
</ul>
\nNested List 1Nested List 2\n
<ul>
\n
<li>Inner Nested List 3</li>
\n
</ul>
\nInner Nested List 3
------------------------------------------innerHTML End
Notice that I've used the clientId
and parentClientId
fields in my query. Since the core/list
and core/list-item
components are hierarchical you can use those parameters to put the whole tree together using:
const blocks = flatListToHierarchical(editorBlocks, {childrenKey: "innerBlocks"});
So each block item will contain an innerBlocks
list of blocks that are considered children blocks and we recursively render them using WordPressBlocksViewer
.
This is how we render for example the CoreColumns
and CoreColumn
Blocks in the @faust/blocks package:
https://github.com/wpengine/faustjs/blob/canary/packages/blocks/src/blocks/CoreColumns.tsx#L30-L39 https://github.com/wpengine/faustjs/blob/canary/packages/blocks/src/blocks/CoreColumn.tsx#L30-L39
Hey @theodesp Thanks for your detailed answer. Sorry for the delay. I was not that deep into wordpress, so I thought it was because of WPGraphQL or this Content Blocks extension. I also already do fetch the client Ids and then create the hierarchy out of it. I just thought maybe it would be more "headless" if the html wasn't included. But if that's how it's stored in the DB, we have to strip it away ourselves I think
I have created the following block structure in the editor for demo:
My GraphQL query:
GraphQL
```graphql query ListPageByUri($uri: ID!) { page(id: $uri, idType: URI) { id title uri editorBlocks(flat: true) { ... on CoreList { name attributes { ordered start } } ... on CoreListItem { name attributes { content } } ... on CoreParagraph { name attributes { content className } } } } } ```Which returns this JSON:
JSON
```json { "data": { "page": { "id": "cG9zdDoxNDA=", "title": "Team", "uri": "/unternehmen/team", "editorBlocks": [ { "name": "core/list", "attributes": { "ordered": false, "start": null } }, { "name": "core/list-item", "attributes": { "content": "Interesting list item" } }, { "name": "core/list-item", "attributes": { "content": "Another one\n\n- Nested ordered
\n\n\n\n- Another nested ordered\n
\n
\nNested orderedAnother nested ordered\n\n- Deeply nested
\n
\n\n- Deeply nested
\n
\nDeeply nested" } }, { "name": "core/list", "attributes": { "ordered": true, "start": null } }, { "name": "core/list-item", "attributes": { "content": "Nested ordered" } }, { "name": "core/list-item", "attributes": { "content": "Another nested ordered\n\n- Deeply nested
\n
\nDeeply nested" } }, { "name": "core/list", "attributes": { "ordered": false, "start": null } }, { "name": "core/list-item", "attributes": { "content": "Deeply nested" } }, { "name": "core/list-item", "attributes": { "content": "The funding" } }, { "name": "core/list", "attributes": { "ordered": true, "start": null } }, { "name": "core/list-item", "attributes": { "content": "Some numbers\n\n- nested
\n
\nnested" } }, { "name": "core/list", "attributes": { "ordered": false, "start": null } }, { "name": "core/list-item", "attributes": { "content": "nested" } }, { "name": "core/list-item", "attributes": { "content": "Again some numbers" } } ] } }, "extensions": { "debug": [ { "type": "DEBUG_LOGS_INACTIVE", "message": "GraphQL Debug logging is not active. To see debug logs, GRAPHQL_DEBUG must be enabled." } ] } } ```As you can see, it returns every nested item as a block, correctly. But on the
attributes.content
field, it includes the HTML for the nested elements.The current workaround is to just strip the HTML off, but I'd consider this more of a bug.
Thanks for creating this plugin, and thanks in advance!