webfactory/shortcode-bundle

Thunderer/Shortcode 的 Symfony 集成

2.5.1 2024-09-04 14:25 UTC

README

一个用于在 Twig 模板中解析 [shortcode] 标记的 Symfony 扩展包,使用 thunderer/Shortcode 库。

它允许您轻松定义短代码及其替换内容。短代码是特殊的文本片段,可以替换为其他内容或标记。例如,用户可以在评论中使用以下内容:

[image url="https://upload.wikimedia.org/wikipedia/en/f/f7/RickRoll.png"]
[text color="red"]This is red text.[/text]

类似于生活风格指南,这个扩展包提供了一個短代码指南,列出了所有注册的短代码,以及可选的描述和示例。

安装

像往常一样,使用 Composer 安装,并在您的应用程序中注册扩展包

composer require webfactory/shortcode-bundle
<?php
// config/bundles.php

public function registerBundles()
{
    return [
        // ...
        Webfactory\ShortcodeBundle\WebfactoryShortcodeBundle::class => ['all' => true],
        // ...
    ];
    // ...
}

使用方法

Twig 过滤器

该扩展包会设置一个名为 shortcodes 的 Twig 过滤器。您通过此过滤器传递的内容将由 Processor 类处理(参见 文档)。

{% apply shortcodes %}
    [image url="https://upload.wikimedia.org/wikipedia/en/f/f7/RickRoll.png"]
    [text color="red"]This is red text.[/text]
{% endapply %}
{{ some_content |shortcodes }}

使用控制器作为短代码处理器

该扩展包包含一个辅助类,允许使用 Symfony 的 Fragment 子框架嵌入控制器 技术来使控制器生成短代码的替换输出。

例如,假设以下配置:

# config.yml
webfactory_shortcode:
    shortcodes:
        image: AppBundle\Controller\EmbeddedImageController::show

然后,在 Twig 中进行类似以下操作时:

{{ '[image url="https://upload.wikimedia.org/wikipedia/en/f/f7/RickRoll.png"]' |shortcodes }}

... 将调用 AppBundle\Controller\EmbeddedImageController::show() 控制器方法。在上面的示例中,如 url 这样的额外短代码属性将作为参数传递给控制器。控制器返回的响应将用于替换指定内容中的短代码。控制器可以直接生成响应,或使用 Twig 渲染模板来创建它。

使用边边包括进行渲染

您还可以为特定的短代码使用 ESI 渲染。ESI 的优点是将单个短代码替换存储在边缓存和/或反向代理(如 Varnish)中,并可能在多个页面上重用。

⚠️ 注意:由于 ESI 的工作方式,控制器可见的(主)Request 已不再是使用短代码的位置。当您,例如,想要记录使用短代码的 URL 时,请记住这一点。

要为特定短代码使用基于 ESI 的嵌入,请使用以下配置:

# config.yml
webfactory_shortcodes:
    shortcodes:
        image: 
            controller: AppBundle\Controller\EmbeddedImageController::showAction
            method: esi

将处理器注册为服务

thunderer/Shortcode 包中,处理器将短代码转换为所需的替换内容。您可以通过使用 webfactory.shortcode 标签并添加指示短代码名称的 shortcode 属性,将来自 Symfony 依赖注入容器的服务注册为短代码处理器。

services:
    My\Shortcode\Handler\Service:
        tags:
            - { name: 'webfactory.shortcode', shortcode: 'my-shortcode-name' }

移除短代码周围的 <p> 标签

默认情况下,此扩展包中包含的 RemoveWrappingParagraphElementsEventHandler 将用于在短代码周围移除 <p>...</p> 标签,如果短代码是该段落的唯一文本内容。

激活短代码指南

可选的简码指南是一个控制器,它提供了一个包含所有配置简码的概览页面。对于每个简码,还有一个详细页面,包括渲染示例。

要使用简码指南,请包含来自 @WebfactoryShortcodeBundle/Resources/config/guide-routing.xml 的路由配置。

⚠️ 你可能只应该在 Symfony 的 dev 和/或 test 环境中这样做,并且可能还需要在安全配置中进一步限制访问。

# src/routing.yml
_shortcode-guide:
    prefix: /shortcodes
    resource: "@WebfactoryShortcodeBundle/Resources/config/guide-routing.xml"

按照上述定义的路由前缀,访问 /shortcodes/ 可以看到所有定义的简码列表。如果你想为简码添加描述并提供在详细页面上要渲染的示例简码,你可以在配置简码时添加这些信息。

# config.yml
webfactory_shortcodes:
    shortcodes:
        image: 
            controller: AppBundle\Controller\EmbeddedImageController::showAction
            description: "Renders an image tag with the {url} as it's source."
            example: "image url=https://upload.wikimedia.org/wikipedia/en/f/f7/RickRoll.png"

其他配置参数

在大多数情况下,默认值应该可以正常工作。但你可能需要配置其他内容,例如,如果默认解析器为大型片段需要太多内存。请参阅 thunderer 关于 解析配置 的文档,以便了解其优点、缺点和限制。

# config.yml

webfactory_shortcode:
    parser: 'regex'      # default: regular
    recursion_depth: 2   # default: null
    max_iterations: 2    # default: null

测试你的简码

本节提供了一些提示和起始指针,用于测试你的简码处理程序和捆绑配置。

直接单元测试

通常,你应该从直接测试简码处理程序开始。

无论你的处理程序是一个实现 __invoke 魔术方法的简单类,还是一个具有一个或多个方法的 Symfony 控制器:直接单元测试是控制处理程序(或控制器)的输入并立即访问其返回值的简单方法。这允许你测试更广泛范围的输入参数并验证结果。在这种情况下,你通常会使用模拟对象来替换处理程序所依赖的某些或所有其他类和服务。

如果你的简码处理程序生成 HTML 输出,Symfony DomCrawler 可能有助于对 HTML 结构和内容进行断言。

对简码处理控制器进行功能测试

当使用控制器来处理简码,且控制器使用 Twig 进行渲染时,你可能想要进行完整的功能(集成)测试,而不是模拟 Twig 引擎。

Symfony 文档描述了如何执行应用程序测试。然而,这种方法可能不适合你的简码控制器,因为这些通常 不是 通过路由可达的,因此你不能直接对其执行 HTTP 请求。

相反,编写一个集成测试,从中检索控制器作为服务从依赖注入容器,并直接在其上调用适当的方法。然后,就像前面所述,对控制器返回的响应进行断言。

以下是一个测试可能的样子。

<?php

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

class MyShortcodeControllerTest extends KernelTestCase
{
    public function test_renderImageAction_returns_img(): void
    {
        // Assume the controller is used to turn `[img id=42]` into some HTML markup

        // create fixture/setup image with ID 42 in the database or similar
        // ...

        // Exercise controller method
        $container = static::getContainer();
        $controller = $container->get(MyShortcodeController::class);
        $response = $controller->renderImageAction(42);

        // Verify outcome
        self::assertStringContainsString('<img src="..." />', (string) $response->getContent());
    }
}

测试配置

在你编写了一些测试来验证处理程序在不同输入参数或其他情况下(例如数据库内容)正常工作之后,你还需要确保给定的处理程序已正确注册并连接到正确的简码名称。由于我们现在关注的是如何将此捆绑、你的配置和你的处理程序结合起来,所以我们处于集成测试的领域。这些测试将会更慢,因为我们需要启动一个 Symfony Kernel,从依赖注入容器中获取服务,并测试各个部分的协同工作。

此包包含 \Webfactory\ShortcodeBundle\Test\ShortcodeDefinitionTestHelper 类及其同名公共服务。根据您偏好的测试具体程度,您可以使用此服务来验证...

  • 已知的短代码名称,即已为其设置处理程序
  • 检索给定短代码名称的处理程序,例如,您可以对所使用的类进行断言
  • 当使用控制器作为短代码处理程序时,测试给定短代码的控制器引用是否可以解析(控制器实际上存在)
  • 检索控制器实例以对其执行断言。

对于所有这些测试,您可能需要使用 KernelTestCase 作为您的测试基类(文档)。基本上,您需要启动内核,然后从容器中获取 ShortcodeDefinitionTestHelper 并使用其方法来检查您的短代码配置。

也许您想查看 ShortcodeDefinitionTestHelper 的测试,以了解该类的一些使用示例。

记住——此类测试不应测试处理程序的所有可能输入和输出;您已经通过更具体、更直接的测试覆盖了这一点。在这个测试层中,我们只关注确保所有单个部分正确连接。

端到端测试

如果您出于某种原因想对短代码处理进行完整的端到端测试,从包含短代码标记的给定字符串到处理后的结果,请查看 \Webfactory\ShortcodeBundle\Test\EndToEndTestHelper 类。

此辅助类可用于集成测试用例,并将对给定输入执行完整的短代码处理,包括向用作短代码处理程序的控制器分发子请求。

测试可能看起来像这样

<?php

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Webfactory\ShortcodeBundle\Test\EndToEndTestHelper;

class MyFullScaleTest extends KernelTestCase
{
    /** @test */
    public function replace_text_color(): void
    {
        self::bootKernel();
        
        $result = EndToEndTestHelper::createFromContainer(static::$container)->processShortcode('[text color="red"]This is red text.[/text]');
        
        self::assertSame('<span style="color: red;">This is red text.</span>', $result);
    }
}

假设您的应用程序配置为注册 text 短代码的处理程序,这可能也是一个控制器,此测试将执行全栈测试。

致谢、版权和许可证

此包始于 webfactory GmbH,波恩。

版权所有 2018-2023 webfactory GmbH,波恩。代码在 MIT 许可证 下发布。