Magento 2:在 head 标签之后添加自定义脚本

Posted

技术标签:

【中文标题】Magento 2:在 head 标签之后添加自定义脚本【英文标题】:Magento 2 : Add custom script just after head tag 【发布时间】:2018-06-18 10:48:48 【问题描述】:

我想在 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标签结束前使用了add脚本。

请检查以下代码

块 => 自定义/模块/块/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>

布局 XML => 自定义/模块/视图/前端/布局/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】:

我发现了一种看起来非常合理的简单方法,因为它使用了adminhtml 主题中的现有功能,而无需覆盖/拦截任何内容。

背景

就像@sanchit-gupta 提到的,root.phtml 模板被用作渲染frontendadminhtml 区域的基础,关联类\Magento\Framework\View\Result\Page 也是如此,它总是寻找一个名为head.additional 渲染前。

此块默认存在于frontend 布局中,但不幸的是它不存在于adminhtml 布局中。

解决方案

考虑到这一点,当前将内联 &lt;scripts&gt; 添加到 adminhtml&lt;head&gt; 部分的最佳方式(从 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>

完成!您的模板将在 &lt;head&gt;&lt;/head&gt; 内呈现 - 没有任何尴尬的覆盖或“黑客”。

更重要的是,如果其他模块在adminhtml 区域中也引用了head.additional,它们将与您的代码兼容。

【讨论】:

【参考方案2】:

我不确定这是否正确,但我有线索。

默认情况下,magento 2 使用root.phtml 文件来相应地设置head 内容,该内容位于vendor/magento/module-theme/view/base/templates/root.phtml 中(如果它没有被覆盖)。

这里,$requireJs 变量首先加载到 head 块中。 $requireJs 变量是在 Page 类中的 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.phtmlvendor/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>

【讨论】:

感谢重播, 但我不想在 require_js.phtml 和 root.phtml 中添加脚本,因为我没有添加自定义主题,所以这是我的自定义模块。 @SandipDutt !请检查更新的答案是否对您有帮助? @SandipDutt 您能否分享您的代码以便更好地理解? 好的,但是当我在 default.xml 中添加您的解决方案时,它会出现错误,例如操作集模板的无效方法 Magento\Framework\View\Element\Template 您可以在这里分享您的代码吗?

以上是关于Magento 2:在 head 标签之后添加自定义脚本的主要内容,如果未能解决你的问题,请参考以下文章

Magento 在哪里添加谷歌再营销标签

Magento2 为产品图片添加动态背景

Magento添加分层导航

Magento 2 - 如何在 Fotorama JS 中替换 webP 图像

Magento:合并产品描述和添加信息选项卡

Magento 2:在产品缺货后切换“已售”标签的价格