doucong7963 2017-03-09 19:11
浏览 39
已采纳

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

I have a controller for setup a few things stored in DB. Pretty much the controller looks like:

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]);
    }
}

How I am using that function in /app/Resources/views/base.html.twig (this is my layout) as follow:

<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>

When I try to render the page it fails with the following error:

Variable "options" does not exist.

Of course where I am trying to use the var it doesn't exist because is coming out on the CommonBundle:Setup:HomePage action, does any one knows a better way to achieve this?

After some research I come up with the use of a Twig Extension but I am missing something since is not working as I expect. My Twig Extension code looks like the one above:

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']]),
        ];
    }
}

I am calling it from base.html.twig (the main layout or base template) as follow:

{{ render_logo() }}

But I end up with the following error:

CRITICAL - Call to undefined function renderLogo() CRITICAL - Uncaught PHP Exception Symfony\Component\Debug\Exception\UndefinedFunctionException: "Attempted to call function "renderLogo" from the global namespace."

I have the extension registered as follow in services.yml:

setup.twig_extension:
    class: CommonBundle\Twig\SetupExtension
    arguments: ['@doctrine','@session', '@zend_bridge']
    tags:
        - { name: twig.extension }

What else I am missing here? I am using Symfony 3.2.5

  • 写回答

1条回答 默认 最新

  • dongsheng6056 2017-03-09 20:57
    关注

    Inside your Twig extension's getFunctions() method you are telling Twig that the callable is the string renderLogo. This is interpreted by PHP as the function renderLogo(). For object methods, you need to pass an array where the first element is the object and the second one is the method name (see http://php.net/manual/en/language.types.callable.php):

    public function getFunctions()
    {
        return [
             new \Twig_SimpleFunction('render_logo', [$this, 'renderLogo'], ['is_safe' => ['html']]),
        ];
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?