Prestashop: Attempted to call function "renderWidget" from the global namespace.

Created on 22 Jan 2019  路  10Comments  路  Source: PrestaShop/PrestaShop

I tried to use the same pattern used on module/ps_shoppingcart/ajax
but this don't work.
So, how does this still work on ps_shoppingcart?

what i did?
used something like that in an ajax controller

header('Content-Type: application/json'); die(json_encode([ 'preview' => $this->module->renderWidget(null, ['cart' => $this->context->cart]), 'modal' => $modal ]));
This is actually ps_shoppingcart code, but renderWidget is not seen if used on custom modules controllers..

Additionnal information
PrestaShop version: 1.7.5
PHP version: 7.2

1.7.5.0 CO No change required

Most helpful comment

You can't use $this->module if you are not in a ps_shoppingcart controller.
You have to get the ps_shoppingcart module instance then call renderWidget on it.
So you can do that :

        /** @var Ps_Shoppingcart $ps_shoppingcart Instance of module ps_shoppingcart */
        $ps_shoppingcart = Module::getInstanceByName('ps_shoppingcart');
        die(json_encode([
            'preview' => $ps_shoppingcart->renderWidget(null, ['cart' => $this->context->cart]),
            'modal'   => $modal
        ]));

All 10 comments

Hi @Bonobomagno,

Thanks to follow this documentation: https://devdocs.prestashop.com/1.7/modules/concepts/widgets/ check & feedback.
Thanks!

I'm not talking about that
I just wanna make an ajax controller and found simpler to return the renderWidget function, as you use on ps_shoppingcart module.
This is fine on ps_shoppingcart controller but not on custom one.
Docs dont say nothing about calling $this->module->renderWidget(etc) from controllers

ping @eternoendless @PrestaShop/prestashop-core-developers
Thanks!

You can't use $this->module if you are not in a ps_shoppingcart controller.
You have to get the ps_shoppingcart module instance then call renderWidget on it.
So you can do that :

        /** @var Ps_Shoppingcart $ps_shoppingcart Instance of module ps_shoppingcart */
        $ps_shoppingcart = Module::getInstanceByName('ps_shoppingcart');
        die(json_encode([
            'preview' => $ps_shoppingcart->renderWidget(null, ['cart' => $this->context->cart]),
            'modal'   => $modal
        ]));

This is not what i want to use. I'm not searching to call module A function from module B controller,
Just want to call a module A function (renderWidget) from module A controller.
I saw this pattern used on ps_shoppingcart , but there are no way to reproduce this.

why i want this? Because it is a simple way to return a rendered template (the widget render a tpl with variables) as a json.

p.s.
btw i had the same result by just using $this->module->fetch(etc) as a json return on the ajax controller .
But i had to repeat the renderWidget logic

Did you have this on your module class ?

<?php

if (!defined('_PS_VERSION_')) {
    exit;
}

use PrestaShop\PrestaShop\Core\Module\WidgetInterface;

class Yourgreatmodule extends Module implements WidgetInterface

sure ofc. the widgetRendering is working , so i can call it from the template.
but if i try to call it from the controller, i got this Attempted to call function "renderWidget" from the global namespace. error

The strange thing is that this module is the only official prestashop module that is using this way to render. So i dunno if ps_shoppingcart works thanks to an hack, or i did something bad

Did you defined a namespace in your Module class or in your controller ?
I can't reproduce your problem so maybe you did something bad.

For example with ps_banner

<?php
// modules/ps_banner/controllers/front/ajax.php

class Ps_BannerAjaxModuleFrontController extends ModuleFrontController
{
    /** @var Ps_Banner Instance of module ps_banner */
    public $module;

    /**
     * @see FrontController::initContent()
     */
    public function initContent()
    {
        parent::initContent();

        ob_end_clean();
        header('Content-Type: application/json');
        die(json_encode([
            'preview' => $this->module->renderWidget(null, []),
        ]));
    }
}

index.php?controller=ajax&module=ps_banner&fc=module
{"preview":"<a class=\"banner\" href=\"http:\/\/localhost\/\" title=\"\">\n <img src=\"http:\/\/localhost\/modules\/ps_banner\/img\/sale70.png\" alt=\"\" title=\"\" class=\"img-fluid\">\n <\/a>\n"}

now it is just working.
cache issue? I'm using developer version on debug mode without cache and with recompile forced
Pretty strange way to act..
Thanks for the help btw.

Was this page helpful?
0 / 5 - 0 ratings