Skip to content

Commit

Permalink
Bard Transformer: Recursively map Prosemirror nodes in order to handl…
Browse files Browse the repository at this point in the history
…e deeply nested images (#85)

* Add support for recursively walking through the Prosemirror content to perform asset transformation. Add appropriate test.

* Resolve code lint syntax issues found.

* Make the example in the test more like the example in the GitHub issue

* Rename the method and simplify.

* Make it more readable

---------

Co-authored-by: Duncan McClean <[email protected]>
  • Loading branch information
tdondich and duncanmcclean authored Jan 29, 2025
1 parent 2e0a635 commit e41a14d
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 26 deletions.
62 changes: 36 additions & 26 deletions src/Transformers/BardTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,32 +35,7 @@ public function transform(string $value): array
$value = (new BardAugmentor($this->field->fieldtype()))->renderHtmlToProsemirror($value)['content'];

$value = collect($value)
->map(function (array $node): ?array {
if ($node['type'] === 'image' && $this->field->get('container') && isset($this->config['assets_base_url'])) {
$assetContainer = AssetContainer::find($this->field->get('container'));

$transformer = new AssetsTransformer(
field: new Field('image', ['container' => $assetContainer->handle(), 'max_files' => 1]),
config: [
'related_field' => 'url',
'base_url' => $this->config['assets_base_url'] ?? null,
'download_when_missing' => $this->config['assets_download_when_missing'] ?? false,
'folder' => $this->config['assets_folder'] ?? null,
'process_downloaded_images' => $this->config['assets_process_downloaded_images'] ?? false,
]
);

$asset = $assetContainer->asset(path: $transformer->transform($node['attrs']['src']));

if (! $asset) {
return null;
}

$node['attrs']['src'] = $asset->id();
}

return $node;
})
->map(fn ($child) => $this->mapProsemirrorNodes($child))
->filter()
->all();

Expand All @@ -69,6 +44,41 @@ public function transform(string $value): array
return $value;
}

private function mapProsemirrorNodes(array $node): ?array
{
if ($node['type'] === 'image' && $this->field->get('container') && isset($this->config['assets_base_url'])) {
$assetContainer = AssetContainer::find($this->field->get('container'));

$transformer = new AssetsTransformer(
field: new Field('image', ['container' => $assetContainer->handle(), 'max_files' => 1]),
config: [
'related_field' => 'url',
'base_url' => $this->config['assets_base_url'] ?? null,
'download_when_missing' => $this->config['assets_download_when_missing'] ?? false,
'folder' => $this->config['assets_folder'] ?? null,
'process_downloaded_images' => $this->config['assets_process_downloaded_images'] ?? false,
]
);

$asset = $assetContainer->asset(path: $transformer->transform($node['attrs']['src']));

if (! $asset) {
return null;
}

$node['attrs']['src'] = $asset->id();
}

if (isset($node['content'])) {
$node['content'] = collect($node['content'])
->map(fn ($child) => $this->mapProsemirrorNodes($child))
->filter()
->all();
}

return $node;
}

private function enableBardButtons(array $value): void
{
$config = $this->field->config();
Expand Down
45 changes: 45 additions & 0 deletions tests/Transformers/BardTransformerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,51 @@ public function it_handles_images()
], $output);
}

#[Test]
public function it_handles_nested_images()
{
AssetContainer::make('assets')->disk('public')->save();
Storage::disk('public')->put('2024/10/image.png', 'original');

$transformer = new BardTransformer(
import: $this->import,
blueprint: $this->blueprint,
field: $this->field,
config: [
'assets_base_url' => 'https://example.com/wp-content/uploads',
]
);

$output = $transformer->transform(<<<'HTML'
<p>Nam voluptatem rem molestiae cumque doloremque. <strong>Saepe animi deserunt</strong> Maxime iam et inventore. ipsam in dignissimos qui occaecati.</p>
<p><img src="https://example.com/wp-content/uploads/2024/10/image.png" /></p>
HTML);

$this->assertEquals([
[
'type' => 'paragraph',
'attrs' => ['textAlign' => 'left'],
'content' => [
['type' => 'text', 'text' => 'Nam voluptatem rem molestiae cumque doloremque. '],
['type' => 'text', 'text' => 'Saepe animi deserunt', 'marks' => [['type' => 'bold']]],
['type' => 'text', 'text' => ' Maxime iam et inventore. ipsam in dignissimos qui occaecati.'],
],
],
[
'type' => 'paragraph',
'attrs' => ['textAlign' => 'left'],
'content' => [
[
'type' => 'image',
'attrs' => [
'src' => 'assets::2024/10/image.png',
],
],
],
],
], $output);
}

#[Test]
public function it_doesnt_handles_images_without_base_url()
{
Expand Down

0 comments on commit e41a14d

Please sign in to comment.