jacksleight / statamic-bard-mutator

This Statamic addon allows you to modify the data and tags rendered by the Bard fieldtype, giving you full control over the final HTML.
https://statamic.com/addons/jacksleight/bard-mutator
MIT License
19 stars 3 forks source link

Move node up one level #24

Closed daun closed 3 months ago

daun commented 3 months ago

Is it possible to move a node up by one level? Haven't seen an example for that in the docs and haven't found an obvious angle yet.

I'm trying to turn this:

<blockquote>
  <p>Lorem ipsum dolor sit amet</p>
  <p>— Publius Vergilius Maro</p>
</blockquote>

Into this:

<figure class="quote">
  <blockquote>
    <p>Lorem ipsum dolor sit amet</p>
  </blockquote>
  <figcaption>
    Publius Vergilius Maro
  </figcaption>
</figure>

I managed to turn the last paragraph into a figcaption, but it's nested under the blockquote, and I'd like to move it up into the figure itself for better semantics.

// Wrap blockquote inside <figure>
Mutator::html('blockquote', function ($value, $data) {
    $inner = array_splice($value, 2, count($value), [0]);
    $value = ['figure', ['class' => 'quote'], $value, ...$inner];
    return $value;
});

// Wrap author on last quote line inside <figcaption>
Mutator::html('paragraph', function ($value, $data, $meta) {
    $isInBlockquote = ($meta['parent']->type ?? null) === 'blockquote';
    if ($isInBlockquote) {
        $isLastChild = !$meta['next'] && $meta['prev'];
        if ($isLastChild) {
            $source = Arr::last($data->content, fn($node) => $node->type === 'text' && Str::startsWith($node->text, ['-', '–', '—']));
            if ($source) {
                $source->text = Str::chopStart($source->text, ['-', '–', '—']);
                $value[0] = 'figcaption';
            }
        }
    }
    return $value;
});
jacksleight commented 3 months ago

Yes, you can use a data mutator to do that, these allow you to modify the raw Prosemirror data before any rendering starts. You can't really do it in an HTML mutator since by the time you get to the child the parent's HTML has already been decided.

daun commented 3 months ago

Fantastic! I somehow thought the data mutators didn't apply here, but I'll give it a go. Thanks 🧃