editor
editor copied to clipboard
Feature: Wrapping Blocks
This is really a tricky request:
The editor's block model is really powerful and will allow us to move away from complex subpage setups to handle modular content. And while adding blocks is easy, layout often requires additional wrappers (e. g. a div
with a specific class).
I'm actually not sure if this is something for the editor to solve or if this is something that needs to be applied to the resulting markup in a separate step but wrapping blocks would be a needed feature.
Example: a page with an interview, imagine two custom blocks, one for questions, one for answers. In the frontend output, we'd like to wrap all answer blocks until the next question (or the end of the content) in a div
with the classanswer
.
I thought about adding a general block settings dialog to all blocks, which could contain a CSS class setting. Then you have full control over the final markup.
I thought about adding a general block settings dialog to all blocks, which could contain a CSS class setting. Then you have full control over the final markup.
I think this is more what #28 requested. I was really thinking about wrapping multiple blocks in a div
or a section
or an article
. These kind of wrappers can be necessary for advanced grid layouts. And after thinking about it, it might not be difficult at all to achieve this. What I am thinking about is something like this:
$page->text()->blocks()->wrap('paragraph', 'heading1', 'div', ['class' => 'example'])->html();
The method's arguments being $from
, $until
, $element
, $attributes
– the latter two being optional. It would turn these blocks …
[
{
"attrs": [],
"content": "My text",
"id": "_9obatb19c",
"type": "paragraph"
},
{
"attrs": [],
"content": "My list",
"id": "_5bbcu4ini",
"type": "ul"
},
{
"attrs": [],
"content": "My heading",
"id": "_o1vzjnx96",
"type": "h1"
}
]
… into:
<div class="example">
<p>My text</p>
<ul>
<li>My list</li>
</ul>
</div>
<h1>My heading</h1>
The wrap method would have to programmatically add "virtual blocks" to the editor collection. Pseudo code:
function wrap($from, $until, $element = 'div', $attributes = []) {
while($block) {
$isOpen = false;
if ($block->type() === $from && !$isOpen) {
$block->prepend({
attrs => [
'element' => $element,
'attributes' => $attributes
],
content => null,
id => "something",
type => "wrapstart"
});
$isOpen = true;
}
if ($block->type() === $until && $isOpen) {
$block->prepend({
attrs => [
'element' => $element,
],
content => null,
id => "something",
type => "wrapend"
});
$isOpen = false;
}
}
}
With these blocks added virtually, the output could be generated using snippets for the opening and closing tag (using the defined attr
):
editor/wrapstart.php
<<?=$attr['element']?>
<?php foreach($attr['attributes'] as $name => $value) ?> <?=$name?>="<?=$value?>"<?php endforeach>
>
editor/wrapend.php
</<?=$attr['element']?>>
Does that make sense?