1

我的 Symfony 项目中有一个 Twig 扩展,它呈现一个 twitter 小部件。目前,在我的扩展中,我有这个:

public function twitter($handle, $number = 5)
{
    return "<div data-tweet-row=\"&lt;div&gt;&lt;a  href='http://twitter.com/{screen_name}/status/{id}'&gt;{tweet}&lt;/a&gt;&lt;span class='datetime'&gt;{datetime}&lt;/span&gt;&lt;/div&gt;\" data-twitter-header=\"&lt;div class='header'&gt;&lt;img src='https://api.twitter.com/1/users/profile_image?screen_name={screen_name}&amp;size=normal' /&gt;&lt;h4&gt;&lt;a href='http://twitter.com/{screen_name}'&gt;@{screen_name}&lt;/a&gt;&lt;/h4&gt;&lt;/div&gt;\" id=\"twitter\">&nbsp;</div><script>$('#twitter').biff_twitter({screen_name:'$handle',count:$number});</script>";
}

但是我真的不喜欢这个解决方案,我宁愿将 HTML 保存在下面views,然后从我的扩展中加载文件。

我可以使用以下方法从扩展中访问容器:

private $container;

public function __construct(ContainerInterface $container){
    $this->container = $container;
}

所以我需要类似的东西

$view_file = $this->container->get('...')->view('InternalSocialBundle:twitter_placeholder.html.twig')
4

2 回答 2

1

当然你完全正确。您要查找的服务名称是templating。所以这对你有用:

$html = $this->container->get('templating')->render('InternalSocialBundle:twitter_placeholder.html.twig');

编辑:

这是一个工作示例:

class FooExtension extends \Twig_Extension
{
    private $container;

    public function setContainer(\Symfony\Component\DependencyInjection\Container $container)
    {
        $this->container = $container;
    }

    public function foo()
    {
        return $this->container->get('templating')->render('CogiPortfolioBundle:Portfolio:tmp.html.twig');
    }

    public function getFunctions()
    {
        return array(
            'foo' => new \Twig_Function_Method($this, 'foo', array('is_safe' => array('html')))
        );
    }

    /* (...) */
}

服务定义:

<service id="cogi.foo.ext" class="Cogi\PortfolioBundle\TwigExtension\FooExtension">
    <call method="setContainer">
        <argument type="service" id="service_container" />
    </call>
    <tag name="twig.extension" />
</service>

并且知道如果我调用任何模板 {{ foo() }} 它会从tmp.twig.html. 另一方面 - 如果在我的扩展中我将“路径”放入render方法中不存在的模板,则会引发异常。

我希望这有帮助。

于 2013-01-09T08:25:27.653 回答
1

好的,所以我解决了我遇到的问题,但是我没有完全测试它是我的错。@Cyprian 的解决方案在您没有做任何复杂的事情并且只是按预期使用扩展时确实工作得很好。

我的问题是我正在使用这个从数据库加载模板的评估扩展,因此它是 twig 正在执行所有加载(因此只是将第一个参数解释$this->render()为 a string- 它没有尝试加载它使用 symfony 命名模式)。

这意味着在实际的树枝文件中使用上述方法时,我的扩展程序可以正常工作,但在我使用{{body|evaluate}}扩展程序时却不行。

该问题的解决方案如下:

在我的 services.yml 文件中,我不仅需要service_container,而且twig.loader看起来很喜欢:

class: Test\SocialBundle\Twig\SocialExtension
arguments: [@service_container,@twig.loader]
tags:
    -  { name: 'twig.extension' }

然后我把它作为树枝扩展构造函数:

public function __construct(ContainerInterface $container, \Symfony\Bundle\TwigBundle\Loader\FilesystemLoader $loader)
{
    $this->container = $container;
    $this->loader = $loader;
}

在我的getFilters()定义中:

public function getFilters()
{
  return array(
    'twitter' => new \Twig_Filter_Method($this, 'twitter',array(
        'is_safe' => array(
            'evaluate' => true
            ),
        'needs_environment' => true,
        )
    )
  )
}

最后,在我返回渲染输出之前:

public function twitter(\Twig_Environment $environment, $id)
{
    $social_item = array(); // get my data here from my service;
    $environment->setLoader($this->loader);
    return $environment->render("TestSocialBundle:Front:twitter_placeholder.html.twig",array());
}

这确保了我一直在使用\Symfony\Bundle\TwigBundle\Loader\FilesystemLoader加载器,而不是\Twig_Loader_String在我的案例中使用的加载器。

于 2013-01-22T15:44:16.183 回答