1

我正在编写一个具有以下功能的系统:普通用户(没有程序员或管理员)可以创建可以插入“占位符”的内容。在呈现页面时,这些占位符将被替换为不同的内容类型(例如,十六进制颜色代码、滑块、图像……)。占位符的替换有点复杂,并且有一些额外的功能(例如定义默认值,用正确语言的内容替换占位符,...)。因此,我创建了一个带有“占位符过滤器”的树枝扩展。此函数应获取正确的内容以替换占位符并处理附加功能。

因为内容类型是如此不同,所以对于每个包含在控制器中呈现内容的逻辑的内容类型,都有一些 - 让它称之为“插件”。

现在我的问题:

插件的控制器动作返回渲染的内容。因为我用树枝扩展中的内容替换了占位符,所以我需要一种方法来调用这个树枝扩展中的控制器动作。

到目前为止我的想法:

我知道我可以通过这种方式在模板中调用控制器动作(来源:http ://symfony.com/doc/current/book/templating.html ):

{{ render(controller(
        'AppBundle:Article:recentArticles',
        { 'max': 3 }
    )) }}

所以在twig中调用controller-action似乎没有问题。但我需要在树枝扩展中调用这个函数。

我也知道当我将控制器实现为服务时,我可以调用控制器动作。但是我不能将所有插件控制器定义为服务,因为插件是动态包含在系统中的。在安装新插件时动态处理服务也将是“困难的”(我认为我必须使用脚本编辑 service.yml - 或者我错了吗?)。这就是为什么我不能将控制器用作服务。- 但是当您可以告诉我如何动态实施服务时,我对其他解决方案持开放态度。

我已经尝试过的是结合这两个页面的解决方案:http: //symfony.com/doc/current/book/templating.html

echo $view['actions']->render(
    new \Symfony\Component\HttpKernel\Controller\ControllerReference(
        'AppBundle:Article:recentArticles',
        array('max' => 3)
    )
)

https://www.robinvdvleuten.nl/blog/rendering-templates-in-a-twig-extension/

我现在可以在我的 twig-extension 中的占位符过滤器中访问 Twig_Environment,但以下代码不起作用:

$twig->render( new \Symfony\Component\HttpKernel\Controller\ControllerReference(
                            'Extensions'.$namespace.'Bundle:Index:getContent',
                            array('content'=>$contentObject)
                        ), array() );

我收到 ControllerReference 无法转换为字符串的错误(这是有道理的,因为 ControllerReference 是一个对象......)。

那么有没有办法在树枝扩展中调用控制器动作而不将控制器定义为服务?还是我应该重新考虑整个解决方案?

4

2 回答 2

1

也许您可以定义一个 ViewListener 并让您的控制器返回您想要的 html,而不是 $this->render 在控制器上返回的响应。

您需要在控制器上使用 $this->renderView 并将结果返回给您的扩展程序。

老实说,我觉得像这样设置的整个系统非常hacky并且难以长期维护,所以我建议重新考虑它

于 2016-01-30T17:30:08.680 回答
0

经过几个小时“思考问题”后,我为主要问题找到了一个简单的答案。当我在我的过滤器函数中包含 Twig_environment 时(请参阅https://www.robinvdvleuten.nl/blog/rendering-templates-in-a-twig-extension/),我可以访问 twig render() 函数。该函数适用于模板和字符串。因此,在没有服务的情况下在 twig-extension 中调用控制器操作的最简单方法是使用普通的 twig-template-syntax:

// $twig is the Twig_Environment in my filter-function
$myRenderedContent = $twig->render(
    "{{ render(controller( 'Extensions".$namespace."Bundle:Index:getContent', { 'content': content })) }}", 
    array('content'=>$contentObject)
);

额外的想法:

正如您在http://symfony.com/doc/current/book/templating.html中看到的那样,在 symfony 中调用这样的控制器似乎完全没问题。所以我认为在 twig-extension 中使用这个功能也是可以的(因为 twig-extension 为模板渲染定义了额外的辅助函数,这就是我想用我的过滤器函数来用特殊的占位符替换特殊的占位符内容)。

也许不将我的插件控制器作为服务包括在内不是最佳做法,但到​​目前为止我还没有看到像这样处理插件控制器的缺点 - 当你知道一个时:请告诉我,因为我是开放的学习“如何让它变得更好”;-)

于 2016-02-02T12:29:30.810 回答