没有请求的Symfony2模板化

时间:2012-01-11 16:04:05

标签: symfony

我试图从Symfony2中的ContainerAwareCommand发送电子邮件。但是当电子邮件模板呈现时,我得到了这个例外:

$body = $this->templating->render($template, $data);

异常

 ("You cannot create a service ("templating.helper.assets") of an inactive scope ("request").") 

我在github中发现这个助手需要请求对象。有人知道如何实例化Request对象吗?

4 个答案:

答案 0 :(得分:19)

您需要将容器设置为正确的范围并为其提供(假的)请求。在大多数情况下,这就足够了:

//before you render template add bellow code
$this->getContainer()->enterScope('request');
$this->getContainer()->set('request', new Request(), 'request');

完整的故事是here。如果您想了解详细信息,请阅读此issue on github

答案 1 :(得分:4)

问题出现是因为您在模板中使用了 asset()功能。

默认情况下, asset()依靠 Request 服务为您的资产生成网址(它需要知道您网站的基本路径是什么,或者是什么例如,如果您使用绝对资产网址,则为域名。

但是当您从命令行运行应用程序时,没有请求

解决此问题的一种方法是在config.yml中明确定义资产的基本网址,如下所示:

framework:
  templating:
    assets_base_urls: { http: ["http://yoursite.com"], ssl: ["http://yoursite.com"] }

定义 http ssl 非常重要,因为如果省略其中一个 asset()仍将依赖于请求服务

(可能的)缺点是资产的所有网址现在都是绝对的。

答案 2 :(得分:1)

由于您没有请求,您需要直接调用模板服务:

$this->container->get('templating')->render($template, $data);

答案 3 :(得分:1)

按照BetaRide的回答让我走上正轨但这还不够。然后它抱怨:“无法生成指定路线的URL”“因为这样的路线不存在。”

要创建一个有效的请求,我已经修改了它以请求项目的根目录,如下所示:

$request = new Request();
$request->create('/');
$this->container->enterScope('request');
$this->container->set('request', $request, 'request');

您可能需要调用不同的路径(安全的root?),root对我来说很好。

Symfony2 Docs

加分:

我必须通过Symfony2命令在cli中做很多模板/路由,我已经在AppKernel中更新了initializeContainer()方法。它创建到站点根目录的路由,设置路由器上下文并伪造用户登录:

protected function initializeContainer()
{
    parent::initializeContainer();
    if (PHP_SAPI == 'cli') {

        $container = $this->getContainer();

        /**
         * Fake request to home page for cli router.
         * Need to set router base url to request uri because when request object
         * is created it perceives the "/portal" part as path info only, not base
         * url and thus router will not include it in the generated url's.
         */
        $request = Request::create($container->getParameter('domain'));
        $container->enterScope('request');
        $container->set('request', $request, 'request');
        $context = new RequestContext();
        $context->fromRequest($request);
        $container->get('router')->setContext($context);
        $container->get('router')->getContext()->setBaseUrl($request->getRequestUri());

        /**
         * Fake admin user login for cli. Try database read,
         * gracefully print error message if failed and continue.
         * Continue mainly for doctrine:fixture:load when db still empty.
         */
        try {
            $user = $container->get('fos_user.user_manager')->findUserByUsername('admin');
            if ($user !== null) {
                $token = $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
                $this->getContainer()->get('security.token_storage')->setToken($token);
            }
        } catch (\Exception $e) {
            echo "Fake Admin user login failed.\n";
        }
    }
}

您可能不需要最后$container->get('router')->getContext()->setBaseUrl($request->getRequestUri());部分,但我必须这样做,因为我的网站根位于domain.com/siteroot/,并且路由器正在剥离/ siteroot / away以生成网址。