Symfony League CommonMarkdown 自定义ExternalLinksExtension

发布于 2025-01-13 20:05:56 字数 4446 浏览 4 评论 0原文

在 Symfony 4/5/6.1 上的 services.yml 中自定义ExternalLinksExtension的正确方法是怎样的?

根据官方文档 ExternalLinksExtension 假设配置参数必须被传递到环境。但是,环境不是服务,也不会实例化为服务,即使它是这样声明的。它直接从初始化 CommonMarkdown 包的函数实例化,其中将空参数传递给它。

通过制作自定义扩展,也无法修改当前环境的配置。从 ExtensionInterface 继承不会为您提供此类访问权限。

我当前的方法是复制本机扩展 ExternalLinksExtension 的所有内容,并在 configureSchema 方法中将当前环境的配置与自定义参数合并。

class ExternalLinksExtension implements ConfigurableExtensionInterface
{

    public function configureSchema(ConfigurationBuilderInterface $builder): void
    {
        $applyOptions = [
            ExternalLinkProcessor::APPLY_NONE,
            ExternalLinkProcessor::APPLY_ALL,
            ExternalLinkProcessor::APPLY_INTERNAL,
            ExternalLinkProcessor::APPLY_EXTERNAL,
        ];

        $builder->addSchema('external_link', Expect::structure([
            'internal_hosts' => Expect::type('string|string[]'),
            'open_in_new_window' => Expect::bool(false),
            'html_class' => Expect::string()->default(''),
            'nofollow' => Expect::anyOf(...$applyOptions)->default(ExternalLinkProcessor::APPLY_NONE),
            'noopener' => Expect::anyOf(...$applyOptions)->default(ExternalLinkProcessor::APPLY_EXTERNAL),
            'noreferrer' => Expect::anyOf(...$applyOptions)->default(ExternalLinkProcessor::APPLY_EXTERNAL),
        ]));

        //this is where I pass custom arfuments
        $builder->merge([
            'external_link' => [
                'internal_hosts' => ["localhost"],
                'open_in_new_window' => true,
                'html_class' => 'external-link',
                'nofollow' => '',
                'noopener' => 'external',
                'noreferrer' => 'external',
            ]
        ]);
    }

    public function register(EnvironmentBuilderInterface $environment): void
    {
        $environment->addEventListener(DocumentParsedEvent::class, new ExternalLinkProcessor($environment->getConfiguration()), -50);
    }
}

这种方式对我有用,但我认为必须复制您想要自定义的所有扩展或者必须进行此类黑客攻击并不方便,应该有另一种更直接的配置方法。

在我的 service.yml 文件中

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.


    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/'
        exclude:
            - '../src/DependencyInjection/'
            - '../src/Entity/'
            - '../src/Kernel.php'
            - '../src/Tests/'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/Controller/'
        tags: ['controller.service_arguments']

     
    League\CommonMark\Environment\Environment:
        public: true
        arguments:
            -
                external_link:
                    -
                        internal_hosts: [ "localhost" ]
                        open_in_new_window: true
                        html_class: "external-link"
                        nofollow: ""
                        noopener: "external"
                        noreferrer: "external"


    League\CommonMark\Extension\Table\TableExtension:
        tags:
            - { name: twig.markdown.league_extension }

    League\CommonMark\Extension\Autolink\AutolinkExtension:
        tags:
            - { name: twig.markdown.league_extension }

    League\CommonMark\Extension\Strikethrough\StrikethroughExtension:
        tags:
            - { name: twig.markdown.league_extension }

    App\Service\League\CommonMark\ExternalLinksExtension:
        arguments: ... ##arguments here also doesnt work with the native extension
        tags:
            - { name: twig.markdown.league_extension }

twig docs 提到扩展必须使用标签 twig.markdown.league_extension

How is the correct way to customize the ExternalLinksExtension in the services.yml on Symfony 4/5/6.1?

according to official documentation ExternalLinksExtension it is assumed that the configuration parameters must be passed to the Enviroment. However, the Enviroment is not a service and is not instantiated as a service, even if it is declared as such. It is instantiated directly from the function that initializes the CommonMarkdown bundle, where empty arguments are passed on to it.

By making a custom extension there is also no way to modify the configuration of the current environment. Inheriting from ExtensionInterface does not give you such access.

The current way I do it is to copy all the content of the native extension ExternalLinksExtension and in the configureSchema method merge the configuration of the current environment with custom arguments.

class ExternalLinksExtension implements ConfigurableExtensionInterface
{

    public function configureSchema(ConfigurationBuilderInterface $builder): void
    {
        $applyOptions = [
            ExternalLinkProcessor::APPLY_NONE,
            ExternalLinkProcessor::APPLY_ALL,
            ExternalLinkProcessor::APPLY_INTERNAL,
            ExternalLinkProcessor::APPLY_EXTERNAL,
        ];

        $builder->addSchema('external_link', Expect::structure([
            'internal_hosts' => Expect::type('string|string[]'),
            'open_in_new_window' => Expect::bool(false),
            'html_class' => Expect::string()->default(''),
            'nofollow' => Expect::anyOf(...$applyOptions)->default(ExternalLinkProcessor::APPLY_NONE),
            'noopener' => Expect::anyOf(...$applyOptions)->default(ExternalLinkProcessor::APPLY_EXTERNAL),
            'noreferrer' => Expect::anyOf(...$applyOptions)->default(ExternalLinkProcessor::APPLY_EXTERNAL),
        ]));

        //this is where I pass custom arfuments
        $builder->merge([
            'external_link' => [
                'internal_hosts' => ["localhost"],
                'open_in_new_window' => true,
                'html_class' => 'external-link',
                'nofollow' => '',
                'noopener' => 'external',
                'noreferrer' => 'external',
            ]
        ]);
    }

    public function register(EnvironmentBuilderInterface $environment): void
    {
        $environment->addEventListener(DocumentParsedEvent::class, new ExternalLinkProcessor($environment->getConfiguration()), -50);
    }
}

This way it works for me, but I believe that it is not convenient to have to be copying all the extensions that you want to customize or that you must make this type of hacks, there should be another more direct method of configuration.

In my service.yml file

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.


    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/'
        exclude:
            - '../src/DependencyInjection/'
            - '../src/Entity/'
            - '../src/Kernel.php'
            - '../src/Tests/'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/Controller/'
        tags: ['controller.service_arguments']

     
    League\CommonMark\Environment\Environment:
        public: true
        arguments:
            -
                external_link:
                    -
                        internal_hosts: [ "localhost" ]
                        open_in_new_window: true
                        html_class: "external-link"
                        nofollow: ""
                        noopener: "external"
                        noreferrer: "external"


    League\CommonMark\Extension\Table\TableExtension:
        tags:
            - { name: twig.markdown.league_extension }

    League\CommonMark\Extension\Autolink\AutolinkExtension:
        tags:
            - { name: twig.markdown.league_extension }

    League\CommonMark\Extension\Strikethrough\StrikethroughExtension:
        tags:
            - { name: twig.markdown.league_extension }

    App\Service\League\CommonMark\ExternalLinksExtension:
        arguments: ... ##arguments here also doesnt work with the native extension
        tags:
            - { name: twig.markdown.league_extension }

the twig docs, mentions that the extensions must go with the tag twig.markdown.league_extension

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

2025-01-20 20:05:56

根据 此讨论PR其次,从 Twig 3.3.5 开始,Twig/Extra-Bundle 包含一个工厂,该工厂仅依赖于在 services.yaml 中声明所需的扩展,并使用特定标签 twig.markdown.league_extension

# services.yaml
services:
    League\CommonMark\Extension\Table\ExternalLinksExtension:
        tags: [ 'twig.markdown.league_extension' ]

这对我有用,使用 TableExtension 和我的 twig/extra-bundle v3.3.8。

According to this discussion and the PR that followed, since Twig 3.3.5, the Twig/Extra-Bundle contains a factory that simply relies on declaring the desired extensions in services.yaml, with the specific tag twig.markdown.league_extension:

# services.yaml
services:
    League\CommonMark\Extension\Table\ExternalLinksExtension:
        tags: [ 'twig.markdown.league_extension' ]

This worked for me, with TableExtension and my twig/extra-bundle v3.3.8.

陈年往事 2025-01-20 20:05:56

我也找不到在 symfony 中使用配置的方法。 lmeyer 提到了一种解决方法,其中创建了一个自定义工厂类 twig.markdown.league_common_mark_converter_factory,您可以在其中自定义配置(还包括扩展的设置):https://github.com/twigphp/Twig/issues/3725#issuecomment-1367948462

I couldnt find a way to use the configuration in symfony either. lmeyer mentioned a workaround where a custom factory class twig.markdown.league_common_mark_converter_factory is created in which you can customize the config (and also inlcude settings of the extensions): https://github.com/twigphp/Twig/issues/3725#issuecomment-1367948462

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文