Jump to content

Passing new parameters to the template


Fruitcake_Gary

Recommended Posts

Hi

I have some problem with transferring new variables to a template. I wrote myself a small module that passes custom text to products in a category. I wanted these variables to appear in product-add-to-cart.tpl

<?php

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

class CustomTextCategories extends Module
{
    public function __construct()
    {
        $this->name = 'customtextcategories';
        $this->tab = 'front_office_features';
        $this->version = '1.0.0';
        $this->author = 'X X';
        $this->need_instance = 0;

        parent::__construct();

        $this->displayName = $this->l('Custom Text for Categories');
        $this->description = $this->l('Displays custom text for selected product categories.');
    }

    public function install()
    {
        return parent::install() &&
            $this->registerHook('displayProductButtons') &&
            $this->installTab() &&
            Configuration::updateValue('CUSTOM_TEXT', '') &&
            Configuration::updateValue('CATEGORY_IDS', '');
    }

    public function installTab()
    {
        $tab = new Tab();
        $tab->active = 1;
        $tab->class_name = 'AdminCustomTextCategories';
        $tab->name = [];
        foreach (Language::getLanguages(true) as $lang) {
            $tab->name[$lang['id_lang']] = 'Custom Text Categories';
        }
        $tab->id_parent = (int) Tab::getIdFromClassName('AdminOrders');
        $tab->module = $this->name;
        $tab->add();
        return true;
    }

    public function uninstall()
    {
        $this->uninstallTab();
        return parent::uninstall() &&
            Configuration::deleteByName('CUSTOM_TEXT') &&
            Configuration::deleteByName('CATEGORY_IDS');
    }

    public function uninstallTab()
    {
        $tabId = (int) Tab::getIdFromClassName('AdminCustomTextCategories');
        if ($tabId) {
            $tab = new Tab($tabId);
            $tab->delete();
        }
    }

    public function getContent()
    {
        $output = '';

        if (Tools::isSubmit('submitCustomTextCategories')) {
            $customText = Tools::getValue('CUSTOM_TEXT');
            $categoryIds = Tools::getValue('CATEGORY_IDS');

            Configuration::updateValue('CUSTOM_TEXT', $customText);
            Configuration::updateValue('CATEGORY_IDS', $categoryIds);

            $output .= $this->displayConfirmation($this->l('Settings updated.'));
        }

        return $output . $this->renderForm();
    }

    protected function renderForm()
    {
        $fieldsForm = [
            'form' => [
                'legend' => [
                    'title' => $this->l('Settings'),
                ],
                'input' => [
                    [
                        'type' => 'textarea',
                        'label' => $this->l('Custom Text'),
                        'name' => 'CUSTOM_TEXT',
                        'rows' => 5,
                        'cols' => 40,
                        'desc' => $this->l('Enter the custom text to display on products in selected categories.'),
                    ],
                    [
                        'type' => 'text',
                        'label' => $this->l('Category IDs'),
                        'name' => 'CATEGORY_IDS',
                        'desc' => $this->l('Enter category IDs, separated by commas. Example: 1,2,3'),
                    ],
                ],
                'submit' => [
                    'title' => $this->l('Save'),
                ],
            ],
        ];

        $helper = new HelperForm();
        $helper->submit_action = 'submitCustomTextCategories';
        $helper->fields_value['CUSTOM_TEXT'] = Configuration::get('CUSTOM_TEXT');
        $helper->fields_value['CATEGORY_IDS'] = Configuration::get('CATEGORY_IDS');

        return $helper->generateForm([$fieldsForm]);
    }

    public function hookDisplayProductButtons($params)
    {
        error_log("hookDisplayProductButtons called");

        $customText = Configuration::get('CUSTOM_TEXT');
        $categoryIds = Configuration::get('CATEGORY_IDS');
        $categoryIdsArray = explode(',', $categoryIds);

        error_log("Custom Text: " . $customText);
        error_log("Category IDs: " . implode(',', $categoryIdsArray));

        // Przypisanie zmiennych do Smarty
        $this->context->smarty->assign([
            'custom_text' => $customText,
            'custom_categories' => $categoryIdsArray,
        ]);

    }

    public function hookHeader()
    {
        $this->context->controller->registerStylesheet(
            'customtextcategories-style',
            'modules/' . $this->name . '/views/css/customtextcategories.css',
            ['media' => 'all', 'priority' => 150]
        );
    }
}

product-add-to-cart.tpl

<div class="product-add-to-cart js-product-add-to-cart text-uppercase din-pro-font">
    {if !$configuration.is_catalog}

        {if $product.add_to_cart_url}
            {block name='product_quantity'}
                <span class="control-label">{l s='Quantity' d='Shop.Theme.Catalog'}</span>
                <div class="product-quantity clearfix">
                    <div class="qty">
                        <input
                                type="number"
                                name="qty"
                                id="quantity_wanted"
                                inputmode="numeric"
                                pattern="[0-9]*"
                                {if $product.quantity_wanted}
                                    value="{$product.quantity_wanted}"
                                    min="{$product.minimal_quantity}"
                                {else}
                                    value="1"
                                    min="1"
                                {/if}
                                class="input-group"
                                aria-label="{l s='Quantity' d='Shop.Theme.Actions'}"
                        >
                    </div>

                    <h1>{$custom_text}</h1>
                    <div class="add">
{*                        <button*}
{*                                class="btn btn-primary add-to-cart buy-button"*}
{*                                data-button-action="add-to-cart"*}
{*                                type="submit"*}
{*                                {if !$product.add_to_cart_url}*}
{*                                    disabled*}
{*                                {/if}*}
{*                        >*}
{*                            <i class="material-icons shopping-cart">&#xE547;</i>*}
{*                            {l s='Add to cart' d='Shop.Theme.Actions'}*}
{*                        </button>*}
                        {if $product.id_category_default|in_array:[$custom_categories]}
                            <div class="custom-text">
                                {$custom_text}
                            </div>
                        {else}
                            <button
                                    class="btn btn-primary add-to-cart buy-button"
                                    data-button-action="add-to-cart"
                                    type="submit"
                                    {if !$product.add_to_cart_url}
                                        disabled
                                    {/if}
                            >
                                <i class="material-icons shopping-cart">&#xE547;</i>
                                {l s='Add to cart' d='Shop.Theme.Actions'}
                            </button>
                        {/if}
                    </div>
                    {hook h='displayProductActions' product=$product}

                </div>
            {/block}
        {else}

            <div class="main-container-styled p-1 mb-2">
                Oferta ma charakter informacyjny i prezentuje dostępność broni i amunicji w naszym sklepie stacjonarny pod adresem ul. Jag 2A, 55-095 Mirków. Zakup broni, amunicji, prochów strzelniczych oraz spłonek możliwy jest wyłącznie w siedzibie naszej firmy, za okazaniem stosownych dokumentów uprawniających do zakupu.

                Kontakt w sprawie broni i amunicji:
            </div>
        {/if}

        {if Configuration::get('RESERVATION_ENABLED')}
            <button id="reserve-button" class="btn btn-primary buy-button">ZAREZERWUJ</button>
        {/if}
        {block name='product_availability'}
            <span id="product-availability" class="js-product-availability">
        {if $product.show_availability && $product.availability_message}
            {if $product.availability == 'available'}
                <i class="material-icons rtl-no-flip product-available">&#xE5CA;</i>

{elseif $product.availability == 'last_remaining_items'}

                <i class="material-icons product-last-items">&#xE002;</i>

{else}

                <i class="material-icons product-unavailable">&#xE14B;</i>
            {/if}
            {$product.availability_message}
        {/if}
      </span>
        {/block}

        {block name='product_minimal_quantity'}
            <p class="product-minimal-quantity js-product-minimal-quantity">
                {if $product.minimal_quantity > 1}
                    {l
                    s='The minimum purchase order quantity for the product is %quantity%.'
                    d='Shop.Theme.Checkout'
                    sprintf=['%quantity%' => $product.minimal_quantity]
                    }
                {/if}
            </p>
        {/block}
    {/if}
</div>

 

The problem is that these variables do not pass, I want them to appear directly in this template and not any hook. The only thing that appears in <pre> is '1'. In the hookup {hook h='displayProductActions' product=$product} the variables do appear, but the point is not there.

Link to comment
Share on other sites

Hi.

And you've already tried:

{$custom_text nofilter}

 

Or add your own hook to the TPL template, for example:

{hook h='displayMyCustomText' productId=$product.id categoryDefault=$product.id_category_default}

 

Link to comment
Share on other sites

Dnia 30.09.2024 o 12:45 AM, Fruitcake_Gary napisał:

Hi

I have some problem with transferring new variables to a template. I wrote myself a small module that passes custom text to products in a category. I wanted these variables to appear in product-add-to-cart.tpl

<?php

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

class CustomTextCategories extends Module
{
    public function __construct()
    {
        $this->name = 'customtextcategories';
        $this->tab = 'front_office_features';
        $this->version = '1.0.0';
        $this->author = 'X X';
        $this->need_instance = 0;

        parent::__construct();

        $this->displayName = $this->l('Custom Text for Categories');
        $this->description = $this->l('Displays custom text for selected product categories.');
    }

    public function install()
    {
        return parent::install() &&
            $this->registerHook('displayProductButtons') &&
            $this->installTab() &&
            Configuration::updateValue('CUSTOM_TEXT', '') &&
            Configuration::updateValue('CATEGORY_IDS', '');
    }

    public function installTab()
    {
        $tab = new Tab();
        $tab->active = 1;
        $tab->class_name = 'AdminCustomTextCategories';
        $tab->name = [];
        foreach (Language::getLanguages(true) as $lang) {
            $tab->name[$lang['id_lang']] = 'Custom Text Categories';
        }
        $tab->id_parent = (int) Tab::getIdFromClassName('AdminOrders');
        $tab->module = $this->name;
        $tab->add();
        return true;
    }

    public function uninstall()
    {
        $this->uninstallTab();
        return parent::uninstall() &&
            Configuration::deleteByName('CUSTOM_TEXT') &&
            Configuration::deleteByName('CATEGORY_IDS');
    }

    public function uninstallTab()
    {
        $tabId = (int) Tab::getIdFromClassName('AdminCustomTextCategories');
        if ($tabId) {
            $tab = new Tab($tabId);
            $tab->delete();
        }
    }

    public function getContent()
    {
        $output = '';

        if (Tools::isSubmit('submitCustomTextCategories')) {
            $customText = Tools::getValue('CUSTOM_TEXT');
            $categoryIds = Tools::getValue('CATEGORY_IDS');

            Configuration::updateValue('CUSTOM_TEXT', $customText);
            Configuration::updateValue('CATEGORY_IDS', $categoryIds);

            $output .= $this->displayConfirmation($this->l('Settings updated.'));
        }

        return $output . $this->renderForm();
    }

    protected function renderForm()
    {
        $fieldsForm = [
            'form' => [
                'legend' => [
                    'title' => $this->l('Settings'),
                ],
                'input' => [
                    [
                        'type' => 'textarea',
                        'label' => $this->l('Custom Text'),
                        'name' => 'CUSTOM_TEXT',
                        'rows' => 5,
                        'cols' => 40,
                        'desc' => $this->l('Enter the custom text to display on products in selected categories.'),
                    ],
                    [
                        'type' => 'text',
                        'label' => $this->l('Category IDs'),
                        'name' => 'CATEGORY_IDS',
                        'desc' => $this->l('Enter category IDs, separated by commas. Example: 1,2,3'),
                    ],
                ],
                'submit' => [
                    'title' => $this->l('Save'),
                ],
            ],
        ];

        $helper = new HelperForm();
        $helper->submit_action = 'submitCustomTextCategories';
        $helper->fields_value['CUSTOM_TEXT'] = Configuration::get('CUSTOM_TEXT');
        $helper->fields_value['CATEGORY_IDS'] = Configuration::get('CATEGORY_IDS');

        return $helper->generateForm([$fieldsForm]);
    }

    public function hookDisplayProductButtons($params)
    {
        error_log("hookDisplayProductButtons called");

        $customText = Configuration::get('CUSTOM_TEXT');
        $categoryIds = Configuration::get('CATEGORY_IDS');
        $categoryIdsArray = explode(',', $categoryIds);

        error_log("Custom Text: " . $customText);
        error_log("Category IDs: " . implode(',', $categoryIdsArray));

        // Przypisanie zmiennych do Smarty
        $this->context->smarty->assign([
            'custom_text' => $customText,
            'custom_categories' => $categoryIdsArray,
        ]);

    }

    public function hookHeader()
    {
        $this->context->controller->registerStylesheet(
            'customtextcategories-style',
            'modules/' . $this->name . '/views/css/customtextcategories.css',
            ['media' => 'all', 'priority' => 150]
        );
    }
}

product-add-to-cart.tpl

<div class="product-add-to-cart js-product-add-to-cart text-uppercase din-pro-font">
    {if !$configuration.is_catalog}

        {if $product.add_to_cart_url}
            {block name='product_quantity'}
                <span class="control-label">{l s='Quantity' d='Shop.Theme.Catalog'}</span>
                <div class="product-quantity clearfix">
                    <div class="qty">
                        <input
                                type="number"
                                name="qty"
                                id="quantity_wanted"
                                inputmode="numeric"
                                pattern="[0-9]*"
                                {if $product.quantity_wanted}
                                    value="{$product.quantity_wanted}"
                                    min="{$product.minimal_quantity}"
                                {else}
                                    value="1"
                                    min="1"
                                {/if}
                                class="input-group"
                                aria-label="{l s='Quantity' d='Shop.Theme.Actions'}"
                        >
                    </div>

                    <h1>{$custom_text}</h1>
                    <div class="add">
{*                        <button*}
{*                                class="btn btn-primary add-to-cart buy-button"*}
{*                                data-button-action="add-to-cart"*}
{*                                type="submit"*}
{*                                {if !$product.add_to_cart_url}*}
{*                                    disabled*}
{*                                {/if}*}
{*                        >*}
{*                            <i class="material-icons shopping-cart">&#xE547;</i>*}
{*                            {l s='Add to cart' d='Shop.Theme.Actions'}*}
{*                        </button>*}
                        {if $product.id_category_default|in_array:[$custom_categories]}
                            <div class="custom-text">
                                {$custom_text}
                            </div>
                        {else}
                            <button
                                    class="btn btn-primary add-to-cart buy-button"
                                    data-button-action="add-to-cart"
                                    type="submit"
                                    {if !$product.add_to_cart_url}
                                        disabled
                                    {/if}
                            >
                                <i class="material-icons shopping-cart">&#xE547;</i>
                                {l s='Add to cart' d='Shop.Theme.Actions'}
                            </button>
                        {/if}
                    </div>
                    {hook h='displayProductActions' product=$product}

                </div>
            {/block}
        {else}

            <div class="main-container-styled p-1 mb-2">
                Oferta ma charakter informacyjny i prezentuje dostępność broni i amunicji w naszym sklepie stacjonarny pod adresem ul. Jag 2A, 55-095 Mirków. Zakup broni, amunicji, prochów strzelniczych oraz spłonek możliwy jest wyłącznie w siedzibie naszej firmy, za okazaniem stosownych dokumentów uprawniających do zakupu.

                Kontakt w sprawie broni i amunicji:
            </div>
        {/if}

        {if Configuration::get('RESERVATION_ENABLED')}
            <button id="reserve-button" class="btn btn-primary buy-button">ZAREZERWUJ</button>
        {/if}
        {block name='product_availability'}
            <span id="product-availability" class="js-product-availability">
        {if $product.show_availability && $product.availability_message}
            {if $product.availability == 'available'}
                <i class="material-icons rtl-no-flip product-available">&#xE5CA;</i>

{elseif $product.availability == 'last_remaining_items'}

                <i class="material-icons product-last-items">&#xE002;</i>

{else}

                <i class="material-icons product-unavailable">&#xE14B;</i>
            {/if}
            {$product.availability_message}
        {/if}
      </span>
        {/block}

        {block name='product_minimal_quantity'}
            <p class="product-minimal-quantity js-product-minimal-quantity">
                {if $product.minimal_quantity > 1}
                    {l
                    s='The minimum purchase order quantity for the product is %quantity%.'
                    d='Shop.Theme.Checkout'
                    sprintf=['%quantity%' => $product.minimal_quantity]
                    }
                {/if}
            </p>
        {/block}
    {/if}
</div>

 

The problem is that these variables do not pass, I want them to appear directly in this template and not any hook. The only thing that appears in <pre> is '1'. In the hookup {hook h='displayProductActions' product=$product} the variables do appear, but the point is not there.

I dont see your hook being called inside tpl. Also you should return template to your variables since they passed only to your template.
 

    public function hookDisplayProductButtons($params)
    {
        error_log("hookDisplayProductButtons called");

        $customText = Configuration::get('CUSTOM_TEXT');
        $categoryIds = Configuration::get('CATEGORY_IDS');
        $categoryIdsArray = explode(',', $categoryIds);

        error_log("Custom Text: " . $customText);
        error_log("Category IDs: " . implode(',', $categoryIdsArray));

        // Przypisanie zmiennych do Smarty
        $this->context->smarty->assign([
            'custom_text' => $customText,
            'custom_categories' => $categoryIdsArray,
        ]);
		return $this->fetch('module:'.$this->name.'/views/templates/front/yourtemplatename.tpl');
    }

Then you simply add your hook inside theme template so it will be executed.

product-add-to-cart.tpl
{hook='DisplayProductButtons'}

Link to comment
Share on other sites

  • 3 weeks later...

Hi @WisQQ

Your solution works correctly. However, there was another problem. While plugging this hookup works popawfully it plugs in addition to displayProductAdditionalInfo which makes my button appear twice. 

image.thumb.png.2b0cc36d1dc215c3c1498e9d0d59dbed.png

TEST HOOK comes from my module. It adds itself to product-additional-info which causes JS to malfunction, the chevrons responsible for increasing the number of products disappear, and that heart icon disappears. The same problem occurs in quick-view.

 

By the way, is there any possibility that after installing the module, it will replace the 

{block name='product_add_to_cart'}
	{include file='catalog/_partials/product-add-to-cart.tpl'}
{/block}

For my solution, or at least overwrite this product-add-to-cart.tpl

{hook h='displayProductButtons' product=$product}

 

Link to comment
Share on other sites

@WisQQ

good, I got to the fact that this button comes from core.js and is injected into the template. Is there any way to force Prestashop to use my template by default as the primary one? It's as if the store forgets that such a file in _partials-product-add-to-cart.tpl even exists, and takes the same file from my module, but already properly crafted


<div class="product-add-to-cart js-product-add-to-cart text-uppercase din-pro-font">
    
        
            <span class="control-label">Ilość</span>
            <div class="product-quantity clearfix">
                <div class="qty">
                    <input
                            type="number"
                            name="qty"
                            id="quantity_wanted"
                            inputmode="numeric"
                            pattern="[0-9]*"
                                                            value="1"
                                min="1"
                                                        class="input-group"
                            aria-label="Ilość"
                    >
                </div>

                <div class="add">
                    <button
                            class="btn btn-primary add-to-cart buy-button"
                            data-button-action="add-to-cart"
                            type="submit"
                                                >
                        <i class="material-icons shopping-cart">&#xE547;</i>
                        Dodaj do koszyka ZZ
                    </button>
                </div>
                <h1>test strona</h1>
                <div
  class="wishlist-button Q"
  data-url="http://localhost:8080/pl/module/blockwishlist/action?action=deleteProductFromWishlist"
  data-product-id="1"
  data-product-attribute-id="1"
  data-is-logged="1"
  data-list-id="1"
  data-checked="true"
  data-is-product="true"
></div>


            </div>
        


                    <button id="reserve-button" class="btn btn-primary buy-button">ZAREZERWUJ</button>
                
            <span id="product-availability" class="js-product-availability">
              </span>
        

        
            <p class="product-minimal-quantity js-product-minimal-quantity">
                            </p>
        
    </div>

image.thumb.png.14dfd02377876fa211dde9fc6521ee58.png

The idea is to make the module fully autonomous. I upload it and no longer have to code anything

Link to comment
Share on other sites

9 godzin temu, Fruitcake_Gary napisał:

@WisQQ

good, I got to the fact that this button comes from core.js and is injected into the template. Is there any way to force Prestashop to use my template by default as the primary one? It's as if the store forgets that such a file in _partials-product-add-to-cart.tpl even exists, and takes the same file from my module, but already properly crafted


<div class="product-add-to-cart js-product-add-to-cart text-uppercase din-pro-font">
    
        
            <span class="control-label">Ilość</span>
            <div class="product-quantity clearfix">
                <div class="qty">
                    <input
                            type="number"
                            name="qty"
                            id="quantity_wanted"
                            inputmode="numeric"
                            pattern="[0-9]*"
                                                            value="1"
                                min="1"
                                                        class="input-group"
                            aria-label="Ilość"
                    >
                </div>

                <div class="add">
                    <button
                            class="btn btn-primary add-to-cart buy-button"
                            data-button-action="add-to-cart"
                            type="submit"
                                                >
                        <i class="material-icons shopping-cart">&#xE547;</i>
                        Dodaj do koszyka ZZ
                    </button>
                </div>
                <h1>test strona</h1>
                <div
  class="wishlist-button Q"
  data-url="http://localhost:8080/pl/module/blockwishlist/action?action=deleteProductFromWishlist"
  data-product-id="1"
  data-product-attribute-id="1"
  data-is-logged="1"
  data-list-id="1"
  data-checked="true"
  data-is-product="true"
></div>


            </div>
        


                    <button id="reserve-button" class="btn btn-primary buy-button">ZAREZERWUJ</button>
                
            <span id="product-availability" class="js-product-availability">
              </span>
        

        
            <p class="product-minimal-quantity js-product-minimal-quantity">
                            </p>
        
    </div>

image.thumb.png.14dfd02377876fa211dde9fc6521ee58.png

The idea is to make the module fully autonomous. I upload it and no longer have to code anything

Please paste code you are using in your module, not sure where is problem with calling additional info twice, because this hook isnt inside classic theme product-add-to-cart.tpl

You could try to ovrride add to cart button using hookfilterProductContent. But I'm not 100% sure that it isnt protected property.

Link to comment
Share on other sites

@WisQQ

This is the full code for the module

<?php
define('_PS_MODE_DEV_', true);
class CustomTextCategories extends Module
{
    public function __construct()
    {
        $this->name = 'customtextcategories';
        $this->tab = 'administration';
        $this->version = '1.0.0';
        $this->author = 'test.test';
        $this->need_instance = 0;
        $this->bootstrap = true;

        parent::__construct();

        $this->displayName = $this->l('Custom Text Categories');
        $this->description = $this->l('Module to display custom text for specific product categories.');

        $this->ps_versions_compliancy = ['min' => '1.7', 'max' => _PS_VERSION_];
    }

    public function install()
    {

        return parent::install() &&
            $this->registerHook('displayOverrideTemplate') &&
            $this->registerHook('hookActionFrontControllerAfterInit') &&

            $this->registerHook('displayProductButtons') &&
            $this->registerHook('displayCategoryProductList') &&
//            $this->registerHook('displayProductListFunctionalButtons') &&
            $this->registerHook('actionFrontControllerSetMedia') &&
            $this->installTab('AdminParentOrders', 'AdminCustomTextCategories', 'Custom Text for Categories') &&
            Configuration::updateValue('CUSTOM_TEXT', '') &&
            Configuration::updateValue('CATEGORY_IDS', '');
    }

    public function installTab($parent, $className, $name)
    {
        $tab = new Tab();
        $tab->id_parent = (int) Tab::getIdFromClassName($parent);
        $tab->class_name = $className;
        $tab->module = $this->name;
        $tab->active = 1;

        foreach (Language::getLanguages(true) as $lang) {
            $tab->name[$lang['id_lang']] = $name;
        }

        return $tab->add();
    }

    public function initContent()
    {
        $this->context->smarty->assign([
            'custom_text' => Configuration::get('CUSTOM_TEXT'),
            'category_ids' => Configuration::get('CATEGORY_IDS'),
        ]);

        $this->content .= $this->context->smarty->fetch(
            _PS_MODULE_DIR_ . $this->module->name . '/views/templates/admin/configure.tpl'
        );

        parent::initContent();
    }

    public function uninstall()
    {
        return parent::uninstall() &&
            Configuration::deleteByName('CUSTOM_TEXT') &&
            Configuration::deleteByName('CATEGORY_IDS') &&
            $this->uninstallTab('AdminCustomTextCategories');
    }

    private function uninstallTab($class_name)
    {
        $id_tab = (int)Tab::getIdFromClassName($class_name);
        if ($id_tab) {
            $tab = new Tab($id_tab);
            return $tab->delete();
        }
        return false;
    }

    public function getContent()
    {
        $output = null;

        if (Tools::isSubmit('submitCustomTextCategories')) {
            $this->processForm();
            $output .= $this->displayConfirmation($this->l('Settings updated'));
        }

        return $output . $this->renderForm();
    }

    public function renderForm()
    {
        $helper = new HelperForm();

        $helper->show_toolbar = false;
        $helper->table = $this->table;
        $helper->module = $this;
        $helper->default_form_language = $this->context->language->id;
        $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG', 0);

        $helper->identifier = $this->identifier;
        $helper->submit_action = 'submitCustomTextCategories';
        $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false)
            . '&configure=' . $this->name
            . '&tab_module=' . $this->tab
            . '&module_name=' . $this->name;
        $helper->token = Tools::getAdminTokenLite('AdminModules');

        $helper->tpl_vars = [
            'fields_value' => $this->getConfigFormValues(),
            'languages' => $this->context->controller->getLanguages(),
            'id_language' => $this->context->language->id,
        ];

        return $helper->generateForm([$this->getConfigForm()]);
    }

    public function hookDisplayProductButtons($params)
    {
        static $hook_called = false;
        if ($hook_called) {
            return ''; // Hook był już wywołany, więc nic nie robimy
        }
        $hook_called = true;

        $customText = Configuration::get('CUSTOM_TEXT');
        $categoryIds = Configuration::get('CATEGORY_IDS');
        $categoryIdsArray = explode(',', $categoryIds);
        $blockBuyButton = Configuration::get('BLOCK_BUY_BUTTON');

        $this->context->smarty->assign([
            'custom_text' => $customText,
            'custom_categories' => $categoryIdsArray,
            'block_buy_button' => $blockBuyButton,
        ]);

        return $this->fetch('module:customtextcategories/views/templates/front/product-add-to-cart.tpl');
    }

    public function hookDisplayOverrideTemplate($params)
    {
        if ($params['controller'] == 'product') {
            if ($params['template_file'] == 'catalog/_partials/product-add-to-cart.tpl') {
                $params['template_file'] = 'module:customtextcategories/views/templates/front/product-add-to-cart.tpl';
            }
        }
    }

    public function hookActionFrontControllerAfterInit($params)
    {
        if ($this->context->controller->php_self === 'product') {
            $this->context->smarty->assign([
                'custom_text' => Configuration::get('CUSTOM_TEXT'),
                'category_ids' => explode(',', Configuration::get('CATEGORY_IDS')),
                'block_buy_button' => Configuration::get('BLOCK_BUY_BUTTON'),
            ]);

            $this->context->controller->getTemplateVarPage()['body_classes'][] = 'custom-add-to-cart';
        }
    }

    public function hookDisplayCategoryProductList($params)
    {
        $categoryIds = Configuration::get('CATEGORY_IDS');
        $categoryIdsArray = explode(',', $categoryIds);

        $productCategories = Product::getProductCategories($params['product']['id_product']);

        $matchingCategories = array_intersect($productCategories, $categoryIdsArray);

        $this->context->smarty->assign([
            'custom_categories' => $matchingCategories,
        ]);

        return $this->fetch('module:customtextcategories/views/templates/hook/category-add-to-cart.tpl');

    }

    public function hookActionFrontControllerSetMedia($params)
    {
        if ('product' === $this->context->controller->php_self) {
            $this->context->controller->registerJavascript(
                'modules-customtextcategories',
                'modules/' . $this->name . '/views/js/add_to_cart.js',
                ['position' => 'bottom', 'priority' => 150]
            );
        }
    }

    public function getAllCategories()
    {
        $categories = Category::getCategories($this->context->language->id, true, false);
        return $categories;
    }

    public function getConfigForm()
    {
        $categories = $this->getAllCategories();

        $categoryCheckboxes = [];
        foreach ($categories as $category) {
            $categoryCheckboxes[] = [
                'id' => 'category_' . $category['id_category'],
                'value' => $category['id_category'],
                'label' => $category['name']
            ];
        }

        return [
            'form' => [
                'legend' => [
                    'title' => $this->l('Custom Text Categories Configuration'),
                    'icon' => 'icon-cogs',
                ],
                'input' => [
                    [
                        'type' => 'textarea',
                        'label' => $this->l('Custom Text'),
                        'name' => 'CUSTOM_TEXT',
                        'cols' => 60,
                        'rows' => 5,
                        'required' => true,
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Włącz okno modalne'),
                        'name' => 'BLOCK_BUY_BUTTON',
                        'required' => false,
                        'is_bool' => true,
                        'values' => [
                            [
                                'id' => 'block_buy_button_on',
                                'value' => 1,
                                'label' => $this->l('Yes')
                            ],
                            [
                                'id' => 'block_buy_button_off',
                                'value' => 0,
                                'label' => $this->l('No')
                            ]
                        ]
                    ]
                ],
                'submit' => [
                    'title' => $this->l('Save'),
                ],
            ],
        ];
    }

    public function getConfigFormValues()
    {
        $categoryIds = Configuration::get('CATEGORY_IDS');
        $categoryIdsArray = explode(',', $categoryIds);

        $values = [
            'CUSTOM_TEXT' => Configuration::get('CUSTOM_TEXT'),
            'CATEGORY_IDS' => $categoryIdsArray,
            'BLOCK_BUY_BUTTON' => Configuration::get('BLOCK_BUY_BUTTON')
        ];

        return $values;
    }

    public function processForm()
    {
        $customText = Tools::getValue('CUSTOM_TEXT');
        Configuration::updateValue('CUSTOM_TEXT', $customText);

        $categories = Tools::getValue('CATEGORY_IDS', []);

        PrestaShopLogger::addLog('CATEGORY_IDS: ' . var_export($categories, true), 1);

        if (is_array($categories) && !empty($categories)) {
            $categoriesString = implode(',', $categories);
            Configuration::updateValue('CATEGORY_IDS', $categoriesString);
        } else {
            Configuration::updateValue('CATEGORY_IDS', '');
        }

        $blockBuyButton = Tools::getValue('BLOCK_BUY_BUTTON', 0);
        Configuration::updateValue('BLOCK_BUY_BUTTON', (int)$blockBuyButton);

        PrestaShopLogger::addLog('BLOCK_BUY_BUTTON value: ' . Tools::getValue('BLOCK_BUY_BUTTON'), 1);
    }

    public function postProcess()
    {
        if (Tools::isSubmit('submitCustomTextCategories')) {
            $customText = Tools::getValue('CUSTOM_TEXT');
            $categoryIds = Tools::getValue('CATEGORY_IDS', []);

            Configuration::updateValue('CUSTOM_TEXT', $customText);

            if (is_array($categoryIds) && !empty($categoryIds)) {
                $categoryIdsString = implode(',', $categoryIds);
                Configuration::updateValue('CATEGORY_IDS', $categoryIdsString);
            } else {
                Configuration::updateValue('CATEGORY_IDS', '');
            }

            $blockBuyButton = Tools::getValue('BLOCK_BUY_BUTTON', 0);
            Configuration::updateValue('BLOCK_BUY_BUTTON', (int)$blockBuyButton);

            PrestaShopLogger::addLog('BLOCK_BUY_BUTTON value: ' . Tools::getValue('BLOCK_BUY_BUTTON'), 1);
        }
    }

}

Module structure:

image.png.6f0748b19e61bcc61573a1542e0b0720.png

I wish I didn't have to paste this:

{hook h='displayProductButtons' product=$product}

 

But it automatically turned into this:

{block name='product_add_to_cart'}
	{include file='catalog/_partials/product-add-to-cart.tpl'}
{/block}

.tpl


{if (in_array($product->id_category_default, $custom_categories) && $block_buy_button == 0) || $configuration.is_catalog}
    <div class="main-container-styled p-1 mb-2">
        {$custom_text}
    </div>
{else}
    <div class="product-add-to-cart js-product-add-to-cart text-uppercase din-pro-font">
        {if !$configuration.is_catalog}

            {block name='product_quantity'}
                <span class="control-label">{l s='Quantity' d='Shop.Theme.Catalog'}</span>
                <div class="product-quantity clearfix">
                    <div class="qty">
                        <input
                                type="number"
                                name="qty"
                                id="quantity_wanted"
                                inputmode="numeric"
                                pattern="[0-9]*"
                                {if $product.quantity_wanted}
                                    value="{$product.quantity_wanted}"
                                    min="{$product.minimal_quantity}"
                                {else}
                                    value="1"
                                    min="1"
                                {/if}
                                class="input-group"
                                aria-label="{l s='Quantity' d='Shop.Theme.Actions'}"
                        >
                    </div>

                    <div class="add">
                        <button
                                class="btn btn-primary add-to-cart buy-button test_Custom_modules"
                                {if (in_array($product->id_category_default, $custom_categories) && $block_buy_button == 1)}
                                    data-button-action="test-cart"
                                    type="button"
                                {else}
                                    data-button-action="add-to-cart"
                                    type="submit"
                                {/if}

                                {if !$product.add_to_cart_url}
                                    disabled
                                {/if}
                        >
                            <i class="material-icons shopping-cart">&#xE547;</i>
                            {l s='Add to cart' d='Shop.Theme.Actions'}
                        </button>
                    </div>
                    <h1>test hook</h1>
                    {hook h='displayProductActions' product=$product}
                </div>
            {/block}


            {if Configuration::get('RESERVATION_ENABLED') && $product.add_to_cart_url}
                <button id="reserve-button" class="btn btn-primary buy-button">ZAREZERWUJ</button>
            {/if}
            {block name='product_availability'}
                <span id="product-availability" class="js-product-availability">
        {if $product.show_availability && $product.availability_message}
            {if $product.availability == 'available'}
                <i class="material-icons rtl-no-flip product-available">&#xE5CA;</i>
{elseif $product.availability == 'last_remaining_items'}
                <i class="material-icons product-last-items">&#xE002;</i>
{else}
                <i class="material-icons product-unavailable">&#xE14B;</i>
            {/if}
            {$product.availability_message}
        {/if}
      </span>
            {/block}

            {block name='product_minimal_quantity'}
                <p class="product-minimal-quantity js-product-minimal-quantity">
                    {if $product.minimal_quantity > 1}
                        {l
                        s='The minimum purchase order quantity for the product is %quantity%.'
                        d='Shop.Theme.Checkout'
                        sprintf=['%quantity%' => $product.minimal_quantity]
                        }
                    {/if}
                </p>
            {/block}
        {/if}
    </div>
{/if}

What I am trying to do is that it substitutes its template instead of _partials-product-add-to-cart.tpl. The thing is that my product-add-to-cart.tpl has some modified features that I really care about. I could make it so that I substitute the original _partials-product-add-to-cart.tpl but I would like to make it so that the person who will use this module will not have to interfere with anything in the store

Link to comment
Share on other sites

Dnia 25.10.2024 o 10:14 PM, Fruitcake_Gary napisał:

@WisQQ

This is the full code for the module

<?php
define('_PS_MODE_DEV_', true);
class CustomTextCategories extends Module
{
    public function __construct()
    {
        $this->name = 'customtextcategories';
        $this->tab = 'administration';
        $this->version = '1.0.0';
        $this->author = 'test.test';
        $this->need_instance = 0;
        $this->bootstrap = true;

        parent::__construct();

        $this->displayName = $this->l('Custom Text Categories');
        $this->description = $this->l('Module to display custom text for specific product categories.');

        $this->ps_versions_compliancy = ['min' => '1.7', 'max' => _PS_VERSION_];
    }

    public function install()
    {

        return parent::install() &&
            $this->registerHook('displayOverrideTemplate') &&
            $this->registerHook('hookActionFrontControllerAfterInit') &&

            $this->registerHook('displayProductButtons') &&
            $this->registerHook('displayCategoryProductList') &&
//            $this->registerHook('displayProductListFunctionalButtons') &&
            $this->registerHook('actionFrontControllerSetMedia') &&
            $this->installTab('AdminParentOrders', 'AdminCustomTextCategories', 'Custom Text for Categories') &&
            Configuration::updateValue('CUSTOM_TEXT', '') &&
            Configuration::updateValue('CATEGORY_IDS', '');
    }

    public function installTab($parent, $className, $name)
    {
        $tab = new Tab();
        $tab->id_parent = (int) Tab::getIdFromClassName($parent);
        $tab->class_name = $className;
        $tab->module = $this->name;
        $tab->active = 1;

        foreach (Language::getLanguages(true) as $lang) {
            $tab->name[$lang['id_lang']] = $name;
        }

        return $tab->add();
    }

    public function initContent()
    {
        $this->context->smarty->assign([
            'custom_text' => Configuration::get('CUSTOM_TEXT'),
            'category_ids' => Configuration::get('CATEGORY_IDS'),
        ]);

        $this->content .= $this->context->smarty->fetch(
            _PS_MODULE_DIR_ . $this->module->name . '/views/templates/admin/configure.tpl'
        );

        parent::initContent();
    }

    public function uninstall()
    {
        return parent::uninstall() &&
            Configuration::deleteByName('CUSTOM_TEXT') &&
            Configuration::deleteByName('CATEGORY_IDS') &&
            $this->uninstallTab('AdminCustomTextCategories');
    }

    private function uninstallTab($class_name)
    {
        $id_tab = (int)Tab::getIdFromClassName($class_name);
        if ($id_tab) {
            $tab = new Tab($id_tab);
            return $tab->delete();
        }
        return false;
    }

    public function getContent()
    {
        $output = null;

        if (Tools::isSubmit('submitCustomTextCategories')) {
            $this->processForm();
            $output .= $this->displayConfirmation($this->l('Settings updated'));
        }

        return $output . $this->renderForm();
    }

    public function renderForm()
    {
        $helper = new HelperForm();

        $helper->show_toolbar = false;
        $helper->table = $this->table;
        $helper->module = $this;
        $helper->default_form_language = $this->context->language->id;
        $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG', 0);

        $helper->identifier = $this->identifier;
        $helper->submit_action = 'submitCustomTextCategories';
        $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false)
            . '&configure=' . $this->name
            . '&tab_module=' . $this->tab
            . '&module_name=' . $this->name;
        $helper->token = Tools::getAdminTokenLite('AdminModules');

        $helper->tpl_vars = [
            'fields_value' => $this->getConfigFormValues(),
            'languages' => $this->context->controller->getLanguages(),
            'id_language' => $this->context->language->id,
        ];

        return $helper->generateForm([$this->getConfigForm()]);
    }

    public function hookDisplayProductButtons($params)
    {
        static $hook_called = false;
        if ($hook_called) {
            return ''; // Hook był już wywołany, więc nic nie robimy
        }
        $hook_called = true;

        $customText = Configuration::get('CUSTOM_TEXT');
        $categoryIds = Configuration::get('CATEGORY_IDS');
        $categoryIdsArray = explode(',', $categoryIds);
        $blockBuyButton = Configuration::get('BLOCK_BUY_BUTTON');

        $this->context->smarty->assign([
            'custom_text' => $customText,
            'custom_categories' => $categoryIdsArray,
            'block_buy_button' => $blockBuyButton,
        ]);

        return $this->fetch('module:customtextcategories/views/templates/front/product-add-to-cart.tpl');
    }

    public function hookDisplayOverrideTemplate($params)
    {
        if ($params['controller'] == 'product') {
            if ($params['template_file'] == 'catalog/_partials/product-add-to-cart.tpl') {
                $params['template_file'] = 'module:customtextcategories/views/templates/front/product-add-to-cart.tpl';
            }
        }
    }

    public function hookActionFrontControllerAfterInit($params)
    {
        if ($this->context->controller->php_self === 'product') {
            $this->context->smarty->assign([
                'custom_text' => Configuration::get('CUSTOM_TEXT'),
                'category_ids' => explode(',', Configuration::get('CATEGORY_IDS')),
                'block_buy_button' => Configuration::get('BLOCK_BUY_BUTTON'),
            ]);

            $this->context->controller->getTemplateVarPage()['body_classes'][] = 'custom-add-to-cart';
        }
    }

    public function hookDisplayCategoryProductList($params)
    {
        $categoryIds = Configuration::get('CATEGORY_IDS');
        $categoryIdsArray = explode(',', $categoryIds);

        $productCategories = Product::getProductCategories($params['product']['id_product']);

        $matchingCategories = array_intersect($productCategories, $categoryIdsArray);

        $this->context->smarty->assign([
            'custom_categories' => $matchingCategories,
        ]);

        return $this->fetch('module:customtextcategories/views/templates/hook/category-add-to-cart.tpl');

    }

    public function hookActionFrontControllerSetMedia($params)
    {
        if ('product' === $this->context->controller->php_self) {
            $this->context->controller->registerJavascript(
                'modules-customtextcategories',
                'modules/' . $this->name . '/views/js/add_to_cart.js',
                ['position' => 'bottom', 'priority' => 150]
            );
        }
    }

    public function getAllCategories()
    {
        $categories = Category::getCategories($this->context->language->id, true, false);
        return $categories;
    }

    public function getConfigForm()
    {
        $categories = $this->getAllCategories();

        $categoryCheckboxes = [];
        foreach ($categories as $category) {
            $categoryCheckboxes[] = [
                'id' => 'category_' . $category['id_category'],
                'value' => $category['id_category'],
                'label' => $category['name']
            ];
        }

        return [
            'form' => [
                'legend' => [
                    'title' => $this->l('Custom Text Categories Configuration'),
                    'icon' => 'icon-cogs',
                ],
                'input' => [
                    [
                        'type' => 'textarea',
                        'label' => $this->l('Custom Text'),
                        'name' => 'CUSTOM_TEXT',
                        'cols' => 60,
                        'rows' => 5,
                        'required' => true,
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Włącz okno modalne'),
                        'name' => 'BLOCK_BUY_BUTTON',
                        'required' => false,
                        'is_bool' => true,
                        'values' => [
                            [
                                'id' => 'block_buy_button_on',
                                'value' => 1,
                                'label' => $this->l('Yes')
                            ],
                            [
                                'id' => 'block_buy_button_off',
                                'value' => 0,
                                'label' => $this->l('No')
                            ]
                        ]
                    ]
                ],
                'submit' => [
                    'title' => $this->l('Save'),
                ],
            ],
        ];
    }

    public function getConfigFormValues()
    {
        $categoryIds = Configuration::get('CATEGORY_IDS');
        $categoryIdsArray = explode(',', $categoryIds);

        $values = [
            'CUSTOM_TEXT' => Configuration::get('CUSTOM_TEXT'),
            'CATEGORY_IDS' => $categoryIdsArray,
            'BLOCK_BUY_BUTTON' => Configuration::get('BLOCK_BUY_BUTTON')
        ];

        return $values;
    }

    public function processForm()
    {
        $customText = Tools::getValue('CUSTOM_TEXT');
        Configuration::updateValue('CUSTOM_TEXT', $customText);

        $categories = Tools::getValue('CATEGORY_IDS', []);

        PrestaShopLogger::addLog('CATEGORY_IDS: ' . var_export($categories, true), 1);

        if (is_array($categories) && !empty($categories)) {
            $categoriesString = implode(',', $categories);
            Configuration::updateValue('CATEGORY_IDS', $categoriesString);
        } else {
            Configuration::updateValue('CATEGORY_IDS', '');
        }

        $blockBuyButton = Tools::getValue('BLOCK_BUY_BUTTON', 0);
        Configuration::updateValue('BLOCK_BUY_BUTTON', (int)$blockBuyButton);

        PrestaShopLogger::addLog('BLOCK_BUY_BUTTON value: ' . Tools::getValue('BLOCK_BUY_BUTTON'), 1);
    }

    public function postProcess()
    {
        if (Tools::isSubmit('submitCustomTextCategories')) {
            $customText = Tools::getValue('CUSTOM_TEXT');
            $categoryIds = Tools::getValue('CATEGORY_IDS', []);

            Configuration::updateValue('CUSTOM_TEXT', $customText);

            if (is_array($categoryIds) && !empty($categoryIds)) {
                $categoryIdsString = implode(',', $categoryIds);
                Configuration::updateValue('CATEGORY_IDS', $categoryIdsString);
            } else {
                Configuration::updateValue('CATEGORY_IDS', '');
            }

            $blockBuyButton = Tools::getValue('BLOCK_BUY_BUTTON', 0);
            Configuration::updateValue('BLOCK_BUY_BUTTON', (int)$blockBuyButton);

            PrestaShopLogger::addLog('BLOCK_BUY_BUTTON value: ' . Tools::getValue('BLOCK_BUY_BUTTON'), 1);
        }
    }

}

Module structure:

image.png.6f0748b19e61bcc61573a1542e0b0720.png

I wish I didn't have to paste this:

{hook h='displayProductButtons' product=$product}

 

But it automatically turned into this:

{block name='product_add_to_cart'}
	{include file='catalog/_partials/product-add-to-cart.tpl'}
{/block}

.tpl


{if (in_array($product->id_category_default, $custom_categories) && $block_buy_button == 0) || $configuration.is_catalog}
    <div class="main-container-styled p-1 mb-2">
        {$custom_text}
    </div>
{else}
    <div class="product-add-to-cart js-product-add-to-cart text-uppercase din-pro-font">
        {if !$configuration.is_catalog}

            {block name='product_quantity'}
                <span class="control-label">{l s='Quantity' d='Shop.Theme.Catalog'}</span>
                <div class="product-quantity clearfix">
                    <div class="qty">
                        <input
                                type="number"
                                name="qty"
                                id="quantity_wanted"
                                inputmode="numeric"
                                pattern="[0-9]*"
                                {if $product.quantity_wanted}
                                    value="{$product.quantity_wanted}"
                                    min="{$product.minimal_quantity}"
                                {else}
                                    value="1"
                                    min="1"
                                {/if}
                                class="input-group"
                                aria-label="{l s='Quantity' d='Shop.Theme.Actions'}"
                        >
                    </div>

                    <div class="add">
                        <button
                                class="btn btn-primary add-to-cart buy-button test_Custom_modules"
                                {if (in_array($product->id_category_default, $custom_categories) && $block_buy_button == 1)}
                                    data-button-action="test-cart"
                                    type="button"
                                {else}
                                    data-button-action="add-to-cart"
                                    type="submit"
                                {/if}

                                {if !$product.add_to_cart_url}
                                    disabled
                                {/if}
                        >
                            <i class="material-icons shopping-cart">&#xE547;</i>
                            {l s='Add to cart' d='Shop.Theme.Actions'}
                        </button>
                    </div>
                    <h1>test hook</h1>
                    {hook h='displayProductActions' product=$product}
                </div>
            {/block}


            {if Configuration::get('RESERVATION_ENABLED') && $product.add_to_cart_url}
                <button id="reserve-button" class="btn btn-primary buy-button">ZAREZERWUJ</button>
            {/if}
            {block name='product_availability'}
                <span id="product-availability" class="js-product-availability">
        {if $product.show_availability && $product.availability_message}
            {if $product.availability == 'available'}
                <i class="material-icons rtl-no-flip product-available">&#xE5CA;</i>
{elseif $product.availability == 'last_remaining_items'}
                <i class="material-icons product-last-items">&#xE002;</i>
{else}
                <i class="material-icons product-unavailable">&#xE14B;</i>
            {/if}
            {$product.availability_message}
        {/if}
      </span>
            {/block}

            {block name='product_minimal_quantity'}
                <p class="product-minimal-quantity js-product-minimal-quantity">
                    {if $product.minimal_quantity > 1}
                        {l
                        s='The minimum purchase order quantity for the product is %quantity%.'
                        d='Shop.Theme.Checkout'
                        sprintf=['%quantity%' => $product.minimal_quantity]
                        }
                    {/if}
                </p>
            {/block}
        {/if}
    </div>
{/if}

What I am trying to do is that it substitutes its template instead of _partials-product-add-to-cart.tpl. The thing is that my product-add-to-cart.tpl has some modified features that I really care about. I could make it so that I substitute the original _partials-product-add-to-cart.tpl but I would like to make it so that the person who will use this module will not have to interfere with anything in the store

You can use any other hook but using {hook h='displayProductButtons' product=$product} allows you to place it anywhere you want, so i would still keep it as an option for the user.
 

    public function hookDisplayOverrideTemplate($params)
    {
        if ($params['controller'] == 'product') {
            if ($params['template_file'] == 'catalog/_partials/product-add-to-cart.tpl') {
                $params['template_file'] = 'module:customtextcategories/views/templates/front/product-add-to-cart.tpl';
            }
        }
    }

With this hook you can override entire product.tpl, but you cant change partials. When you dump the template_file variable you will see that it refers to 'catalog/product'.

You can override the addtocart on variant change, using prestashop js events. on updatedProduct
https://devdocs.prestashop-project.org/8/themes/reference/javascript-events/ Or you can try to override ProductController displayAjaxRefresh() function.

However you cant override add to cart template as its part of the theme without modifying theme file. You can only do that by using javascript after page was loaded.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...