Magento 2:在 head 标签之后添加自定义脚本
Magento 2 : Add custom script just after head tag
我想在 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 标记结束前使用添加脚本。
请检查下面的代码
阻止 => Custom/Module/Block/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;
}
}
助手 => 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>
布局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>
模板 => Custom/Module/view/frontend/templates/success/head.phtml
<script>
console.log("I'm loaded!");
</script>
请帮我解决这个问题
提前致谢。
我不确定这是否正确,但我有线索。
默认情况下,magento 2 使用 root.phtml
文件相应地设置 head
内容,它位于 vendor/magento/module-theme/view/base/templates/root.phtml
中(如果它没有被覆盖)。
这里,$requireJs
变量首先加载到 head 块中。 $requireJs
变量在 Page
class 中的 render
方法中定义 - 它位于 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
主题中的现有功能而无需 override/intercept 任何东西。
背景
就像@sanchit-gupta提到的那样,root.phtml
模板被用作渲染frontend
和adminhtml
区域的基础,相关的class \Magento\Framework\View\Result\Page
,它总是在渲染之前寻找名为 head.additional
的块。
此块默认存在于 frontend
布局中,但不幸的是它不存在于 adminhtml
布局中。
解决方案
考虑到这一点,将内联 <scripts>
添加到 adminhtml
的 <head>
部分的当前最佳方法(从 2.3.x 开始)是添加任何 head.additional
块:它将由框架自动呈现。它要么必须是一个 ListText
块以便自动呈现它的所有子项,要么是一个具有指定模板文件的 Template
。我实际上选择将我的实际块嵌套在 ListText
块中,只是为了保持与 frontend
区域中相同的机制可用(即为了与可能做同样事情的其他插件兼容)。
例子
在您的自定义模块或主题中,添加一个布局更新,将以下块插入到页面布局的 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>
内呈现——没有任何笨拙的覆盖或 "hacks".
更重要的是,如果其他模块在adminhtml
区域中也引用了head.additional
,它们将与您的代码兼容。
我想在 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 标记结束前使用添加脚本。
请检查下面的代码
阻止 => Custom/Module/Block/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;
}
}
助手 => 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>
布局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>
模板 => Custom/Module/view/frontend/templates/success/head.phtml
<script>
console.log("I'm loaded!");
</script>
请帮我解决这个问题
提前致谢。
我不确定这是否正确,但我有线索。
默认情况下,magento 2 使用 root.phtml
文件相应地设置 head
内容,它位于 vendor/magento/module-theme/view/base/templates/root.phtml
中(如果它没有被覆盖)。
这里,$requireJs
变量首先加载到 head 块中。 $requireJs
变量在 Page
class 中的 render
方法中定义 - 它位于 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
主题中的现有功能而无需 override/intercept 任何东西。
背景
就像@sanchit-gupta提到的那样,root.phtml
模板被用作渲染frontend
和adminhtml
区域的基础,相关的class \Magento\Framework\View\Result\Page
,它总是在渲染之前寻找名为 head.additional
的块。
此块默认存在于 frontend
布局中,但不幸的是它不存在于 adminhtml
布局中。
解决方案
考虑到这一点,将内联 <scripts>
添加到 adminhtml
的 <head>
部分的当前最佳方法(从 2.3.x 开始)是添加任何 head.additional
块:它将由框架自动呈现。它要么必须是一个 ListText
块以便自动呈现它的所有子项,要么是一个具有指定模板文件的 Template
。我实际上选择将我的实际块嵌套在 ListText
块中,只是为了保持与 frontend
区域中相同的机制可用(即为了与可能做同样事情的其他插件兼容)。
例子
在您的自定义模块或主题中,添加一个布局更新,将以下块插入到页面布局的 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>
内呈现——没有任何笨拙的覆盖或 "hacks".
更重要的是,如果其他模块在adminhtml
区域中也引用了head.additional
,它们将与您的代码兼容。