contentful / rich-text
Contentful Rich Text 工具
Requires
- php: ^8.0
- ext-json: *
- contentful/core: ^3.0|^4.0
Requires (Dev)
- league/plates: ^3.3
- phpstan/phpstan: ^1.9
- phpunit/phpunit: ^8.5
- roave/backward-compatibility-check: ^7.1|^8.2.1
- symfony/finder: ^3.0|^4.0|^5.0
- twig/twig: ^3.0
Suggests
- league/plates: For integration with the Plates templating engine
- twig/twig: For integration with the Twig templating engine
This package is auto-updated.
Last update: 2024-09-02 23:17:05 UTC
README
此库旨在帮助您解析和渲染 Contentful 中的富文本字段类型。它需要 PHP 7.2 或更高版本或 PHP 8.0 或更高版本。
设置
使用 Composer 将此包添加到您的应用程序,并执行以下命令
composer require contentful/rich-text
然后,如果您还没有,请包含 Composer 自动加载器
require_once 'vendor/autoload.php';
解析
Contentful\RichText\Parser::parseLocalized(array $data, string|null $locale)
方法接受有效的未序列化富文本数据结构,并返回一个实现 Contentful\RichText\Node\NodeInterface
的对象。您还需要一个链接解析器来实例化解析器。
$parser = new Contentful\RichText\Parser($linkResolver); // Fetch some data from an entry field from Contentful /** @var Contentful\RichText\Node\NodeInterface $node */ $node = $parser->parseLocalized($data, $locale);
解析器还将自动解析任何链接的资产和条目。为此,您需要提供当前区域设置 - 否则,解析器将使用给定空间的默认区域设置解析链接。
根据节点实际类型,可以使用获取方法导航层次结构。请参阅可用节点的完整列表以获取完整参考。
渲染
此库的主要目的是提供一种自动渲染节点的方法。最简单的设置仅涉及创建 Contentful\RichText\Renderer
类的一个实例
$renderer = new Contentful\RichText\Renderer(); $output = $renderer->render($node);
库为所有支持的节点类型提供默认值。但是,您可能需要覆盖其中一些默认值,以自定义输出。为此,您将创建 NodeRenderer
类,这些类实现 Contentful\RichText\NodeRenderer\NodeRendererInterface
接口
namespace Contentful\RichText\NodeRenderer; use Contentful\RichText\Node\NodeInterface; use Contentful\RichText\RendererInterface; /** * NodeRendererInterface. * * A class implementing this interface is responsible for * turning a limited subset of objects implementing NodeInterface * into a string. * * The node renderer makes the support for a certain node explicit by * implementing the "supports" method. * * The node renderer can also throw an exception during rendering if * the given node is not supported. */ interface NodeRendererInterface { /** * Returns whether the current renderer * supports rendering the given node. * * @param NodeInterface $node The node which will be tested * * @return bool */ public function supports(NodeInterface $node): bool; /** * Renders a node into a string. * * @param RendererInterface $renderer The generic renderer object, which is used for * delegating rendering of nested nodes (such as ListItem in lists) * @param NodeInterface $node The node which must be rendered * @param array $context Optionally, extra context variables (useful with custom node renderers) * * @throws \InvalidArgumentException when the given $node is not supported * * @return string */ public function render(RendererInterface $renderer, NodeInterface $node, array $context = []): string; }
例如,如果您想将类添加到所有 h1
标签,您将得到类似下面的内容
use Contentful\RichText\NodeRenderer\NodeRendererInterface; use Contentful\RichText\Node\NodeInterface; use Contentful\RichText\Node\Heading1; use Contentful\RichText\RendererInterface; class CustomHeading1 implements NodeRendererInterface { public function supports(NodeInterface $node): bool { return $node instanceof Heading1; } public function render(RendererInterface $renderer, NodeInterface $node, array $context = []): string { return '<h1 class="my-custom-class">'.$renderer->renderCollection($node->getContent()).'</h1>'; } }
最后,您需要告诉主渲染器使用您的自定义节点渲染器
$renderer->pushNodeRenderer(new CustomHeading1());
现在所有 Heading1
节点的实例都将使用自定义节点渲染器进行渲染。您可以在 supports
方法中实现任何逻辑,因为只需要一个接口,所以您可以在构造函数中注入任何类型的依赖项。例如,这样做是为了允许使用模板引擎,如 Twig 或 Plates
use Twig\Environment; use Contentful\RichText\NodeRenderer\NodeRendererInterface; use Contentful\RichText\Node\NodeInterface; use Contentful\RichText\Node\Heading1; use Contentful\RichText\RendererInterface; class TwigCustomHeading1 implements NodeRendererInterface { /** * @var Environment */ private $twig; public function __construct(Environment $twig) { $this->twig = $twig; } public function supports(NodeInterface $node): bool { return $node instanceof Heading1; } public function render(RendererInterface $renderer, NodeInterface $node, array $context = []): string { $context['node'] = $node; return $this->twig->render('heading1.html.twig', $context); } }
此库为 Twig 和 Plates 提供开箱即用的支持,允许您从模板中调用 RenderInterface::render()
和 RenderInterface::renderCollection()
方法。要启用适当的扩展,只需让 Twig 环境或 Plates 引擎知道即可,如下所述。
Twig 集成
设置
$renderer = new Contentful\RichText\Renderer(); // Register the Twig extension, which will provide functions // rich_text_render() and rich_text_render_collection() // in a Twig template $extension = new Contentful\RichText\Bridge\TwigExtension($renderer); /** @var Twig\Environment $twig */ $twig->addExtension($extension); // Finally, tell the main renderer about your custom node renderer $customTwigHeading1NodeRenderer = new TwigCustomHeading1($twig); $renderer->pushNodeRenderer($customTwigHeading1NodeRenderer);
模板
<h1 class="my-custom-class">{{ rich_text_render_collection(node.content) }}</h1>
有关基于 Twig 的渲染过程的示例实现,请参阅测试节点渲染器和完整的集成测试。
Plates 集成
设置
$renderer = new \Contentful\RichText\Renderer(); // Register the Plates extension, which will provide functions // $this->richTextRender() and $this->richTextRenderCollection() // in a Plates template $extension = new \Contentful\RichText\Bridge\PlatesExtension($renderer); /** @var League\Plates\Engine $plates */ $plates->loadExtension($extension); // Finally, tell the main renderer about your custom node renderer $customPlatesHeading1NodeRenderer = new PlatesCustomHeading1($plates); $renderer->pushNodeRenderer($customPlatesHeading1NodeRenderer);
模板
// The function will output HTML, so remember *not* to escape it using $this->e() <?= $this->richTextRenderCollection($node->getContent()) ?>
有关基于Plates的渲染过程的示例实现,请查看测试节点渲染器和完整的集成测试。
如何避免主渲染器在遇到未知节点时抛出异常
默认情况下,当渲染器找不到合适的节点渲染器时,会抛出异常。为了避免这种情况,您必须将其设置为使用特殊的通用节点渲染器。
$renderer = new Contentful\RichText\Renderer(); $renderer->appendNodeRenderer(new Contentful\RichText\NodeRenderer\CatchAll());
特殊的Contentful\RichText\NodeRenderer\CatchAll
节点渲染器无论节点类型如何都会返回空字符串。重要的是使用appendNodeRenderer
而不是通常的pushNodeRenderer
方法,以便让这个特殊的节点渲染器具有最低的优先级,从而避免它拦截常规节点渲染器。
术语表
关于Contentful
Contentful是一个面向网络应用程序、移动应用程序和互联设备的云内容管理系统。它允许您在云中创建、编辑和管理内容,并通过强大的API在任何地方发布。Contentful提供管理编辑团队和促进组织间协作的工具。
许可证
版权所有(c)2015-2019 Contentful GmbH。代码在MIT许可证下发布。有关详细信息,请参阅LICENSE。