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
области, они будут совместимы с вашим кодом.