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 DB-GPT-HUB Text-to-SQL微调
  • ¥20 求解答(matlab)
  • ¥30 ffmpeg库使用过程中遇到的问题
  • ¥15 pyqt5 中python如何通过Qtwebchannel主动发消息给web前端
  • ¥15 关于HTML中title获取xml内容的问题
  • ¥15 fanuc机器人PRIO083数字信号未复原错误,如何解决?
  • ¥20 如何为现有电路板增加远程控制功能
  • ¥15 C#点击按钮的时候的循环次数就是最后一次,如何是循环第几次的值?
  • ¥15 UE5打包失败,求解决
  • ¥15 请问STM32G431的CANOPEN协议函数怎么写