contentful / rich-text.php

Utilities for the Contentful Rich Text
https://www.contentful.com
MIT License
12 stars 9 forks source link

How to render an image embedded in a Rich Text field? #57

Closed jellevandevelde closed 2 years ago

jellevandevelde commented 3 years ago

I'm currently grabbing the asset url as such, yet I'm getting a warning that getAsset() does not exists on NodeInterface.

public function render(RendererInterface $renderer, NodeInterface $node, array $context = []): string
{
    $url = $node->getAsset()->getFile()->getUrl();
    return '<img src=' . $url . ' />';
}
travisanderson commented 3 years ago

^ This...the documentation is severely lacking. Just want to display images and embeds within rich text. Desperate for help on this. If you want folks to use contentful in production, gotta help em out.

Sebb767 commented 3 years ago

Hi @jellevandevelde , Hi @travisanderson ,

sorry for being so late on this issue! I'll find the solution on Monday and get back to you ASAP

Sebb767 commented 3 years ago

Hi @jellevandevelde , @travisanderson ,

here is a full working example class which can embed images:

use Contentful\Core\File\ImageFile;
use Contentful\Delivery\Resource\Asset;
use Contentful\RichText\Node\EmbeddedAssetBlock;
use Contentful\RichText\NodeRenderer\NodeRendererInterface;
use Contentful\RichText\Node\NodeInterface;
use Contentful\RichText\RendererInterface;

class ImageEmbeddingRenderer implements NodeRendererInterface
{
    public function supports(NodeInterface $node): bool
    {
        if ($node instanceof EmbeddedAssetBlock) {
            /**
             * @var $asset Asset
             */
            $asset = $node->getAsset();
            $file = $asset->getFile();
            $contentType = $file->getContentType();
            return str_starts_with($contentType, "image/") && $file instanceof ImageFile;
        }
        return false;
    }

    public function render(RendererInterface $renderer, NodeInterface $node, array $context = []): string
    {
        /**
         * @var $asset Asset
         */
        $asset = $node->getAsset();
        /**
         * @var $file ImageFile
         */
        $file = $asset->getFile();

        return '<img src="'.$file->getUrl().'" alt="'.htmlspecialchars($asset->getTitle(), ENT_QUOTES).'">';
    }
}

This class should probably be in the base package; I'll add it in the next update and update the documentation accordingly. The original problem of your renderer was probably that the supports()-function did not search for the right entry type.

Hope this solves your issue and again, sorry for the long delay!