在Symfony 3的基本布局中使用Twig Extension

时间:2017-03-09 19:11:45

标签: php twig symfony

我有一个控制器,用于设置存储在DB中的一些东西。控制器看起来很像:

class SetupController extends Controller
{   
    protected $foreground = '#fff';
    protected $background = '#333';
    protected $logo = 'default.png';
    protected $show_logo = true;

    public function HomePageAction()
    {
        ...          
        $options = [
            ...
            'logo'              => $this->logo,
            'foreground'        => $this->foreground,
            'background'        => $this->background
        ];

        return $this->render('CommonBundle:Layout:topbar_info.html.twig', ['options' => $options]);
    }
}

我如何在/app/Resources/views/base.html.twig(这是我的布局)中使用该功能,如下所示:

<head>
    ...
    {% block stylesheets %}
        ...
        <style type="text/css" media="all">
            .background, .dynamic_color {
                background-color: {{ options.background }};
            }    
        </style>
    {% endblock %}
</head>
<body>
    <div id="logo_id_area_container" class="topbar">
        {{ render(controller('CommonBundle:Setup:HomePage')) }}
    </div>
</body>

当我尝试渲染页面时,它失败并出现以下错误:

  

变量“选项”不存在。

当然我试图使用var它不存在因为CommonBundle:Setup:HomePage动作出现,是否有人知道更好的方法来实现这个? < / p>

经过一些研究后,我想出了一个Twig Extension的使用,但我遗漏了一些因为没有按照我的预期工作。我的Twig扩展代码如上所示:

class SetupExtension extends \Twig_Extension
{
    use MMISessionTools;

    protected $em, $session, $zend, $session_record, $storage;
    protected $foreground = '#fff', $background = '#333', $logo = 'default.png', $show_logo = true;

    public function __construct(
        RegistryInterface $em,
        SessionInterface $session,
        ZendBridge $zb,
    ) {
        $this->em      = $em;
        $this->session = $session;
        $this->zend    = $zb;

        // Start the session before lookup for the required data
        $session->start();

        // Vars for internal usage
        $this->session_record = $record = $em->getRepository('CommonBundle:Session')->find($session->getId());
        $this->storage        = $this->UnserializeSessionData(explode('|', $record->getData())[1])['storage'];
    }

    public function renderLogo()
    {
        $logo = $this->storage->show_logo &&
        $this->storage instanceof \stdClass &&
        file_exists("/images/icons/logos/{$this->storage->prefix}_{$this->storage->host_companies_id}.gif")
            ? $this->storage->prefix.'_'.$this->storage->host_companies_id.'.gif'
            : $this->logo;

        return '<a href=""><img src="/images/icons/logos/'.$logo.'" alt="" height="60"></a>';
    }

    public function getFunctions()
    {
        return [
             new \Twig_SimpleFunction('render_logo', 'renderLogo', ['is_safe' => ['html']]),
        ];
    }
}

我从base.html.twig(主要布局或基本模板)调用它,如下所示:

{{ render_logo() }}

但我最终得到以下错误:

  

CRITICAL - 调用未定义的函数renderLogo()CRITICAL -   未捕获的PHP异常   Symfony的\分量\调试\异常\ UndefinedFunctionException:   “试图从全局命名空间调用函数”renderLogo“。”

我在[{1}}:

中注册了以下扩展程序
services.yml

我还缺少什么?我正在使用Symfony 3.2.5

1 个答案:

答案 0 :(得分:1)

在你的Twig扩展程序的getFunctions()方法中,你告诉Twig可调用字符串是renderLogo。这被PHP解释为函数renderLogo()。对于对象方法,您需要传递一个数组,其中第一个元素是对象,第二个元素是方法名称(参见http://php.net/manual/en/language.types.callable.php):

public function getFunctions()
{
    return [
         new \Twig_SimpleFunction('render_logo', [$this, 'renderLogo'], ['is_safe' => ['html']]),
    ];
}
相关问题