Magento 2: добавить собственный скрипт сразу после тега head

Я хочу добавить собственный скрипт сразу после начала заголовка.

лайк.

<head>
<script>console.log("I'm loaded!");</script>

я пытался добавить код в default_head_blocks.xml

<referenceContainer name="head.additional">
      <block class="Custom\Module\Block\Success" template="Custom_Module::success/head.phtml"/>
</referenceContainer>

=> вывод:

<script>console.log("I'm loaded!");</script>
</head>

этот код использует скрипт добавления до конца тега head.

Пожалуйста, проверьте ниже код

Блок => Пользовательский / Модуль / Блок / Onepage / Success.php

namespace Custom\Module\Block\Onepage;
    use Magento\Framework\View\Element\Template;

    class Success extends \Magento\Checkout\Block\Onepage\Success {

    public function getOrder() 
        {
            $objectManager =\Magento\Framework\App\ObjectManager::getInstance();
            $helper = $objectManager->get('Custom\Module\Helper\Data');

            $lastOrderId = $this->getOrderId();

            if (empty($lastOrderId)) 
            {
                return null;
            }
              $orderData = $objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId($this->getOrderId());

            return $orderData;
        }

    }

Helper => Custom \ Module \ Helper \ Data.php

namespace Custom\Module\Helper;
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{

    /**
     * @param \Magento\Framework\App\Helper\Context $context
     */
    protected $_request;

    public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Framework\App\Request\Http $request
    ) {
         $this->_request = $request;
        parent::__construct($context);

    }
     public function getConfigValue($value = '') {
        return $this->scopeConfig
                ->getValue($value,\Magento\Store\Model\ScopeInterface::SCOPE_STORE);
    }
    public function getTemplate()
    {
        if ($this->getConfigValue('custom_general/general/active') == 1) {
            $template =  'Custom_Module::checkout/success.phtml';
        } else {
            $template = 'Magento_Checkout::success.phtml';
        }

        return $template;
    }
}

di.xml => etc \ di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../vendor/magento/framework/ObjectManager/etc/config.xsd">
    <preference for="Magento\Checkout\Block\Onepage\Success" type="Custom\Module\Block\Onepage\Success"/>
</config>

Layout Xml => Custom / Module / view / frontend / layout / default.xml

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
    <referenceBlock name="require.js">
        <action method="setTemplate">
            <argument name="template" xsi:type="string">Custom_Module::success/head.phtml</argument>
        </action>
    </referenceBlock> 
    </body>
</page>

Шаблон => Пользовательский / Модуль / Вид / Внешний / Шаблоны / Успех / head.phtml

<script>
    console.log("I'm loaded!");

</script>

Пожалуйста, помогите мне и решить эту проблему

Заранее спасибо.

1 ответ

Решение

Я не уверен, что это правильный путь или нет, но у меня есть преимущество.

По умолчанию magento 2 использует root.phtml файл для настройки head содержание соответственно, которое находится в vendor/magento/module-theme/view/base/templates/root.phtml (если он не был переопределен).

Здесь $requireJs переменная загружается первой в головной блок. $requireJs переменная определяется в render метод внутри Page класс, который находится в vendor/magento/framework/view/Result/Page.php,

В этом файле $requireJs содержит require.js блок. И require.js блок определен в vendor/Magento/module-theme/view/frontend/layout/default.xml:

<block name="require.js" class="Magento\Framework\View\Element\Template" template="Magento_Theme::page/js/require_js.phtml" />

Решение

1) Копировать require_js.phtml от vendor/magento/module-theme/view/frontend/templates/page/js к вашей теме app/design/frontend/{VENDOR}/{THEME_NAME}/Magento_Theme/templates/page/js/

2) Теперь вы можете добавить свой скрипт так:

<script>
    console.log("I'm loaded!");

    var require = {
        "baseUrl": "<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('/') ?>"
    };
</script>

ОБНОВЛЕНИЕ (Использование модуля)

Переопределение require.js Блок не элегантное решение. если у кого-то есть хорошее решение, пожалуйста, ответьте. А пока отредактируйте свой макет xml:

<referenceBlock name="require.js">
    <action method="setTemplate">
        <argument name="template" xsi:type="string">Custom_Module::success/head.phtml</argument>
    </action>
</referenceBlock> 

и внутри success/head.phtml добавьте свой код:

<script>
    console.log("I'm loaded!");
    var require = {
        "baseUrl": "<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('/') ?>"
    };
</script>

Я нашел простой способ сделать это, который кажется очень разумным, потому что он использует существующие функции в adminhtml тема без необходимости что-либо переопределять / перехватывать.

Задний план

Как упоминалось в @sanchit-gupta, root.phtml шаблон используется в качестве основы для рендеринга как frontend а также adminhtml областей, и связанный класс \Magento\Framework\View\Result\Page, который всегда ищет блок с именем head.additional перед рендерингом.

Этот блок существует в frontend макеты по умолчанию, но, к сожалению, его нет в adminhtml макет.

Решение

Имея это в виду, текущий лучший способ (начиная с 2.3.x) добавить встроенный <scripts> к adminhtmlс <head> раздел - добавить любые head.additionalблок: он будет автоматически отображаться фреймворком. Это либо должно бытьListText блок, чтобы он автоматически отображал все свои дочерние элементы, или Templateс указанным файлом шаблона. На самом деле я решил слишком вложить свой реальный блок вListText блок, чтобы сохранить тот же механизм доступным, что и в frontend area (т.е. для совместимости с другими плагинами, которые могут делать то же самое).

пример

В пользовательском модуле или теме добавьте обновление макета, которое вставляет следующий блок в body макета страницы (это просто делается так же, как это делается в ядре Magento 2 для frontend площадь):

<body>
    <block class="Magento\Framework\View\Element\Text\ListText" name="head.additional">
        <block name="your_block" class="Magento\Framework\View\Element\Template" template="Your_Module::your/template.phtml" />
    </block>
</body>

Выполнено! Ваш шаблон будет отображаться внутри<head></head> - без каких-либо неудобных переопределений или "взломов".

Более того, если другие модули также ссылаются на head.additional в adminhtml области, они будут совместимы с вашим кодом.

Другие вопросы по тегам