文章列表


Magento 2小部件–相册小部件应用–客户推荐展示

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>继我们之前关于Magento图库小部件的文章(其中我们解释了如何构建图像库)之后,我们想展示这个小部件的另一种可能用途。因为它基于Fotorama插件,所以画廊小部件不仅可以处理图像,还可以处理其他HTML内容。我们将通过构建客户推荐库来演示如何,我们将在网店的页脚中显示该库。</p><p>我们需要的第一件事是带有实际推荐的 HTML。我们可以选择两个地方之一来存储我们的HTML内容。</p><p><span style="color: #6a9955;">### 模板文件中的库内容</span></p><p>构建推荐滑块的一种方法是将所有 HTML 标记放在一个模板文件中<span style="color: #6a9955;">;我们可以命名它.为了便于编辑和自定义,我们还将调用图库小部件的脚本放在同一个文件中,因此我们的模板将具有以下代码:client-testimonials.phtml</span></p><pre class="brush:bash;toolbar:false">&lt;--&nbsp;Container&nbsp;for&nbsp;testimonials&nbsp;--&gt; &lt;ul&nbsp;class=&quot;testimonials&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;li&gt;Testimonial&nbsp;#1&lt;/li&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;li&gt;Testimonial&nbsp;#2&lt;/li&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;li&gt;Testimonial&nbsp;#3&lt;/li&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;li&gt;...&lt;/li&gt; &lt;/ul&gt; &lt;--&nbsp;Script&nbsp;that&nbsp;calls&nbsp;gallery&nbsp;widget&nbsp;--&gt; &lt;script&gt; require&nbsp;([ &#39;jquery&#39;, &#39;mage/gallery/gallery&#39; ],&nbsp;function&nbsp;($,&nbsp;Gallery)&nbsp;{ &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;$(function&nbsp;()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;parse&nbsp;HTML&nbsp;to&nbsp;get&nbsp;client&nbsp;testimonials&nbsp;in&nbsp;array&nbsp;of&nbsp;objects &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;testimonialsList&nbsp;=&nbsp;document.querySelectorAll(&quot;.testimonials&nbsp;li&quot;); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;data&nbsp;=&nbsp;[]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;i; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;testimonialsList.length;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;obj&nbsp;=&nbsp;{&nbsp;html:&nbsp;testimonialsList[i].outerHTML}; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data.push(obj); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#39;.testimonials&#39;)&nbsp;//&nbsp;we&nbsp;expect&nbsp;that&nbsp;page&nbsp;contains&nbsp;markup&nbsp;tag&nbsp;with&nbsp;class&nbsp;.testimonials &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.each(function&nbsp;(index,&nbsp;element)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gallery({ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;options:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;nav&quot;:&nbsp;&quot;dots&quot;, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data:&nbsp;data,&nbsp;//&nbsp;contains&nbsp;previously&nbsp;parsed&nbsp;testimonials &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fullscreen:&nbsp;{} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;element);&nbsp;//&nbsp;&#39;element&#39;&nbsp;is&nbsp;simgle&nbsp;DOM&nbsp;node. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;}); }); &lt;/script&gt;</pre><p>在上面的代码中,与我们上一篇文章相比,图片库的唯一区别是组的内容。与图像库不同,其中组指定图像的路径,这里的组包含我们之前解析并保存在数组中的HTML内容(作为对象数组)。datadatadatadata</p><p>由于我们已经提到我们希望推荐显示在网站页脚中,因此我们将文件放在主题的文件夹中,并通过内部文件夹引用它:testimonials.phtmlMagento_Theme/templatedefault.xmlMagento_Theme/layout</p><pre class="brush:bash;toolbar:false">&lt;referenceContainer&nbsp;name=&quot;footer-container&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;block&nbsp;class=&quot;Magento\Framework\View\Element\Template&quot;&nbsp;name=&quot;testimonials&quot;&nbsp;template=&quot;Magento_Cms::testimonials.phtml&quot;&nbsp;before=&quot;-&quot;&gt;&lt;/block&gt; &lt;/referenceContainer&gt;</pre><p>对于初学者,我们需要将我们的 HTML 标记(从)复制/粘贴到我们的静态块中。至于javascript,我们建议不要将其放在静态块中,因为js脚本中的非自愿和意外更改或拼写错误可能会破坏整个图库。这就是为什么最好将javascript保存为我们主题文件夹中的单独文件并声明它是使用requireJs的配置文件的原因。</p><pre class="brush:bash;toolbar:false">testimonials.phtmlweb/jsrequirejs-config.js var&nbsp;config&nbsp;=&nbsp;{ &nbsp;&nbsp;&quot;map&quot;:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&quot;*&quot;:&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;testimonials&quot;:&nbsp;&quot;js/testimonials&quot;, &nbsp;&nbsp;&nbsp;&nbsp;}, &nbsp;&nbsp;}, };</pre><p>但是,我们仍然需要在静态块中调用脚本,而Magento 2的方法是使用以下属性:data-mage-init</p><pre class="brush:bash;toolbar:false">&lt;ul&nbsp;class=&quot;testimonials&quot;&nbsp;data-mage-init=&#39;{&quot;testimonials&quot;:{}}&#39;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;Client&nbsp;testimonials&nbsp;--&gt; &lt;/ul&gt;</pre><p>我们快完成了。在最后一步中,我们需要更新布局文件中的说明,因为我们正在调用静态块而不是模板文件,该文件不再有用,可以从我们的代码库中删除:default.xml</p><pre class="brush:bash;toolbar:false">&lt;referenceContainer&nbsp;name=“footer-container&quot;&gt; &nbsp;&nbsp;&lt;block&nbsp;class=&quot;Magento\Cms\Block\Block&quot;&nbsp;name=&quot;testimonials&quot;&nbsp;before=&quot;-&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;arguments&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;argument&nbsp;name=&quot;block_id&quot;&nbsp;xsi:type=“string&quot;&gt;testimonials&lt;/argument&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;/arguments&gt; &nbsp;&nbsp;&nbsp;&lt;/block&gt; &lt;/referenceContainer&gt;</pre><p>至于功能,我们的内容库已经完成。剩下要做的就是参考网站的风格指南并开始使用 (s)css 来添加一些样式并在视觉上增强它。</p><p><span style="color: #6a9955;">### 总结</span></p><p>希望在这个关于Magento画廊小部件的迷你两部分系列中,我们为您提供了足够的输入来构建自己的画廊,图像或HTML内容的天气。正如我们已经提到的,小部件基于Fotorama插件,因此继承了它的所有优点和缺点。</p><p>我们认为使用此小部件的最大缺点是它仅限于每张幻灯片的一个项目(图像)。另外值得注意的是,Fotorama插件不再被维护,Magento团队可能会决定在未来的软件版本中放弃使用它,并在其他插件上构建他们的画廊小部件。</p><p>但是,目前,此小部件可以安全使用<span style="color: #6a9955;">;如果不在生产阶段,则处于开发阶段,以便于原型设计和布局试验。</span></p>

如何在Magento 2结帐(结算)页面中显示CMS内容

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>使用CMS块是Magento过去和现在如此受欢迎的原因之一。使用 CMS 块,站点管理员可以轻松操作商店的内容。CMS块可用于显示促销横幅,销售块,退货政策,商店某些部分的重要信息消息等。 CMS块可以携带纯文本或HTML / JS/CSS代码块,这意味着它们可以用于更复杂的内容交付,如滑块,产品轮播等。</p><p>我个人喜欢尽可能使用CMS块,以便商店的内容变得更加“模块化”且易于管理。</p><p>结账时的CMS块可以有很多用途,例如显示某些促销内容的特定运输方式的一些信息,以说服用户在结帐前花费更多。</p><p>将CMS块添加到某些特定位置/页面并不麻烦,我们只需要在布局中“注册”我们的CMS块并定义CMS块的顺序/位置。然后我们需要在模板中调用它,仅此而已。CMS 块现在是内容的一部分,将在需要时呈现/交付。</p><p>将CMS块添加到Magento 2 Checkout是一项更复杂的任务,因为整个结帐是由一系列KnockoutJS组件构建的,然后使用Knockout.js模板系统进行渲染。Magento 2在一个大型XML文件中定义了这些组件及其相互关系。为了从服务器中提取数据,Magento使用全局Javascript变量window.checkoutConfig,然后由Knockout使用.js在前端计算和显示信息。</p><p>简而言之,整个结帐是动态加载的,我们不能在里面放任何“静态”的东西。</p><p>希望有一种方法可以在结帐流程中插入CMS块。</p><p>由于整个结帐是从各种JS组件捆绑而来的,因此此任务的方法将根据CMS块位置而有所不同。但是,每种方法都有相同的初始步骤。</p><p>想法是从CMS块中获取内容并将其放入JS对象中,然后通过挖空绑定输出到前端。这样,我们的 CMS 内容就会成为结帐流程的一部分,并与其他组件一起加载。如果您想与组件一起闲逛,请充当组件!</p><p><span style="color: #6a9955;">### 创建模块</span></p><p>如果您不知道如何创建Magento 2模块,请按照我的同事Hrvoje Ivancic的这篇文章中的步骤进行操作。</p><p>我建议您使用 netz98 magerun CLI 工具扩展,这是开发过程中的有用资产。例如,您可以使用一个命令创建一个包含所有必要文件的模块。</p><p>根据需要命名模块。我将使用供应商作为供应商,使用模块名称作为模块名称。</p><p>创建包含所有必要文件的模块后,我们将添加/编辑其中的一些文件以实现我们的目标。</p><p>请不要忘记在创建模块后进行设置:升级。</p><p>在结帐侧边栏中添加 CMS 块</p><p>编辑Vendor/ModuleName/etc/frontend/di.xml文件:</p><pre class="brush:bash;toolbar:false">&lt;?xml&nbsp;version=&quot;1.0&quot;?&gt; &lt;config&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xsi:noNamespaceSchemaLocation=&quot;urn:magento:framework:ObjectManager/etc/config.xsd&quot;&gt; &nbsp;&nbsp;&nbsp;&lt;type&nbsp;name=&quot;Magento\Checkout\Model\CompositeConfigProvider&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;arguments&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;argument&nbsp;name=&quot;configProviders&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;cms_block_config_provider&quot;&nbsp;xsi:type=&quot;object&quot;&gt;Vendor\ModuleName\Model\ConfigProvider&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/argument&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/arguments&gt; &nbsp;&nbsp;&nbsp;&lt;/type&gt; &nbsp;&nbsp;&nbsp;&lt;type&nbsp;name=&quot;Vendor\ModuleName\Model\ConfigProvider&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;arguments&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;argument&nbsp;name=&quot;blockId&quot;&nbsp;xsi:type=&quot;string&quot;&gt;checkout_cms_block&lt;/argument&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/arguments&gt; &nbsp;&nbsp;&nbsp;&lt;/type&gt; &lt;/config&gt;</pre><p>使用此代码,我们将向 ConfigProvider 添加新条目,并且我们还声明了将用于解析数据的 CMS 块。</p><p>在上面的例子中,一个块被命名为“checkout_cms_block”(它与块的id或标识符一起工作)。</p><p>请确保 和 路径与您的块名称匹配。在上面的示例中,路径是供应商\模块名称\模型\配置提供者。</p><p>接下来,我们将通过创建或编辑Vendor/ModuleName/Model/ConfigProvider.php来为配置提供程序创建新条目:</p><pre class="brush:bash;toolbar:false">&lt;?php&nbsp;namespace&nbsp;Vendor\ModuleName\Model; &nbsp; use&nbsp;Magento\Checkout\Model\ConfigProviderInterface; use&nbsp;Magento\Framework\View\LayoutInterface; &nbsp; class&nbsp;ConfigProvider&nbsp;implements&nbsp;ConfigProviderInterface { &nbsp;&nbsp;&nbsp;/**&nbsp;@var&nbsp;LayoutInterface&nbsp;&nbsp;*/ &nbsp;&nbsp;&nbsp;protected&nbsp;$_layout; &nbsp;&nbsp;&nbsp;protected&nbsp;$cmsBlock; &nbsp; &nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;__construct(LayoutInterface&nbsp;$layout,&nbsp;$blockId) &nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_layout&nbsp;=&nbsp;$layout; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;cmsBlock&nbsp;=&nbsp;$this-&gt;constructBlock($blockId); &nbsp;&nbsp;&nbsp;} &nbsp; &nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;constructBlock($blockId){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$block&nbsp;=&nbsp;$this-&gt;_layout-&gt;createBlock(&#39;Magento\Cms\Block\Block&#39;) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;setBlockId($blockId)-&gt;toHtml(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;$block; &nbsp;&nbsp;&nbsp;} &nbsp; &nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;getConfig() &nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;cms_block&#39;&nbsp;=&gt;&nbsp;$this-&gt;cmsBlock &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]; &nbsp;&nbsp;&nbsp;} }</pre><p>由于我们已将自己的变量添加到全局 window.checkoutConfig 变量中,我们现在可以使用window.checkoutConfig.cms_block变量调用该内容。</p><p>现在我们只需要将该变量绑定到某个 HTML 元素,Knockout .JS 将完成剩下的工作。</p><p>这是 app/design/frontend/Vendor/ThemeName/Magento_Checkout/web/template/sidebar.html</p><p><br/></p><pre class="brush:bash;toolbar:false">&lt;div&nbsp;id=&quot;opc-sidebar&quot; &nbsp;&nbsp;&nbsp;&nbsp;data-bind=&quot;afterRender:setModalElement,&nbsp;mageInit:&nbsp;{ &nbsp;&nbsp;&nbsp;&#39;Magento_Ui/js/modal/modal&#39;:{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;type&#39;:&nbsp;&#39;custom&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;modalClass&#39;:&nbsp;&#39;opc-sidebar&nbsp;opc-summary-wrapper&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;wrapperClass&#39;:&nbsp;&#39;checkout-container&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;parentModalClass&#39;:&nbsp;&#39;_has-modal-custom&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;responsive&#39;:&nbsp;true, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;responsiveClass&#39;:&nbsp;&#39;custom-slide&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;overlayClass&#39;:&nbsp;&#39;modal-custom-overlay&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;buttons&#39;:&nbsp;[] &nbsp;&nbsp;&nbsp;}}&quot;&gt; &nbsp; &nbsp;&nbsp;&nbsp;&lt;!--&nbsp;ko&nbsp;foreach:&nbsp;getRegion(&#39;summary&#39;)&nbsp;--&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;ko&nbsp;template:&nbsp;getTemplate()&nbsp;--&gt;&lt;!--&nbsp;/ko&nbsp;--&gt; &nbsp;&nbsp;&nbsp;&lt;!--/ko--&gt; &nbsp; &nbsp;&nbsp;&nbsp;&lt;div&nbsp;data-bind=&quot;html:&nbsp;window.checkoutConfig.cms_block&quot;&gt;&lt;/div&gt; &nbsp; &nbsp;&nbsp;&nbsp;&lt;div&nbsp;class=&quot;opc-block-shipping-information&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;ko&nbsp;foreach:&nbsp;getRegion(&#39;shipping-information&#39;)&nbsp;--&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;ko&nbsp;template:&nbsp;getTemplate()&nbsp;--&gt;&lt;!--&nbsp;/ko&nbsp;--&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--/ko--&gt; &nbsp;&nbsp;&nbsp;&lt;/div&gt; &lt;/div&gt;</pre><p>如果您做对了一切,您应该会在侧边栏中看到您的 CMS 块。</p><p>请注意,我已经在我的包/主题中创建了sidebar.html模板。切勿直接在Vendor/magento/* 文件夹中编辑文件。</p><p><span style="color: #6a9955;">### 将 CMS 块添加到地址表单</span></p><p>对于此任务,我们将使用一些不同的方法。</p><p>我们将app/code/Vendor/ModuleName/Model/ConfigProvider.php</p><p>更改为:</p><pre class="brush:bash;toolbar:false">&lt;?php &nbsp; namespace&nbsp;Vendor\ModuleName\Model; &nbsp; &nbsp; use&nbsp;Magento\Checkout\Model\ConfigProviderInterface; use&nbsp;Magento\Cms\Block\Widget\Block; &nbsp; class&nbsp;ConfigProvider&nbsp;implements&nbsp;ConfigProviderInterface { &nbsp;&nbsp;&nbsp;protected&nbsp;$cmsBlockWidget; &nbsp; &nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;__construct(Block&nbsp;$block,&nbsp;$blockId) &nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;cmsBlockWidget&nbsp;=&nbsp;$block; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$block-&gt;setData(&#39;block_id&#39;,&nbsp;$blockId); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$block-&gt;setTemplate(&#39;Magento_Cms::widget/static_block/default.phtml&#39;); &nbsp;&nbsp;&nbsp;} &nbsp; &nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;getConfig() &nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;cms_block&#39;&nbsp;=&gt;&nbsp;$this-&gt;cmsBlockWidget-&gt;toHtml() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]; &nbsp;&nbsp;&nbsp;} }</pre><p>然后,</p><p>使用以下内容创建应用/code/Vendor/ModuleName/view/frontend/layout/checkout_index_index.xml:</p><pre class="brush:bash;toolbar:false">&lt;?xml&nbsp;version=&quot;1.0&quot;?&gt; &nbsp; &lt;page&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&nbsp;layout=&quot;checkout&quot;&nbsp;xsi:noNamespaceSchemaLocation=&quot;urn:magento:framework:View/Layout/etc/page_configuration.xsd&quot;&gt; &nbsp;&nbsp;&nbsp;&lt;body&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;referenceBlock&nbsp;name=&quot;checkout.root&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;arguments&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;argument&nbsp;name=&quot;jsLayout&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;components&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;checkout&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;children&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;steps&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;children&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;shipping-step&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;children&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;shippingAddress&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;children&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;shipping-address-fieldset&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;children&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;cms-block&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;component&quot;&nbsp;xsi:type=&quot;string&quot;&gt;uiComponent&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;config&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;template&quot;&nbsp;xsi:type=&quot;string&quot;&gt;Vendor_ModuleName/cms-block&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;sortOrder&quot;&nbsp;xsi:type=&quot;string&quot;&gt;1&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/argument&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/arguments&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/referenceBlock&gt; &nbsp;&nbsp;&nbsp;&lt;/body&gt; &lt;/page&gt;</pre><p>现在,我们已将新的 UI 组件添加到地址窗体中。该组件将保存我们的 CMS 块的内容。正如我上面提到的,组件加载顺序在XML文件中管理。如您所见,我已经为 sortOrder 设置了 1,这意味着我的组件将首先加载到地址表单中。</p><p>注意此行Vendor_ModuleName/cms-block并更改它。</p><p>现在我们已经设置好了一切,我们只需要一个挖空模板来输出 CMS 块数据。</p><p>使用此内容创建 app/code/Vendor/ModuleName/view/frontend/web/template/cms-block.html:</p><pre class="brush:bash;toolbar:false">&lt;div&nbsp;data-bind=&quot;html:&nbsp;window.checkoutConfig.cms_block&quot;&gt;&lt;/div&gt;</pre><p>仅此而已。现在,您的CMS块应以地址形式显示并首先呈现。<br/></p><p>给定的示例适用于干净的Magento 2.2安装。Luma主题用于测试目的。</p><p>如果出现问题,请检查:</p><p>您的模块是否正确创建并包含所有具有正确值的配置文件?</p><p>您是否在创建模块后运行了PHP bin/magento setup:upgrade?</p><p>通过将Vendor/ModuleName替换为正确的供应商和模块名称来检查您是否正确更改了本文中的代码!</p><p><br/></p>

在Magento 2中购物结算页面的运费计算页面的字段排序

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>随着时间的流逝,我们越来越熟悉Magento 2结帐。我们正在努力进一步建立我们的知识。希望本文能在此过程中为您提供帮助。在本文中,我们将学习如何更改结帐页面上的输入字段顺序。</p><p>如果您曾经测试过Magento 2,那么您熟悉默认的Magento 2 Checkout和默认字段的排序顺序。</p><p>对于美国或其他一些国家/地区(州/省是重要且必填字段)的地址,此顺序是完全可以理解的。但在大多数欧洲国家,州/省字段并不重要。在这里,大多数欧盟客户期望其他一些字段,例如此处邮政编码或国家/地区具有更高的优先级。</p><p>请记住,我们希望更改默认的Magento结帐字段排序顺序以满足我们的需求。因此,我们的目标是实现这一目标:</p><p>此外,我们希望保持一致性,考虑了所有结帐步骤,因此我们将对运输和计费步骤中的输入字段重新排序。</p><p><span style="color: #6a9955;">### 运输步骤</span></p><p>在运输步骤中重新排序字段是一项简单的任务,我们只需要知道相关字段的排序顺序值和一些xml Magento 2特定命令。</p><p>首先,我们需要有自己的布局覆盖。如果您没有它,请创建新的xml文件,以便我们可以以正确的Magento方式操作结帐布局。文件需要位于以下路径上:checkout_index_indexcheckout_index_index</p><p>/app/design/frontend/Vendor/themeName/Magento_Checkout/layout/checkout_index_index.xml</p><p>新的布局文件需要具有结构清晰的树,以便定位正确的元素 Checkout UI 组件,如下所示:</p><pre class="brush:bash;toolbar:false">&lt;referenceBlock&nbsp;name=&quot;checkout.root&quot;&gt; &lt;arguments&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument&nbsp;name=&quot;jsLayout&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;components&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;checkout&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;children&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;steps&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;children&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;shipping-step&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;children&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;shippingAddress&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;children&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;The&nbsp;name&nbsp;of&nbsp;the&nbsp;form&nbsp;the&nbsp;field&nbsp;belongs&nbsp;to&nbsp;--&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;shipping-address-fieldset&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;children&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!—&nbsp;Start:&nbsp;Important&nbsp;part&nbsp;—&gt; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;postcode&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;sortOrder&quot;&nbsp;xsi:type=&quot;string&quot;&gt;71&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;country_id&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;sortOrder&quot;&nbsp;xsi:type=&quot;string&quot;&gt;81&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!—&nbsp;End:&nbsp;Important&nbsp;part:&nbsp;—&gt; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;/argument&gt; &lt;/arguments&gt; &lt;/referenceBlock&gt;</pre><p>有很多嵌套和很多子元素。但是在该项目下,我们针对两个表示输入字段的子元素。如果您仔细观察,您会注意到我们试图定位:shippingAddress</p><p><span style="color: #6a9955;">### 邮政编码字段 (postcode)</span></p><p>提交的国家 (country_id)</p><p>为了改变这些元素(邮政编码和国家/地区)的位置,我们需要用适合我们的想法的值更新值,以便更好地排序。默认情况下,sortOrder 值为 110,值为 115。我们已经用 71 和 81 更新了它们,在这种情况下,目标字段将很好地适应我们的新布局。sortOrderingpostcodecountry_id</p><p>清除您的Magento缓存。重新加载结帐页面,您会注意到更改。</p><p>我们还需要指出的是,XML布局更新也会影响结帐地址弹出窗口,当注册客户希望在第一个结帐步骤中使用现有地址添加新地址时,该弹出窗口将可见。</p><p>现在让我们调整计费步骤。</p><p><span style="color: #6a9955;">### 计费步骤</span></p><p>更改计费步骤请求不同的方法,然后是运输步骤。原因是计费步骤建立在动态 UI 组件上。目前,这里要知道的最重要的事情是,在计费步骤中,每种付款方式使用不同的计费地址表单(每种付款方式的不同组件)。因此,考虑到这一点,我们需要对结帐时使用的所有付款方式应用布局更改。但出于本文的目的,我们将只介绍支票/货币付款方式。</p><p>我们将通过扩展计费步骤的默认Magento布局处理器接口来做到这一点。这将需要一些 PHP 后端调整。但考虑到必要的工作水平,做起来不会太复杂。请通过在签出、块目录下创建新的 PHP 类文件来扩展:LayoutProcessorInterface</p><p>/app/code/Vendor/Checkout/Block/LayoutProcessor.php</p><p>对于我们的起点将使用简单的函数检查:</p><p><br/></p><pre class="brush:bash;toolbar:false">namespace&nbsp;Inchoo\Checkout\Block; use&nbsp;Magento\Checkout\Block\Checkout\LayoutProcessorInterface; &nbsp; class&nbsp;LayoutProcessor&nbsp;implements&nbsp;LayoutProcessorInterface { &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;process($jsLayout) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;$jsLayout; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre><p>此外,我们需要为配置创建,以便Magento了解布局处理器更改。XML 文件将包含以下代码:di.xml</p><pre class="brush:bash;toolbar:false">&lt;?xml&nbsp;version=&quot;1.0&quot;?&gt; &lt;config&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&nbsp;xsi:noNamespaceSchemaLocation=&quot;urn:magento:framework:ObjectManager/etc/config.xsd&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;type&nbsp;name=&quot;Magento\Checkout\Block\Onepage&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;arguments&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;argument&nbsp;name=&quot;layoutProcessors&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;checkoutFieldsReorder&quot;&nbsp;xsi:type=&quot;object&quot;&gt;Inchoo\Checkout\Block\LayoutProcessor&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/argument&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/arguments&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;/type&gt; &lt;/config&gt;</pre><p>我们需要确保在计费步骤中定位正确的 UI 组件。为此,请检查Magento敲除在前端给我们的JSON对象。您可以通过 IDE 或某些 JSON 在线编辑器执行此操作。在结帐 JSON 中查找要重新定位的元素的值。在 JSON 树之后,我们将声明数组的相同路径。所以基本上,我们将这样做:sortOrder$jsLayout</p><pre class="brush:bash;toolbar:false">namespace&nbsp;Inchoo\Checkout\Block; use&nbsp;Magento\Checkout\Block\Checkout\LayoutProcessorInterface; class&nbsp;LayoutProcessor&nbsp;implements&nbsp;LayoutProcessorInterface { &nbsp;&nbsp;&nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Reposition&nbsp;postcode&nbsp;to&nbsp;be&nbsp;above&nbsp;city&nbsp;input,&nbsp;and&nbsp;country&nbsp;drop&nbsp;down&nbsp;to&nbsp;be&nbsp;above&nbsp;region &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;array&nbsp;$jsLayout &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;array &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;process($jsLayout) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$jsLayout[&#39;components&#39;][&#39;checkout&#39;][&#39;children&#39;][&#39;steps&#39;][&#39;children&#39;] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&#39;billing-step&#39;][&#39;children&#39;][&#39;payment&#39;][&#39;children&#39;] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&#39;payments-list&#39;][&#39;children&#39;][&#39;checkmo-form&#39;][&#39;children&#39;] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&#39;form-fields&#39;][&#39;children&#39;][&#39;postcode&#39;][&#39;sortOrder&#39;]&nbsp;=&nbsp;71; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$jsLayout[&#39;components&#39;][&#39;checkout&#39;][&#39;children&#39;][&#39;steps&#39;][&#39;children&#39;] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&#39;billing-step&#39;][&#39;children&#39;][&#39;payment&#39;][&#39;children&#39;] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&#39;payments-list&#39;][&#39;children&#39;][&#39;checkmo-form&#39;][&#39;children&#39;] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[&#39;form-fields&#39;][&#39;children&#39;][&#39;country_id&#39;][&#39;sortOrder&#39;]&nbsp;=&nbsp;81; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;$jsLayout; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre><p>清除缓存并重新加载页面。您将看到更改。</p><p>如果您想更改其他方法的布局,请随时执行此操作。您只需要更换为您的付款方式即可。但请确保您在结帐时使用哪种方法。至少检查您的 JSON 对象以及您的项目下可用的表单。这样做的原因是有时可能看起来像这样:[<span style="color: #ce9178;">&#39;checkmo-form&#39;</span>]payment-listpayment-list</p><p>因此,很难猜测我们需要针对哪种形式。</p><p><br/></p><p><br/></p>

magento2如何将自定义的列添加到后台产品列表页中展示

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>如果要在列中显示的值是产品属性,则可以轻松地向产品网格添加列。它们已存在于列控件下的产品网格工具栏中。您只需选中/取消选中要从网格中显示或删除的列。但是,如果您想显示不是产品属性的数量和网站等值,该怎么办?如果您继续阅读,您将学习如何将这样的值添加到产品网格中。</p><p><span style="color: #6a9955;">### 介绍</span></p><p>由于可以为每个产品打开/关闭库存管理,因此我们将向产品网格添加一个新列,该列将在打开或关闭库存管理时显示。 对于所有代码示例,我创建了一个名为 Inchoo_Custom 的 Magento 2 模块。</p><p>如果你想学习如何创建一个Magento 2模块,你可以检查这个:如何在Magento 2中创建基本模块</p><p>重要的是,Magento的Magento_Catalog模块在我们的模块之前加载,这就是为什么我们将它添加到模块.xml文件中的序列标签下。</p><p>app/code/Inchoo/Custom/etc/module.xml</p><pre class="brush:bash;toolbar:false">&lt;?xml&nbsp;version=&quot;1.0&quot;&nbsp;encoding=&quot;utf-8&quot;&nbsp;?&gt; &lt;config&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&nbsp;xsi:noNamespaceSchemaLocation=&quot;urn:magento:framework:Module/etc/module.xsd&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;module&nbsp;name=&quot;Inchoo_Custom&quot;&nbsp;setup_version=&quot;1.0.0&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;sequence&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;module&nbsp;name=&quot;Magento_Catalog&quot;/&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/sequence&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;/module&gt; &lt;/config&gt;</pre><p>编辑模块后.xml我们需要使用控制台命令更新应用程序/etc/config.php文件:</p><p>php bin/magento setup:upgrade</p><p><span style="color: #6a9955;">### 产品列表 UI 组件实例</span></p><p>渲染产品网格Magento 2使用名为product_listing的列表UI组件实例和XML配置文件,因为它是Magento_Catalog/view/adminhtml/ui_component/product_listing.xml。如果我们想自定义它,我们需要在我们的模块中创建一个具有相同路径和名称的文件。</p><p>app/code/Inchoo/Custom/view/adminhtml/ui_component/product_listing.xml</p><pre class="brush:bash;toolbar:false">&lt;?xml&nbsp;version=&quot;1.0&quot;&nbsp;encoding=&quot;utf-8&quot;?&gt; &lt;listing&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&nbsp;xsi:noNamespaceSchemaLocation=&quot;urn:magento:module:Magento_Ui:etc/ui_configuration.xsd&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;columns&nbsp;name=&quot;product_columns&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;column&nbsp;name=&quot;manage_stock&quot;&nbsp;component=&quot;Magento_Ui/js/grid/columns/select&quot;&nbsp;sortOrder=&quot;76&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;settings&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;addField&gt;true&lt;/addField&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;options&nbsp;class=&quot;Magento\Config\Model\Config\Source\Yesno&quot;/&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;filter&gt;select&lt;/filter&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;dataType&gt;select&lt;/dataType&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;sortable&gt;false&lt;/sortable&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;label&nbsp;translate=&quot;true&quot;&gt;Manage&nbsp;Stock&lt;/label&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/settings&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/column&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;/columns&gt; &lt;/listing&gt;</pre><p>要添加新列,我们需要从原始配置文件中引用名为 product_columns 的列 UI 组件,并将新列添加到其中。我们将专栏命名为manage_stock标签“管理库存”。</p><p>运行此控制台命令以清理缓存:</p><p>php bin/magento cache:clean config</p><p>清理缓存后,我们应该在产品网格中看到我们的新列,但数据丢失。这是因为我们没有将库存管理数据添加到产品系列中。</p><p><span style="color: #6a9955;">### 产品列表数据提供程序</span></p><p>将库存管理数据添加到产品集合的最佳位置是 UI 组件实例使用的数据提供程序类product_listing。</p><p>Magento_Catalog/view/adminhtml/ui_component/product_listing.xml</p><pre class="brush:bash;toolbar:false">&lt;dataSource&nbsp;name=&quot;product_listing_data_source&quot;&nbsp;component=&quot;Magento_Ui/js/grid/provider&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;settings&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;storageConfig&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;param&nbsp;name=&quot;dataScope&quot;&nbsp;xsi:type=&quot;string&quot;&gt;filters.store_id&lt;/param&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/storageConfig&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;updateUrl&nbsp;path=&quot;mui/index/render&quot;/&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;/settings&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;aclResource&gt;Magento_Catalog::products&lt;/aclResource&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;dataProvider&nbsp;class=&quot;Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider&quot;&nbsp;name=&quot;product_listing_data_source&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;settings&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;requestFieldName&gt;id&lt;/requestFieldName&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;primaryFieldName&gt;entity_id&lt;/primaryFieldName&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/settings&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;/dataProvider&gt; &lt;/dataSource&gt;</pre><p>如果我们查看 dataSource UI 组件,我们将看到 dataProvider 类是 Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider。</p><p>如果我们查看这个数据提供程序类,我们将看到两个属性 addFieldStrategies 和 addFilterStrategies。它们都是数组,具有我们可以对特定列(字段)的集合执行的其他策略。它们分别在数据提供程序的 addField 和 addFilter 方法中调用。我们将为我们的库存管理专栏创建自己的策略。</p><p><span style="color: #6a9955;">### 管理库存字段策略</span></p><p>首先,我们将创建一个字段策略,将库存管理状态添加到产品系列中。</p><p>Inchoo\Custom\UI\DataProvider\Product\AddManageStockFieldToCollection</p><pre class="brush:bash;toolbar:false">&lt;?php namespace&nbsp;Inchoo\Custom\Ui\DataProvider\Product;&nbsp; class&nbsp;AddManageStockFieldToCollection&nbsp;implements&nbsp;\Magento\Ui\DataProvider\AddFieldToCollectionInterface { &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;addField(\Magento\Framework\Data\Collection&nbsp;$collection,&nbsp;$field,&nbsp;$alias&nbsp;=&nbsp;null) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$collection-&gt;joinField(&#39;manage_stock&#39;,&nbsp;&#39;cataloginventory_stock_item&#39;,&nbsp;&#39;manage_stock&#39;,&nbsp;&#39;product_id=entity_id&#39;,&nbsp;null,&nbsp;&#39;left&#39;);&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre><p>在AddManageStockFieldToCollection字段策略中,我们从Magento\Ui\DataProvider\AddFieldToCollection接口实现了addField方法。库存管理状态来自 DB 表中cataloginventory_stock_item manage_stock列。我们使用这些信息和Magento\Eav\Model\Entity\Collection\AbstractCollection::joinField方法将库存管理状态添加到产品集合中。</p><p><br/></p><p><span style="color: #6a9955;">### 管理库存过滤器策略</span></p><p>当有人想要按库存管理状态过滤网格数据时,我们需要创建此过滤策略。</p><p>Inchoo\Custom\UI\DataProvider\Product\AddManageStockFilterToCollection</p><pre class="brush:bash;toolbar:false">&lt;?php namespace&nbsp;Inchoo\Custom\Ui\DataProvider\Product;&nbsp; class&nbsp;AddManageStockFilterToCollection&nbsp;implements&nbsp;\Magento\Ui\DataProvider\AddFilterToCollectionInterface { &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;addFilter(\Magento\Framework\Data\Collection&nbsp;$collection,&nbsp;$field,&nbsp;$condition&nbsp;=&nbsp;null) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(isset($condition[&#39;eq&#39;]))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$collection-&gt;addFieldToFilter($field,&nbsp;$condition);&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} }</pre><p>在AddManageStockFilterToCollection过滤器策略中,我们实现了来自Magento\Ui\DataProvider\AddFilterToCollectionInterface的addFilter方法。如果网格按库存管理状态过滤,我们将过滤器条件转发到 Magento\Eav\Model\Entity\Collection\AbstractCollection::addFieldToFilter 方法。</p><p><span style="color: #6a9955;">### 向商品信息数据提供程序添加策略</span></p><p>如果我们想使用刚刚创建的策略,我们需要将它们添加到product_listing数据提供程序中。我们将在 di.xml 文件中执行此操作。</p><p>app/code/Inchoo/Custom/etc/adminhtml/di.xml</p><pre class="brush:bash;toolbar:false">&lt;?xml&nbsp;version=&quot;1.0&quot;&nbsp;encoding=&quot;utf-8&quot;&nbsp;?&gt; &lt;config&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&nbsp;xsi:noNamespaceSchemaLocation=&quot;urn:magento:framework:ObjectManager/etc/config.xsd&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;type&nbsp;name=&quot;Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;arguments&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;argument&nbsp;name=&quot;addFieldStrategies&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;manage_stock&quot;&nbsp;xsi:type=&quot;object&quot;&gt;Inchoo\Custom\Ui\DataProvider\Product\AddManageStockFieldToCollection&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/argument&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;argument&nbsp;name=&quot;addFilterStrategies&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;manage_stock&quot;&nbsp;xsi:type=&quot;object&quot;&gt;Inchoo\Custom\Ui\DataProvider\Product\AddManageStockFilterToCollection&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/argument&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/arguments&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;/type&gt; &lt;/config&gt;</pre><p>运行此控制台命令以清理缓存:</p><p>php bin/magento cache:clean config</p><p>清理缓存后,我们应该在产品网格中看到包含数据的新列。</p><p><br/></p><p><img src="/uploads/images/20230821/04b28c15a19cde0d3fae48445a283315.jpg" title="3.jpg" alt=""/></p><p><br/></p>

使用Docker构建的magento2开发环境

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>很久以前,当我第一次开始使用PHP时,我确实在设置工作环境时遇到了麻烦。</p><p>我不知道自己在做什么。</p><p>不要问我怎么做,但我最终让Apache Tomcat运行PHP。</p><p>老实说,我不知道我今天能不能设置这样的亵渎。</p><p><br/></p><p>编辑注意:由于udovicic/echo:</p><p>apache-php7.1更新,你不再需要apache配置,所以我编辑了这篇文章并删除了apache配置。</p><p>多年来,我走了从xampp,手动LAMP设置,流浪汉的整个道路......</p><p>所有这些都至少有1个交易破坏者,特别是当我开始与Magento合作时。</p><p>最后,Docker的到来使开发变得更加容易。</p><p>在这一点上,解释Docker是什么变得有点棘手。</p><p>它执行操作系统级虚拟化(容器化),这是指内核允许存在多个隔离的用户空间实例的操作系统功能。</p><p>如果上面的句子对您没有任何意义,那么也许访问 http://www.docker.com 并在某个时候回到这里是明智的,否则,请继续阅读......</p><p>我现在要分享的不是一些Docker的智慧。它更多的是关于能够通过Docker运行Magento 2的设置,所以本文假设你对Docker有些熟悉。</p><p>所以,让我们开始...</p><p>让我们运行Magento 2,假设 http://m2.docker</p><p>你应该做的第一件事是在 /etc/hosts 文件中的某个位置添加此行:</p><p>127.0.0.1 m2.docker www.m2.docker</p><p>我们将需要一些文件系统结构,因此请执行以下操作:</p><pre class="brush:bash;toolbar:false">tomas&nbsp;~&nbsp;$&nbsp;mkdir&nbsp;m2.docker tomas&nbsp;~&nbsp;$&nbsp;cd&nbsp;m2.docker/ tomas&nbsp;~/m2.docker&nbsp;$&nbsp;mkdir&nbsp;docker tomas&nbsp;~/m2.docker&nbsp;$&nbsp;mkdir&nbsp;html tomas&nbsp;~/m2.docker&nbsp;$&nbsp;mkdir&nbsp;-p&nbsp;docker/db tomas&nbsp;~/m2.docker&nbsp;$&nbsp;touch&nbsp;docker/xdebug.ini tomas&nbsp;~/m2.docker&nbsp;$&nbsp;touch&nbsp;docker/apache.conf tomas&nbsp;~/m2.docker&nbsp;$&nbsp;touch&nbsp;docker-compose.yml tomas&nbsp;~/m2.docker&nbsp;$&nbsp;touch&nbsp;.env</pre><p>现在,让我们逐个来看这些文件文件:</p><p>.env</p><p>在这个文件中,你可以编写将在docker-compose.yml</p><p>中使用的变量,我的看起来像这样:</p><pre class="brush:bash;toolbar:false">CONTAINER_PREFIX=m2docker SERVER_NAME=m2.docker SERVER_ALIAS=www.m2.docker DIRECTORY_NAME=m2.docker WEB_USER=inchoo WEB_ROOT&nbsp;=&nbsp;/var/www/html MYSQL_DB_HOST&nbsp;=&nbsp;${CONTAINER_PREFIX}_db_1 MYSQL_DATABASE=inchoo MYSQL_ROOT_USERNAME=root MYSQL_ROOT_PASSWORD=inchoo MYSQL_USER=inchoo MYSQL_PASSWORD=inchoo DOCKER_EXEC=docker&nbsp;exec DOCKER_EXEC_INTERACTIVE=docker&nbsp;exec&nbsp;-i DOCKER_EXEC_TTY=${DOCKER_EXEC_INTERACTIVE}&nbsp;-t</pre><p>对于docker-compose.yml,您将需要以下代码。</p><p>我还添加了一些带有文档链接的评论。</p><p>请注意,我使用的是我的同事Stjepan创建的apache-php图像,我强烈推荐它进行开发。</p><p><br/></p><pre class="brush:bash;toolbar:false">#&nbsp;https://docs.docker.com/compose/compose-file version:&nbsp;&quot;3.6&quot; &nbsp; #&nbsp;https://docs.docker.com/compose/compose-file/#service-configuration-reference services: &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;#custom&nbsp;name &nbsp;&nbsp;&nbsp;&nbsp;apache-php: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;https://docs.docker.com/compose/compose-file/#image &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;https://githheizenberg&nbsp;ub.com/udovicic/echo&nbsp;=&gt;&nbsp;https://hub.docker.com/r/udovicic/echo/ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;image:&nbsp;udovicic/echo:apache-php7.1 &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;https://docs.docker.com/compose/compose-file/#ports &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ports: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&quot;80:80&quot; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;https://docs.docker.com/compose/compose-file/#expose &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expose: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&quot;9000&quot; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;https://docs.docker.com/compose/compose-file/#volumes &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;volumes: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;./docker/xdebug.ini:/etc/php/7.1/mods-available/xdebug.ini &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;./html:/var/www/html &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;https://docs.docker.com/compose/compose-file/#environment &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;environment: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;TERM=xterm-256color &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;APACHE_RUN_USER=1000 &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;https://docs.docker.com/compose/compose-file/#network-configuration-reference &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;networks: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aliases: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;${SERVER_NAME} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;${SERVER_ALIAS} &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;db: &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;https://hub.docker.com/_/mysql/ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;image:&nbsp;mysql:5.7 &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;volumes: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;./docker/db/data:/var/lib/mysql &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;environment: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MYSQL_ROOT_PASSWORD:&nbsp;${MYSQL_ROOT_PASSWORD} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MYSQL_DATABASE:&nbsp;${MYSQL_DATABASE} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MYSQL_USER:&nbsp;${MYSQL_USER} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MYSQL_PASSWORD:&nbsp;${MYSQL_PASSWORD} &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;redis: &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;https://hub.docker.com/_/redis/ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;image:&nbsp;redis:latest &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;phpmyadmin: &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;https://hub.docker.com/r/phpmyadmin/phpmyadmin/ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;image:&nbsp;phpmyadmin/phpmyadmin &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ports: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&quot;8080:80&quot; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;environment: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MYSQL_USERNAME:&nbsp;${MYSQL_ROOT_USERNAME} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MYSQL_ROOT_PASSWORD:&nbsp;${MYSQL_ROOT_PASSWORD} …and&nbsp;xdebug.ini zend_extension=xdebug.so xdebug.remote_autostart=0 xdebug.remote_enable=1 xdebug.remote_port=9000 xdebug.remote_connect_back=1</pre><p>这一点我们有工作环境,所以让我们尝试运行它:</p><pre class="brush:bash;toolbar:false">tomas&nbsp;~/m2.docker&nbsp;$&nbsp;docker-compose&nbsp;up&nbsp;-d Creating&nbsp;network&nbsp;&quot;m2docker_default&quot;&nbsp;with&nbsp;the&nbsp;default&nbsp;driver Creating&nbsp;m2docker_apache-php_1&nbsp;...&nbsp;done Creating&nbsp;m2docker_redis_1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;done Creating&nbsp;m2docker_phpmyadmin_1&nbsp;...&nbsp;done Creating&nbsp;m2docker_db_1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;done tomas&nbsp;~/m2.docker&nbsp;$&nbsp;docker&nbsp;ps CONTAINER&nbsp;ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IMAGE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COMMAND&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CREATED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STATUS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PORTS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NAMES e3384b0eff8c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mysql:5.7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;docker-entrypoint.s…&quot;&nbsp;&nbsp;&nbsp;3&nbsp;seconds&nbsp;ago&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Up&nbsp;2&nbsp;seconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3306/tcp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m2docker_db_1 d283bf018330&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;phpmyadmin/phpmyadmin&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;/run.sh&nbsp;phpmyadmin&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;seconds&nbsp;ago&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Up&nbsp;2&nbsp;seconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;9000/tcp,&nbsp;0.0.0.0:8080-&gt;80/tcp&nbsp;&nbsp;&nbsp;m2docker_phpmyadmin_1 ded8bce1d993&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redis:latest&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;docker-entrypoint.s…&quot;&nbsp;&nbsp;&nbsp;3&nbsp;seconds&nbsp;ago&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Up&nbsp;2&nbsp;seconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6379/tcp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m2docker_redis_1 fe8a80763ac6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;udovicic/echo:apache-php7.1&nbsp;&nbsp;&nbsp;&quot;/start.sh&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;seconds&nbsp;ago&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Up&nbsp;2&nbsp;seconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.0.0.0:80-&gt;80/tcp,&nbsp;9000/tcp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m2docker_apache-php_1 tomas&nbsp;~/m2.docker&nbsp;$</pre><p>Magento应该安装在“html”目录中。</p><p>请注意,在引用数据库地址时需要使用“db”,依此类推。只需检查docker-compose.yml(服务名称)。</p><p>此外,相关凭据位于 .env 文件中。</p><p>PhpMyAdmin 可用 @ http://m2.docker:8080</p><p>这是一个非常基本的设置。我通常创建 git 存储库,它最初以 2 个分支结束,例如 m2-docker 和 master,然后我将 .git 目录复制到 html 中并签出 master 分支,而在基本目录中我签出 m2-docker 分支。</p><p><br/></p>

magento2.3版本中如何以编程的方式向系统中添加用户

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>有几种方法可以在Magento 2中创建客户。客户可以使用注册表单自行创建帐户,可以通过管理界面创建客户,甚至还有一个内置的Magento 2导入功能,可以从CSV文件中批量导入大量客户,前提是CSV中的客户数据已准备好导入。</p><p>但是,如果我们有成千上万的客户,他们的数据在创建之前仍然需要处理怎么办?执行此操作的最佳方法是以编程方式创建客户。</p><p>在本文中,我们将介绍以编程方式创建客户的主题,为此,我们将创建一个简单的Magento 2模块,</p><p>该模块将具有自定义控制台命令和几个模型,这些模型将用于读取,处理和创建客户。</p><p><span style="color: #6a9955;">### 结构</span></p><p>让我们首先在Magento 2安装的目录中创建一个模块。在此示例中,我将使用 Inchoo 作为模块供应商,并将模块命名为 CustomerCreation,但您可以根据需要命名它们。/app/code</p><p>在我们的模块中,我们将需要以下目录和文件:</p><pre class="brush:bash;toolbar:false">registration.php /etc/module.xml /Console/Command/CreateCustomers.php /etc/di.xml /Model/Customer.php /Model/Import/CustomerImport.php</pre><p>registation.php</p><p>为了使我们的客户创建模块正常工作,我们需要在Magento系统中注册我们的模块。将以下代码复制到文件中:registration.php</p><pre class="brush:bash;toolbar:false">&lt;?php &nbsp; \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, &#39;Inchoo_CustomerCreation&#39;, __DIR__ );</pre><p><span style="color: #6a9955;"></span></p><p><span style="color: #6a9955;">### module.xml</span></p><p>我们的模块还需要声明它的名称和存在。将以下代码复制到文件中:/etc/module.xml</p><p>&lt;?xml <span style="color: #569cd6;">version</span>=<span style="color: #ce9178;">&quot;1.0&quot;</span>?&gt;</p><p><br/></p><pre class="brush:bash;toolbar:false">&lt;config&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&nbsp;xsi:noNamespaceSchemaLocation=&quot;urn:magento:framework:Module/etc/module.xsd&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;module&nbsp;name=&quot;Inchoo_CustomerCreation&quot;&nbsp;setup_version=&quot;1.0.0&quot;&nbsp;/&gt; &lt;/config&gt;</pre><p><span style="color: #6a9955;">### 其它文件</span></p><p>现在我们已经设置了模块,我们需要一种方法来触发我们的客户创建过程。我们可以做到这一点的一种方法是创建自定义控制台命令。</p><p>让我们从在文件中导入一堆类开始,让我们也定义类并使其扩展导入的 Command 类:/Console/Command/CreateCustomers.php</p><pre class="brush:bash;toolbar:false">&lt;?php &nbsp; namespace&nbsp;Inchoo\CustomerCreation\Console\Command; &nbsp; use&nbsp;Exception; use&nbsp;Magento\Framework\App\Filesystem\DirectoryList; use&nbsp;Magento\Framework\Console\Cli; use&nbsp;Magento\Framework\Filesystem; use&nbsp;Magento\Framework\App\State; use&nbsp;Magento\Framework\App\Area; use&nbsp;Symfony\Component\Console\Command\Command; use&nbsp;Symfony\Component\Console\Input\InputInterface; use&nbsp;Symfony\Component\Console\Output\OutputInterface; use&nbsp;Inchoo\CustomerCreation\Model\Customer; &nbsp; class&nbsp;CreateCustomers&nbsp;extends&nbsp;Command { &nbsp;&nbsp;//&nbsp;everything&nbsp;else&nbsp;goes&nbsp;here }</pre><p>方法:</p><pre class="brush:bash;toolbar:false">public&nbsp;function&nbsp;__construct( &nbsp;&nbsp;&nbsp;&nbsp;Filesystem&nbsp;$filesystem, &nbsp;&nbsp;&nbsp;&nbsp;Customer&nbsp;$customer, &nbsp;&nbsp;&nbsp;&nbsp;State&nbsp;$state )&nbsp;{ parent::__construct(); &nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;filesystem&nbsp;=&nbsp;$filesystem; &nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;customer&nbsp;=&nbsp;$customer; &nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;state&nbsp;=&nbsp;$state; }</pre><p>我们还需要通过使用类中的方法为其设置名称来配置控制台命令。此方法继承自 Command 类,也可用于设置命令说明、输入参数和其他选项。configure()</p><pre class="brush:bash;toolbar:false">public&nbsp;function&nbsp;configure():&nbsp;void { &nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;setName(&#39;create:customers&#39;); }</pre><p>现在让我们定义调用命令时将触发的方法。此方法也是从 Command 类继承而来的,我们将在其中编写我们的逻辑。execute()bin/magento create:customers</p><p>在该方法中,我们首先必须将区号设置为 .如果我们不这样做,客户创建过程稍后将产生错误。execute()global</p><p>之后,我们必须获取包含所有客户数据的 CSV 文件的绝对路径。在此示例中,CSV 文件已命名并位于目录中(相对于根目录,而不是我们的模块)。customers.csv/pub/media/fixtures</p><p>获得绝对路径后,我们必须调用该方法(此方法稍后将在我们的客户模型中定义),并将 CSV 文件的绝对路径作为参数传递给它。如果有任何错误,我们需要捕获它们并在CLI中显示错误消息:install()</p><pre class="brush:bash;toolbar:false">public&nbsp;function&nbsp;execute(InputInterface&nbsp;$input,&nbsp;OutputInterface&nbsp;$output):&nbsp;?int { &nbsp;&nbsp;try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;state-&gt;setAreaCode(Area::AREA_GLOBAL); &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$mediaDir&nbsp;=&nbsp;$this-&gt;filesystem-&gt;getDirectoryWrite(DirectoryList::MEDIA); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$fixture&nbsp;=&nbsp;$mediaDir-&gt;getAbsolutePath()&nbsp;.&nbsp;&#39;fixtures/customers.csv&#39;; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;customer-&gt;install($fixture,&nbsp;$output); &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Cli::RETURN_SUCCESS; &nbsp;&nbsp;}&nbsp;catch&nbsp;(Exception&nbsp;$e)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$msg&nbsp;=&nbsp;$e-&gt;getMessage(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$output-&gt;writeln(&quot;&lt;error&gt;$msg&lt;/error&gt;&quot;,&nbsp;OutputInterface::OUTPUT_NORMAL); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Cli::RETURN_FAILURE; &nbsp;&nbsp;} }</pre><p>为了使我们的自定义命令正常工作,我们还必须使用依赖注入来配置命令名称。</p><p>将以下代码添加到文件中:/etc/di.xml</p><pre class="brush:bash;toolbar:false">&lt;?xml&nbsp;version=&quot;1.0&quot;?&gt; &lt;config&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xsi:noNamespaceSchemaLocation=&quot;urn:magento:framework:ObjectManager/etc/config.xsd&quot;&gt; &nbsp;&nbsp;&nbsp;&lt;type&nbsp;name=&quot;Magento\Framework\Console\CommandList&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;arguments&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;argument&nbsp;name=&quot;commands&quot;&nbsp;xsi:type=&quot;array&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;item&nbsp;name=&quot;CreateCustomers&quot;&nbsp;xsi:type=&quot;object&quot;&gt;Inchoo\CustomerCreation\Console\Command\CreateCustomers&lt;/item&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/argument&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/arguments&gt; &nbsp;&nbsp;&nbsp;&lt;/type&gt; &lt;/config&gt;</pre><p>是时候创建我们的客户模型了。这是我们将读取CSV数据,对其进行处理,将其存储在数组中并将其发送以进行保存的地方。</p><p>在文件中,导入以下类并定义 Customer 类:/Model/Customer.php</p><pre class="brush:bash;toolbar:false">&lt;?php &nbsp; namespace&nbsp;Inchoo\CustomerCreation\Model; &nbsp; use&nbsp;Exception; use&nbsp;Generator; use&nbsp;Magento\Framework\Filesystem\Io\File; use&nbsp;Magento\Store\Model\StoreManagerInterface; use&nbsp;Inchoo\CustomerCreation\Model\Import\CustomerImport; use&nbsp;Symfony\Component\Console\Output\OutputInterface; &nbsp; class&nbsp;Customer { &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;everything&nbsp;else&nbsp;goes&nbsp;here }</pre><p>我们还必须在此类中创建一个构造函数并注入一些依赖项:</p><pre class="brush:bash;toolbar:false">private&nbsp;$file; private&nbsp;$storeManagerInterface; private&nbsp;$customerImport; private&nbsp;$output; &nbsp; public&nbsp;function&nbsp;__construct( &nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;$file, &nbsp;&nbsp;&nbsp;&nbsp;StoreManagerInterface&nbsp;$storeManagerInterface, &nbsp;&nbsp;&nbsp;&nbsp;CustomerImport&nbsp;$customerImport )&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;file&nbsp;=&nbsp;$file; &nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;storeManagerInterface&nbsp;=&nbsp;$storeManagerInterface; &nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;customerImport&nbsp;=&nbsp;$customerImport; }</pre><p>让我们在 Customer 类中定义方法。这是我们之前在自定义控制台命令中调用的方法。install()</p><p>我们首先检索商店和网站 ID。之后,我们检索 CSV 标头,然后遍历每个 CSV 行,读取这些行中包含的数据并将它们传递给我们尚未定义的方法。createCustomer()</p><pre class="brush:bash;toolbar:false">public&nbsp;function&nbsp;install(string&nbsp;$fixture,&nbsp;OutputInterface&nbsp;$output):&nbsp;void { &nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;output&nbsp;=&nbsp;$output; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;get&nbsp;store&nbsp;and&nbsp;website&nbsp;ID &nbsp;&nbsp;&nbsp;&nbsp;$store&nbsp;=&nbsp;$this-&gt;storeManagerInterface-&gt;getStore(); &nbsp;&nbsp;&nbsp;&nbsp;$websiteId&nbsp;=&nbsp;(int)&nbsp;$this-&gt;storeManagerInterface-&gt;getWebsite()-&gt;getId(); &nbsp;&nbsp;&nbsp;&nbsp;$storeId&nbsp;=&nbsp;(int)&nbsp;$store-&gt;getId(); &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;read&nbsp;the&nbsp;csv&nbsp;header &nbsp;&nbsp;&nbsp;&nbsp;$header&nbsp;=&nbsp;$this-&gt;readCsvHeader($fixture)-&gt;current(); &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;read&nbsp;the&nbsp;csv&nbsp;file&nbsp;and&nbsp;skip&nbsp;the&nbsp;first&nbsp;(header)&nbsp;row &nbsp;&nbsp;&nbsp;&nbsp;$row&nbsp;=&nbsp;$this-&gt;readCsvRows($fixture,&nbsp;$header); &nbsp;&nbsp;&nbsp;&nbsp;$row-&gt;next(); &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;while&nbsp;the&nbsp;generator&nbsp;is&nbsp;open,&nbsp;read&nbsp;current&nbsp;row&nbsp;data,&nbsp;create&nbsp;a&nbsp;customer&nbsp;and&nbsp;resume&nbsp;the&nbsp;generator &nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;($row-&gt;valid())&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$data&nbsp;=&nbsp;$row-&gt;current(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;createCustomer($data,&nbsp;$websiteId,&nbsp;$storeId); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$row-&gt;next(); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre><p>要读取 CSV 标题和行,我们使用生成器。生成器允许我们编写代码,这些代码可以迭代一组数据,而无需在内存中构建数组。如果我们有一个大的CSV文件,这可以帮助我们不超过内存限制。该方法将读取行数据并将其映射到从该方法检索的标头。readCsvRows()readCsvHeader()</p><p>创建以下方法:</p><pre class="brush:bash;toolbar:false">private&nbsp;function&nbsp;readCsvRows(string&nbsp;$file,&nbsp;array&nbsp;$header):&nbsp;?Generator { &nbsp;&nbsp;&nbsp;&nbsp;$handle&nbsp;=&nbsp;fopen($file,&nbsp;&#39;rb&#39;); &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(!feof($handle))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$data&nbsp;=&nbsp;[]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$rowData&nbsp;=&nbsp;fgetcsv($handle); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;($rowData)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp;($rowData&nbsp;as&nbsp;$key&nbsp;=&gt;&nbsp;$value)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$data[$header[$key]]&nbsp;=&nbsp;$value; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield&nbsp;$data; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;fclose($handle); } &nbsp; private&nbsp;function&nbsp;readCsvHeader(string&nbsp;$file):&nbsp;?Generator { &nbsp;&nbsp;&nbsp;&nbsp;$handle&nbsp;=&nbsp;fopen($file,&nbsp;&#39;rb&#39;); &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(!feof($handle))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield&nbsp;fgetcsv($handle); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;fclose($handle); }</pre><p>我们在此类中的最后一个方法是方法。createCustomer()</p><p>传递给该方法的参数是一个关联数组,其中包含来自 CSV 文件的键值对,每个键是标题列表(例如 email_address)的不同字段名称,每个值都是关联的记录(例如 john.doe@email.com)。$data</p><p>在我们的方法中,我们需要定义数组。这也将是一个关联数组,我们需要在其中将数组中的值与该方法需要保存客户的键配对。如果发现任何错误,其错误消息将打印在我们的 CLI 中。$customerData$dataimportCustomerData()</p><p>下面的示例假设CSV文件具有Magento创建客户所需的确切数据,但是,在大多数情况下,情况并非如此。也许客户出生日期的格式不正确,或者我们可能没有客户组 ID,只有客户组名称。在这种情况下,在填充数组之前,我们需要确保处理数组中的数据,使其包含正确的值。$customerData$data</p><pre class="brush:bash;toolbar:false">private&nbsp;function&nbsp;createCustomer(array&nbsp;$data,&nbsp;int&nbsp;$websiteId,&nbsp;int&nbsp;$storeId):&nbsp;void { &nbsp;&nbsp;try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;collect&nbsp;the&nbsp;customer&nbsp;data &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$customerData&nbsp;=&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;email&#39;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;$data[&#39;email_address&#39;], &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;_website&#39;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#39;base&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;_store&#39;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#39;default&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;confirmation&#39;&nbsp;&nbsp;=&gt;&nbsp;null, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;dob&#39;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;null, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;firstname&#39;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;$data[&#39;firstname&#39;], &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;gender&#39;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;null, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;group_id&#39;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;$data[&#39;customer_group_id&#39;], &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;lastname&#39;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;$data[&#39;last_name&#39;], &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;middlename&#39;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;null, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;password_hash&#39;&nbsp;=&gt;&nbsp;$data[&#39;password_hash&#39;], &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;prefix&#39;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;null, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;store_id&#39;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;$storeId, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;website_id&#39;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;$websiteId, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;password&#39;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;null, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;disable_auto_group_change&#39;&nbsp;=&gt;&nbsp;0, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;some_custom_attribute&#39;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;&#39;some_custom_attribute_value&#39; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;save&nbsp;the&nbsp;customer&nbsp;data &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;customerImport-&gt;importCustomerData($customerData); &nbsp;&nbsp;}&nbsp;catch&nbsp;(Exception&nbsp;$e)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;output-&gt;writeln( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;&lt;error&gt;&#39;.&nbsp;$e-&gt;getMessage()&nbsp;.&#39;&lt;/error&gt;&#39;, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutputInterface::OUTPUT_NORMAL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;); &nbsp;&nbsp;} }</pre><p><span style="color: #6a9955;">### 实体</span></p><p>对于最后一步,我们需要创建客户导入模型。在文件中,让我们从Magento CustomerImportExport模块导入客户类并定义我们的CustomerImport类。使其扩展导入的客户类。/Module/Import/CustomerImport.php</p><p>我们的类将包含用于准备和保存客户数据的方法。importCustomerData()</p><pre class="brush:bash;toolbar:false">&lt;?php &nbsp; namespace&nbsp;Inchoo\CustomerCreation\Model\Import; &nbsp; use&nbsp;Magento\CustomerImportExport\Model\Import\Customer; &nbsp; class&nbsp;CustomerImport&nbsp;extends&nbsp;Customer { &nbsp;&nbsp;//&nbsp;everything&nbsp;else&nbsp;goes&nbsp;here }</pre><p>现在我们的类已经定义,我们需要创建处理客户创建过程最后步骤的方法。在此方法中,我们将创建或更新客户实体,并保存为该客户提供的任何属性数据。然后,该方法将返回客户实体 ID。此方法实际上是对我们正在扩展的 Customer 类中找到的函数的轻微修改。importCustomerData()</p><pre class="brush:bash;toolbar:false">public&nbsp;function&nbsp;importCustomerData(array&nbsp;$rowData) { &nbsp;&nbsp;$this-&gt;prepareCustomerData($rowData); &nbsp;&nbsp;$entitiesToCreate&nbsp;=&nbsp;[]; &nbsp;&nbsp;$entitiesToUpdate&nbsp;=&nbsp;[]; &nbsp;&nbsp;$entitiesToDelete&nbsp;=&nbsp;[]; &nbsp;&nbsp;$attributesToSave&nbsp;=&nbsp;[]; &nbsp; &nbsp;&nbsp;$processedData&nbsp;=&nbsp;$this-&gt;_prepareDataForUpdate($rowData); &nbsp;&nbsp;$entitiesToCreate&nbsp;=&nbsp;array_merge($entitiesToCreate,&nbsp;$processedData[self::ENTITIES_TO_CREATE_KEY]); &nbsp;&nbsp;$entitiesToUpdate&nbsp;=&nbsp;array_merge($entitiesToUpdate,&nbsp;$processedData[self::ENTITIES_TO_UPDATE_KEY]); &nbsp;&nbsp;foreach&nbsp;($processedData[self::ATTRIBUTES_TO_SAVE_KEY]&nbsp;as&nbsp;$tableName&nbsp;=&gt;&nbsp;$customerAttributes)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!isset($attributesToSave[$tableName]))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$attributesToSave[$tableName]&nbsp;=&nbsp;[]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$attributesToSave[$tableName]&nbsp;=&nbsp;array_diff_key( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$attributesToSave[$tableName], &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$customerAttributes &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)&nbsp;+&nbsp;$customerAttributes; &nbsp;&nbsp;} &nbsp; &nbsp;&nbsp;$this-&gt;updateItemsCounterStats($entitiesToCreate,&nbsp;$entitiesToUpdate,&nbsp;$entitiesToDelete); &nbsp; &nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Save&nbsp;prepared&nbsp;data &nbsp;&nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;if&nbsp;($entitiesToCreate&nbsp;||&nbsp;$entitiesToUpdate)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_saveCustomerEntities($entitiesToCreate,&nbsp;$entitiesToUpdate); &nbsp;&nbsp;} &nbsp;&nbsp;if&nbsp;($attributesToSave)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_saveCustomerAttributes($attributesToSave); &nbsp;&nbsp;} &nbsp; &nbsp;&nbsp;return&nbsp;$entitiesToCreate[0][&#39;entity_id&#39;]&nbsp;??&nbsp;$entitiesToUpdate[0][&#39;entity_id&#39;]&nbsp;??&nbsp;null; }</pre><p>为了完成工作,我们需要调用 and 命令来让我们的模块和自定义命令正常工作。bin/magento setup:upgradebin/magento setup:di:compile</p><p>使用 运行客户创建脚本后,还需要确保重新索引客户网格索引器。我们可以通过调用命令来做到这一点。bin/magento create:customersbin/magento indexer:reindex customer_grid</p><p><span style="color: #6a9955;">### 小结</span></p><p>就是这样,我们现在应该有一个功能齐全的模块,使我们能够在几分钟内以编程方式创建数千个客户。如果您有任何问题或问题,请在下面发表评论。</p>

Magento 2.4有什么新功能?商家的功能和优点盘点

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>新的Magento 28.2020于2年4月1日发布,为全球第一的电子商务平台提供了一长串新功能,错误修复和安全增强功能。</p><p><span style="color: #6a9955;">### Magento 2.4有什么新功能?</span></p><p>新的和改进的默认搜索引擎</p><p>改进的媒体库</p><p>卖家辅助购物新功能</p><p>新功能采购审批工作流(仅适用于Magento商务)</p><p>双因素身份验证可提高安全性</p><p>整体技术要求更高</p><p><br/></p><p>显然,Magento正在解决其商家社区的一些最大问题,例如搜索和图像管理。</p><p>广泛的工作范围表明,Magento品牌显然已经在Adobe的品牌之家中成熟。</p><p>在Magento 2.4上投入的努力在Magento本身的这条推文中得到了完美的说明。</p><p>对于仍在Magento 1上的数千家在线商店,新的Magento 2.4增加了迁移到Magento 2的更多理由。</p><p>如果您是Magento 1商家,请随时直接与我们联系,我们可以帮助您找出从正在发生的全球电子商务转变中受益的最佳方式。</p><p>现在让我们更多地关注Magento 2.4中的新功能。</p><p><span style="color: #6a9955;">### 更好的默认搜索</span></p><p>搜索是几乎每个客户在登陆您的在线商店后都会采取的行动。您需要搜索体验不仅要好,而且要出色。</p><p>在Magento 2.4中,默认的Magento搜索引擎不再由MySQL提供支持。Magento现在要求您在服务器上安装Elasticsearch,然后再继续使用Magento 2.4。</p><p><span style="color: #6a9955;">### 弹性搜索徽标</span></p><p>说实话,Magento有点偏爱Elasticsearch已经有一段时间了。</p><p>既然 Elasticsearch 是强制性的,那么在服务器上维护另一个服务的成本会更高。特别是如果您当前的托管服务提供商默认不支持它。</p><p>对于我们Inchoo来说,我们一直在建议客户考虑替代搜索引擎。简而言之,Magento的默认搜索没有提供足够好的用户体验。</p><p>我们在Klevu搜索引擎方面有很好的经验。它非常直观,可以实时学习,显示热门搜索并轻松解决拼写错误。</p><p>但是,使Klevu成为其类别中的高级选择的是基于用户行为和购买历史的自学结果等功能。还有用于分析和报告、分层搜索等的详细仪表板。</p><p>但是,请注意,Klevu 是默认解决方案的昂贵替代品,您可以在其定价页面上自行检查。</p><p>总而言之,Magento 2.4中的搜索改进绝对是个好消息。如果您选择多投资一些,您可以为客户提供更好的搜索体验。</p><p><br/></p><p><span style="color: #6a9955;">### 新媒体库和双因素身份验证</span></p><p>在这里,我们在用户体验方面有了更多改进,只是这次是针对管理员用户的。</p><p>双因素身份验证还增加了Magento管理员帐户的安全性。该过程与大多数具有2FA的服务基本相同。系统生成的代码作为第二层身份验证发送给用户。</p><p>借助完全重新开发的媒体库,您的商店管理员现在可以比以前版本的平台更快地搜索、过滤和排序图像。Magento甚至声称它“执行速度提高了30倍”。</p><p>KEH Camera USA home page design</p><p>KEH Camera的例子,世界第一的二手相机设备零售商,其令人印象深刻的视觉效果</p><p>图片销售。更轻松地使用图像将转化为通过您的电子商务商店更有效的销售流程。</p><p>此外,新的媒体库与 Adobe Stock 集成,使您可以直接从媒体库访问库存图像预览。</p><p>是的,它基本上是Adobe向上销售其库存图像业务。但这是一笔好生意,对于某些客户来说,此功能值得研究。</p><p><br/></p><p><span style="color: #6a9955;">### 卖家辅助购物,提供更好的客户服务</span></p><p>您上次需要客户服务代表的帮助时,他/她是否能够从您的角度引导您完成使用该服务的整个过程?</p><p>如果是,那可能是很棒的客户服务。</p><p>借助Magento 2.4的新功能卖家辅助购物,您的客户服务代表可以从Magento管理员以客户身份登录网站。他们不再需要尝试无数的选项,最终却笨拙地要求客户交出他/她的密码。</p><p><br/></p><p>现在他们基本上可以在买家体验的各个方面指导和协助客户:</p><p><br/></p><p>例如,他们可以帮助客户找到产品</p><p>向他们展示如何设置特定功能,例如愿望清单</p><p>他们可以引导客户完成在店面体验中最容易理解的自定义功能(例如产品配置器)</p><p>他们可以通过代表客户快速创建订单和报价来打动客户并节省时间</p><p>他们可以处理管理任务,例如添加买家和设置审批规则</p><p>采购审批工作流(仅适用于Magento Commerce)</p><p>这项新功能为 B2B 购买公司带来了更好的支出控制,使他们能够为个人购买设置审批机制。</p><p><br/></p><p>为此,他们可以根据订单价值、SKU 数量或运输成本创建具有特定规则的审批工作流程。</p><p>他们不再需要尝试无数的选项,最终却笨拙地要求客户交出他/她的密码。</p><p>现在他们基本上可以在买家体验的各个方面指导和协助客户:</p><p><br/></p><p>例如,他们可以帮助客户找到产品</p><p>向他们展示如何设置特定功能,例如愿望清单</p><p>他们可以引导客户完成在店面体验中最容易理解的自定义功能(例如产品配置器)</p><p>他们可以通过代表客户快速创建订单和报价来打动客户并节省时间</p><p>他们可以处理管理任务,例如添加买家和设置审批规则</p><p>采购审批工作流(仅适用于Magento Commerce)</p><p>这项新功能为 B2B 购买公司带来了更好的支出控制,使他们能够为个人购买设置审批机制。</p><p><br/><br/></p><p><br/></p>

在Magento结帐地址表单中添加静态内容

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>如果您正在阅读本文,您可能正在寻找一种将静态内容添加到结帐地址字段集的简单方法。</p><p>如果您打开Magento结帐模块,您会注意到Magento结帐的技术复杂性。当你考虑Knockout,HTML,PHTML,XML,JS - 这样的技术组合通常会使一个简单的简单任务看起来非常复杂。</p><p>通常,如果您需要在结帐时编辑某些内容,则需要创建一个自定义模块,该模块将覆盖布局处理器。如果结帐修改很复杂并且需要某种动态,则此方法是有意义的。</p><p>但是对于简单的任务,例如更新输入占位符,在输入中添加注释或在输入之间添加文本 - 自定义模块是矫枉过正。</p><p>让我与您分享一个简单的前端解决方案,适用于我们需要添加一些文本或图像横幅的情况,例如在姓氏输入和公司输入之间。像这样:</p><p><img src="/uploads/images/20230818/9498b050e4203d5d71728eff93fdae87.png" title="2.png" alt="" width="936" height="326"/></p><p>这些是步骤:</p><p><br/></p><p>找到Magento核心表单字段模板:</p><p>vendor/magento/module-ui/view/frontend/web/templates/form/field.html</p><p>将文件复制到您的主题:</p><p>app/design/frontend/Inchoo/[Theme_Name]/Magento_Ui/web/templates/form/field.html</p><p>在文件底部,创建挖空if,以检查您希望添加该自定义文本的位置。</p><p>例如,如果您希望在姓氏输入后添加内容,则需要添加以下内容:</p><pre class="brush:bash;toolbar:false">&lt;!--&nbsp;ko&nbsp;if:&nbsp;element.inputName&nbsp;===&nbsp;&#39;lastname&#39;&nbsp;--&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;div&nbsp;class=&quot;delivery-address-title&quot;&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;h6&nbsp;translate=&quot;Please&nbsp;add&nbsp;your&nbsp;delivery&nbsp;address&nbsp;below&quot;&gt;&lt;/h6&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt; &lt;!--&nbsp;/ko&nbsp;--&gt;</pre><p>此外,如果您需要将该文本(或其他一些静态内容)放在地址表单中的其他位置,则需要检查 Knockout 语法并查找 inputName:</p><p><img src="/uploads/images/20230818/72fe2d3286cdce76e7c0ef7a207899c0.png" title="3.png" alt="" width="745" height="220"/></p><p>例如,如果您需要在邮政编码之后进行修改,那么您的 Knockout if 语句将包含代码而不是</p><p>postcode &nbsp;lastname</p><p>还有一件事要记住。扩展 Knockout 文件(在本例中为文件)并将该文件添加到您的主题后,请确保您的缓存已刷新并重新生成静态文件。form/field.html</p><p><br/></p>

如何将谷歌分析4连接到Magento 2

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;">按照这些明确的步骤,通过谷歌跟踪代码管理器将您的Google Analytics 4连接到Magento 2商店。注意:这篇文章已经更新,因为上一篇文章有通用分析(GA3)和Magento 1的说明。享受以下更新的说明。将Google Analytics(<span style="box-sizing: inherit; font-weight: bolder;">&nbsp;</span><span style="box-sizing: inherit;">分析4)媒体资源连接到任何网上商店的基本方法是在您要跟踪的每个网页的&lt;head&gt;标签中插入Google Analytics(分析4)跟踪代码(gtag.js)。您可以通过单击属性来找到代码 管理员&gt;数据流 &gt;然后单击流,您就有了它。</span></p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><span style="box-sizing: inherit;"><img src="/uploads/images/20230818/88ec3547924a7e02b59cbe2b8a73b6de.png" title="3.png" alt="" width="680" height="279"/></span></p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"></p><p>还有一种更简单的方法可以通过使用市场上众多Google Analytics Magento扩展之一来连接它。在这种情况下,您只需在 Magento 扩展界面中插入 GA4 属性的测量 ID 号,而无需复制粘贴上述代码。</p><p>如何完成取决于您选择使用的Google Analytics Magento扩展程序。因此,最好搜索扩展提供程序的分步说明。</p><ul class=" list-paddingleft-2" style="list-style-type: disc;"><li><p>创建 Google 跟踪代码管理器 (GTM) 帐号和容器</p></li><li><p>安装谷歌跟踪代码管理器Magento 2扩展程序</p></li><li><p>将您的GTM容器与Magento GTM扩展连接</p></li><li><p>在 GTM 中创建 GA4 配置标记</p></li><li><p>在 GTM 预览模式下测试连接</p></li></ul><p>但是,将Google Analytics连接到Magento的最佳方法是通过Google Tag Manager进行连接。总体而言,在处理Google Analytics和其他营销工具(如Google Ads或Facebook)时,Google Tag Manager为您提供了更多管理选项,并使您能够创建Google Analytics增强型电子商务事件,以帮助您跟踪用户旅程。</p><p>在这里,您可以阅读更多关于为什么我认为这是将Google Analytics连接到Google Tag Manager的最佳方式。在这种情况下,您需要Google Tag Manager Magento扩展程序来正确设置所有内容,而不是Google Analytics Magento扩展程序。</p><p>事不宜迟,以下是使用Google Tag Manager将Google Analytics 4连接到Magento网上商店的步骤。</p><p><strong>1. 创建谷歌跟踪代码管理器 (GTM) 帐号和容器</strong></p><p>首先单击此链接中的“免费开始”按钮:https://marketingplatform.google.com/about/tag-manager/ 然后我强烈建议观看有关如何创建您的第一个 GTM 帐户和容器的简短视频教程。</p><p>您还将获得界面和帐户结构的概述。如果你后来觉得有必要更深入地研究GTM,我建议你查看Analytics Mania Youtube频道的其他视频和材料。</p><p><strong>2. 安装谷歌跟踪代码管理器 2 扩展程序</strong></p><p>我不会在这里建议任何特定的GTM扩展,因为它们都可以完成这项工作。最适合您的是谷歌它并选择具有最适合您需求的功能的扩展程序。通常,他们都需要遵循有关GA4增强型电子商务配置的Google文档。我们努力制作自己的性能感知GTM扩展,该扩展仅供我们的客户免费使用,因此我将在示例中向您展示此扩展的界面。将 GTM 与 GTM 扩展连接是相似且简单的,无论扩展提供程序如何,因此我相信您会成功连接它。</p><p>3. 将您的 GTM 容器与 Magento GTM 扩展连接</p><p><img src="/uploads/images/20230818/248b362b6c9a3ddf52ac714e2b3c843e.png" title="4.png" alt="" width="687" height="400"/></p><p>打开您的 GTM 容器,然后单击 GTM ID 号。</p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><span style="box-sizing: inherit;"><img src="/uploads/images/20230818/419dca5d7b79425eaf03019a11c6c36c.png" title="5.png" alt="" width="696" height="432"/></span></p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><span style="box-sizing: inherit;"><span style="box-sizing: inherit;">打开您的Magento GTM扩展程序,然后将GTM ID号粘贴到Google Tag Manager&gt;Google Tag Manager部分的商店&gt;配置&gt;销售&gt;Google API部分。保存配置,GTM将连接到您的Magento网上商店。您可以通过查看网上商店的页面源代码并找到 GTM ID 号来测试它。或者安装</span><a href="https://chrome.google.com/webstore/detail/tag-assistant-legacy-by-g/kejbdjndbnbjgmefkgdddjlbokphdefk?hl=en" style="box-sizing: inherit; transition: color 0.2s ease 0s; color: rgb(121, 173, 54); text-decoration-line: none;">旧版跟踪代码助手浏览器扩展</a><span style="box-sizing: inherit;">程序。这是一个有用的扩展,可以帮助您对GTM和Google Analytics的安装进行故障排除,并为您提供一些其他见解。</span></span></p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><span style="box-sizing: inherit;"><span style="box-sizing: inherit;"><img src="/uploads/images/20230818/3e8feada6bf267a39146f837b560a5c6.png" title="6.png" alt="" width="703" height="376"/></span></span></p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><span style="box-sizing: inherit;"><span style="box-sizing: inherit;"><span style="color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;">然后单击标签配置空间以打开标签类型。</span></span></span></p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><span style="box-sizing: inherit;"><span style="box-sizing: inherit;"><span style="color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><img src="/uploads/images/20230818/3a76d7a8cd2acdd8aa675b4f64633ca4.png" title="1.png" alt="" width="706" height="403"/></span></span></span></p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;">选择 GA4 配置标记类型。</p><p><span style="box-sizing: inherit;"><img src="/uploads/images/20230818/e43603489000823dff49e9a8709eff6b.png" title="2.png" alt="" width="708" height="402"/></span></p><p><span style="box-sizing: inherit;"></span></p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><span style="box-sizing: inherit;">...,然后输入您的 GA4 测量 ID 号。衡量 ID 与 GA4 跟踪代码位于同一位置。</span></p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><span style="box-sizing: inherit;">请记住本博客开头的屏幕截图,我向您展示了如何查找 GA4 跟踪代码的路径,您将在屏幕截图中看到衡量 ID 位置。</span></p><p><span style="color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;">现在单击触发部分并选择触发器“所有页面”。</span></p><p><span style="box-sizing: inherit;"><font color="#404041" face="Open Sans, Helvetica Neue, Arial, Helvetica, sans-serif"><span style="font-size: 18px;"><img src="/uploads/images/20230818/ca91562bb080c62f25b87254b974fde1.png" title="3.png" alt="" width="717" height="118"/></span></font></span><br/></p><p></p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><span style="box-sizing: inherit;">将您的代码命名为“GA4 配置”,然后点击保存。</span></p><p><span style="box-sizing: inherit;"><br/></span></p><p><img src="/uploads/images/20230818/212bd593f3b88a3d8981e554772ea584.png" title="4.png" alt="" width="714" height="324"/></p><p></p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><span style="box-sizing: inherit;">仅此而已。您使用Google Tag Manager将您的Google Analytics媒体资源连接到Magento网上商店。</span></p><h2 style="box-sizing: inherit; color: rgb(64, 64, 65); font-family: TheSerifB, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; margin: 36px 0px 18px; letter-spacing: 0.25px; font-size: 31px; line-height: 36px; text-wrap: wrap;">5. 在 GTM 预览模式下测试您的连接</h2><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><span style="box-sizing: inherit;">打开您的 Google Analytics GA4 媒体资源,然后检查您是否收到了流量。GA4 需要一些时间才能开始显示流量,但您可以通过单击 GTM 容器中的“预览”按钮立即测试您的连接。输入您的网上商店网址,然后单击“连接”。</span></p><p><img src="/uploads/images/20230818/541e5d6b14686832bfd476f015bba838.png" title="5.png" alt="" width="718" height="396"/></p><p><span style="box-sizing: inherit;"><img src="/uploads/images/20230818/9086610a9f34757f92e4eaea21ab2aa4.png" title="6.png" alt="" width="720" height="379"/></span><br/></p><p></p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><span style="box-sizing: inherit;">GTM将在另一个选项卡中打开您的网上商店。现在转到 GA4 属性,然后在“配置”报告中打开“调试视图”界面。您应该会看到GTM在另一个标签页中打开您的网上商店时发生的page_view事件,这意味着您的Google Analytics收到点击并连接到您的网上商店。继续浏览您的网上商店,并观察哪些事件开始显示在Google Analytics的DebugView中。</span></p><p><img src="/uploads/images/20230818/c1857cc833b742ef717ec0a60a11676e.png" title="7.png" alt="" width="723" height="342"/></p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><span style="box-sizing: inherit;">如果您想继续设置增强型电子商务事件,例如:</span></p><p><img src="/uploads/images/20230818/951041de90beccb2b027efa3fb02ba0a.png" title="8.png" alt="" width="724" height="347"/></p><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 30px; overflow-wrap: break-word; color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><span style="box-sizing: inherit;"><span style="box-sizing: inherit;"><span style="color: rgb(64, 64, 65); font-family: &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, Arial, Helvetica, sans-serif; font-size: 18px; text-wrap: wrap;"><br/></span></span></span><br/></p>

盘点100个学习magento二次开发的网站

<h5 style="color:red;">系统学习magento二次开发,推荐小册:<a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank">《Magento中文全栈二次开发 》</a></h5> <div class="image-container"> <p> <a style="color:blue;" href="https://www.maxiaoke.com/manual/magento_cn_dev.html" target="_blank"> <img src="https://www.maxiaoke.com/uploads/images/20230218/bb9c82995c24d1105676e02f373755f5.jpg" alt="Magento中文全栈二次开发"> </a> </p> </div> <div class="text-container" style="font-size:14px; color:#888"> <p>本小册面向Magento2以上版本,书代码及示例兼容magento2.0-2.4版本。涵盖了magento前端开发,后端开发,magento2主题,magento2重写,magento2 layout,magento2控制器,magento2 block等相关内容,带领您成为magento开发技术专家。</p> </div> <hr><p>1. [Magento 官方文档](https://devdocs.magento.com/): Magento的官方文档,提供了广泛的开发、配置和管理指南。</p><p>2. [Mageplaza Blog](https://www.mageplaza.com/blog/): Mageplaza的博客,包含各种Magento开发和管理的文章。</p><p>3. [Inchoo Blog](https://inchoo.net/blog/): Inchoo公司的博客,涵盖了Magento开发的多个方面。</p><p>4. [Alan Storm<span style="color: rgb(206, 145, 120);">s Blog](https://alanstorm.com/):&nbsp; Magento开发专家Alan Storm的博客,包含深入的技术文章。</span></p><p><span style="color: #ce9178;">5. [Firebear Studio Blog](https://firebearstudio.com/blog/): Firebear Studio的博客,涵盖了Magento和电子商务领域的技术文章。</span></p><p><span style="color: #ce9178;">6. [Magento Stack Exchange](https://magento.stackexchange.com/): Magento的问答社区,可以提问和回答与Magento开发相关的问题。</span></p><p><span style="color: #ce9178;">7. [Smashing Magazine - E-Commerce Category](https://www.smashingmagazine.com/category/e-commerce/): Smashing Magazine的电子商务类别,包含一些与Magento相关的文章。</span></p><p><span style="color: #ce9178;">8. [Reddit - r/magento](https://www.reddit.com/r/magento/): Reddit上的Magento社区,您可以在这里与其他Magento开发者交流和分享。</span></p><p><span style="color: #ce9178;">9. [GitHub - Magento](https://github.com/magento): Magento在GitHub上的官方仓库,包含源代码和一些示例。</span></p><p><span style="color: #ce9178;">10. [Magento DevDocs](https://developer.adobe.com/commerce/): Magento DevDocs,提供Magento的最新技术文档和API参考。</span></p><p><span style="color: #ce9178;">11. [Magento 2 Tutorials by Max Pronko](https://www.maxpronko.com/blog/category/magento-2): Magento开发者Max Pronko的博客,包含Magento 2的教程。</span></p><p><span style="color: #ce9178;">12. [MagePsycho Blog](https://www.magepsycho.com/blog/): 包含有关Magento开发、配置和优化的文章。</span></p><p><span style="color: #ce9178;">13. [Atwix Blog](https://www.atwix.com/blog/): Atwix公司的博客,涵盖了Magento开发和调优的各种话题。</span></p><p><span style="color: #ce9178;">14. [MageComp Blog](https://magecomp.com/blog/): MageComp的博客,包含有关Magento扩展和开发的文章。</span></p><p><span style="color: #ce9178;">15. [Magento Community Engineering](https://communityengineering.readme.io/): Magento社区工程团队的官方文档和资源。</span></p><p><span style="color: #ce9178;">16. [MageWorx Blog](https://www.mageworx.com/blog/): MageWorx的博客,包含有关Magento扩展和技术的文章。</span></p><p><span style="color: #ce9178;">17. [Magebuzz Blog](https://www.magebuzz.com/blog/): Magebuzz的博客,涵盖了Magento开发、设计和营销的话题。</span></p><p><span style="color: #ce9178;">18. [Classy Llama Blog](https://www.classyllama.com/blog): Classy Llama的博客,包含了Magento和电子商务领域的技术和策略文章。</span></p><p><span style="color: #ce9178;">19. [Magento Explained](https://magentoexplained.com/): 提供针对Magento初学者的教程和解释。</span></p><p><span style="color: #ce9178;">20. [Magento U](https://u.magento.com/): Magento官方的在线培训和学习平台,提供各种课程。</span></p><p><span style="color: #ce9178;">21. [MeetMagento Association](https://meet-magento.com/): MeetMagento协会,组织Magento相关的会议和活动。</span></p><p><span style="color: #ce9178;">22. [BelVG Blog](https://belvg.com/blog): BelVG公司的博客,涵盖了Magento和电子商务方面的技术文章。</span></p><p><span style="color: #ce9178;">23. [Tuts+ - Magento Category](https://webdesign.tutsplus.com/categories/magento): Tuts+网站的Magento类别,包含一些教程和技术文章。</span></p><p><span style="color: #ce9178;">24. [Atlassian Confluence - Magento](https://confluence.atlassian.com/mag): Atlassian Confluence上的Magento知识库,包含了一些有关Magento的文档。</span></p><p><span style="color: #ce9178;">25. [Cmsmart Community](https://cmsmart.net/community): Cmsmart社区,包含了一些Magento和电子商务领域的文章和讨论。</span></p><p><span style="color: #ce9178;">26. [Reddit - r/Magento2](https://www.reddit.com/r/Magento2/): Reddit上关于Magento 2的社区,适用于Magento 2开发者。</span></p><p><span style="color: #ce9178;">27. [Quick Tips by Aoepeople](https://www.aoepeople.com/en/blog/category/quick-tips/): Aoepeople的博客,提供有关Magento开发的快速技巧。</span></p><p><span style="color: #ce9178;">28. [Atwix Magento 2 Code Tips](https://github.com/atwix/atwix-magento2-code-tips): Atwix团队的Magento 2代码技巧存储库。</span></p><p><span style="color: #ce9178;">29. [Mgt-Commerce Blog](https://www.mgt-commerce.com/blog/): Mgt-Commerce的博客,涵盖了Magento扩展和开发的内容。</span></p><p><span style="color: #ce9178;">30. [BSS Commerce Blog](https://bsscommerce.com/blog/): BSS Commerce的博客,包含有关Magento 2扩展和开发的文章。</span></p><p><span style="color: #ce9178;">31. [Aitoc Blog](https://www.aitoc.com/blog/): Aitoc的博客,包含有关Magento开发和优化的文章。</span></p><p><span style="color: #ce9178;">32. [Webkul Blog](https://webkul.com/blog/): Webkul的博客,涵盖了关于Magento扩展和电子商务的多个主题。</span></p><p><span style="color: #ce9178;">33. [Cool Ryan Blog](https://coolryan.com/): Ryan的博客,包含Magento开发的实用教程和指南。</span></p><p><span style="color: #ce9178;">34. [Tutorial Magento](https://tutorialmagento.com/): Tutorial Magento是一个专门的博客,提供有关Magento的教程和技巧。</span></p><p><span style="color: #ce9178;">35. [Magently Blog](https://magently.com/blog/): Magently的博客,包含Magento开发和优化的文章。</span></p><p><span style="color: #ce9178;">36. [Experius Blog](https://www.experius.nl/blog/): Experius公司的博客,涵盖了Magento开发和电子商务的多个方面。</span></p><p><span style="color: #ce9178;">37. [Klevu Blog](https://www.klevu.com/blog/): Klevu的博客,涵盖了有关Magento搜索和用户体验的话题。</span></p><p><span style="color: #ce9178;">38. [ScandiPWA Blog](https://scandipwa.com/blog): ScandiPWA的博客,关注Magento Progressive Web App开发。</span></p><p><span style="color: #ce9178;">39. [Vovance Blog](https://www.vovance.com/blog.html): Vovance的博客,涵盖了关于Magento开发和定制的话题。</span></p><p><span style="color: #ce9178;">40. [Mirasvit Blog](https://mirasvit.com/blog/): Mirasvit的博客,提供有关Magento和电子商务的技术文章。</span></p><p><span style="color: #ce9178;">41. [Shero Blog](https://sherocommerce.com/blog/): Shero的博客,包含了有关Magento和电子商务策略的文章。</span></p><p><span style="color: #ce9178;">42. [MageMonkey Blog](https://magemonkey.io/blog/): MageMonkey的博客,涵盖了关于Magento和电子商务的技术和建议。</span></p><p><span style="color: #ce9178;">43. [Magento 2 Blog](https://magefan.com/blog/magento2): Magefan的Magento 2博客,提供有关Magento 2的技术文章。</span></p><p><span style="color: #ce9178;">44. [Cyrill Schumacher&#39;</span>s Blog](https://cyrillschumacher.com/): Cyrill Schumacher是Magento核心开发者,他的博客包含了有关Magento的深入文章。</p><p>45. [IWD Agency Blog](https://www.iwdagency.com/blog/): IWD Agency的博客,涵盖了关于Magento扩展和开发的多个主题。</p><p>46. [A Better Lemonade Stand Blog](https://www.abetterlemonadestand.com/blog/): 虽然不是专门针对Magento的网站,但该博客涵盖了电子商务和在线零售的多个方面,可能会涉及一些Magento相关内容。</p><p>47. [MageDaily](https://magedaily.com/): MageDaily提供有关Magento开发、设计和营销的日常更新。</p><p>48. [Magento Quickies](https://www.magenticity.com/magento-quickies): Magenticity的Magento Quickies系列,提供有关Magento的短小而有用的技巧。</p><p>49. [Modern Retail Blog](https://modernretail.co.uk/blog/): Modern Retail的博客,包含有关Magento和电子商务的文章。</p><p>50. [Sherocommerce Blog](https://sherocommerce.com/blog/): Sherocommerce的博客,涵盖了关于Magento和电子商务的技术和策略。</p><p>51. [Elogic Commerce Blog](https://elogic.co/blog/): Elogic Commerce的博客,包含了有关Magento开发和电子商务的文章。</p><p>52. [MageHost Blog](https://www.magehost.com/blog): MageHost的博客,涵盖了Magento托管、优化和性能方面的话题。</p><p>53. [MageArray Blog](https://magearray.com/blog/): MageArray的博客,提供有关Magento开发和扩展的技术文章。</p><p>54. [Divante Blog](https://divante.com/blog/): Divante公司的博客,涵盖了Magento开发和电子商务的多个方面。</p><p>55. [MageMonkey Blog](https://magemonkey.io/blog/): MageMonkey的博客,关注Magento和电子商务领域的技术和建议。</p><p>56. [MageDirect Blog](https://magedirect.co/blog/): MageDirect的博客,包含有关Magento和电子商务的文章和教程。</p><p>57. [ScandiPWA Blog](https://scandipwa.com/blog): ScandiPWA的博客,专注于Magento Progressive Web App开发。</p><p>58. [OroCommerce Blog](https://www.orocommerce.com/blog): OroCommerce的博客,关注B2B电子商务和技术。</p><p>59. [MagePsycho Blog](https://www.magepsycho.com/blog/): MagePsycho的博客,提供Magento开发、配置和优化的文章。</p><p>60. [MageBees Blog](https://www.magebees.com/blog/): MageBees的博客,涵盖了关于Magento和电子商务的多个话题。</p><p>61. [Creatuity Blog](https://creatuity.com/blog/): Creatuity的博客,提供有关Magento开发和优化的文章。</p><p>62. [Innobyte Blog](https://www.innobyte.com/blog/): Innobyte的博客,包含有关Magento开发和电子商务的多个主题。</p><p>63. [Fooman Blog](https://store.fooman.co.nz/blog/): Fooman的博客,提供有关Magento扩展和开发的技术文章。</p><p>64. [MageComp Blog](https://magecomp.com/blog/): MageComp的博客,涵盖了关于Magento扩展和开发的文章。</p><p>65. [Magento Hacks](https://www.magentohacks.com/): Magento Hacks提供有关Magento开发和技术的教程和文章。</p><p>66. [MagentoBlog](https://magento.blog/): MagentoBlog涵盖了关于Magento开发和电子商务的各种主题。</p><p>67. [Inviqa Blog](https://inviqa.com/blog): Inviqa的博客,涵盖了Magento开发和电子商务的技术和策略。</p><p>68. [Magmodules Blog](https://www.magmodules.eu/blog/): Magmodules的博客,关注Magento模块和扩展。</p><p>69. [Ecomdev Blog](https://ecomdev.org/blog/): Ecomdev的博客,提供有关Magento开发和测试的文章。</p><p>70. [Elsner Blog](https://www.elsner.com/blog/): Elsner的博客,包含有关Magento和电子商务的技术和营销策略。</p><p>71. [MagentoTutorial.net](https://magentotutorial.net/): MagentoTutorial.net提供有关Magento的教程和技术文章。</p><p>72. [Wagento Blog](https://www.wagento.com/blog): Wagento的博客,涵盖了关于Magento开发和电子商务的多个主题。</p><p>73. [Pronko Consulting Blog](https://pronkoconsulting.com/blog/): Pronko Consulting的博客,包含有关Magento开发和技术的文章。</p><p>74. [Atwix Blog](https://www.atwix.com/blog/): Atwix的博客,涵盖了关于Magento开发和调优的各种话题。</p><p>75. [Magebuzz Blog](https://www.magebuzz.com/blog/): Magebuzz的博客,包含有关Magento开发、设计和营销的文章。</p><p>76. [Magemad Blog](https://magemad.com/blog/): Magemad的博客,涵盖了有关Magento开发和电子商务的文章。</p><p>77. [Magedelight Blog](https://www.magedelight.com/blog/): Magedelight的博客,包含了关于Magento扩展和开发的技术文章。</p><p>78. [MageMojo Blog](https://magemojo.com/blog/): MageMojo的博客,关注于Magento托管和性能优化。</p><p>79. [MageComp Blog](https://magecomp.com/blog/): MageComp的博客,涵盖了有关Magento扩展和开发的多个话题。</p><p>80. [The Magento Community Blog](https://magento.com/blog/community): Magento官方社区博客,包含了有关Magento社区和事件的内容。</p><p>81. [Rave Infosys Blog](https://www.raveinfosys.com/blog/): Rave Infosys的博客,涵盖了Magento和电子商务领域的多个话题。</p><p>82. [MageCloud Blog](https://magecloud.agency/blog/): MageCloud的博客,关注于Magento托管和云解决方案。</p><p>83. [Coolblueweb Blog](https://coolblueweb.com/blog/): Coolblueweb的博客,涵盖了关于Magento开发和电子商务的内容。</p><p>84. [Magefan Blog](https://magefan.com/blog/): Magefan的博客,提供有关Magento开发和优化的文章。</p><p>85. [Mage-Coder Blog](https://mage-coder.com/blog/): Mage-Coder的博客,包含了关于Magento开发和技术的文章。</p><p>86. [MageComp Blog](https://magecomp.com/blog/): MageComp的博客,涵盖了关于Magento扩展和开发的多个方面。</p><p>87. [Magebay Blog](https://www.magebay.com/blog/): Magebay的博客,提供有关Magento开发和扩展的技术文章。</p><p>88. [Wahyu Pratama<span style="color: #ce9178;">s Blog](https://www.wahyupratama.com/): Wahyu Pratama的博客,涵盖了关于Magento和电子商务的多个话题。</span></p><p><span style="color: #ce9178;">89. [MageCloud Blog](https://magecloud.net/blog/): MageCloud的博客,关注于Magento托管和性能优化。</span></p><p><span style="color: #ce9178;">90. [Pulse Storm Blog](https://alanstorm.com/): Alan Storm的博客,包含了关于Magento开发的深入技术文章。</span></p><p><span style="color: #ce9178;">91. [Magedia Blog](https://magedia.com/blog/): Magedia的博客,提供有关Magento开发和电子商务的文章。</span></p><p><span style="color: #ce9178;">92. [Magebit Blog](https://magebit.com/blog/): Magebit的博客,包含了关于Magento开发和优化的技术文章。</span></p><p><span style="color: #ce9178;">93. [MageHit Blog](https://magehit.com/blog/): MageHit的博客,涵盖了关于Magento开发和扩展的话题。</span></p><p><span style="color: #ce9178;">94. [Ecom Labs Blog](https://ecom-labs.com/blog/): Ecom Labs的博客,包含有关Magento开发和电子商务的内容。</span></p><p><span style="color: #ce9178;">95. [Vervaunt Blog](https://www.vervaunt.com/blog/): Vervaunt的博客,关注Magento和电子商务领域的技术和策略。</span></p><p><span style="color: #ce9178;">96. [TIG PostNL Blog](https://tig.nl/blog/): TIG PostNL的博客,涵盖了有关Magento和电子商务的文章。</span></p><p><span style="color: #ce9178;">97. [MageComp Blog](https://magecomp.com/blog/): MageComp的博客,提供有关Magento扩展和开发的文章。</span></p><p><span style="color: #ce9178;">98. [Magento Master Blog](https://mmadventure.com/): Magento Master Adventure的博客,分享Magento相关经验和见解。</span></p><p><span style="color: #ce9178;">99. [MageSpecialist Blog](https://blog.mageplaza.com/): MageSpecialist的博客,涵盖了关于Magento开发和技术的多个话题。</span></p><p><span style="color: #ce9178;">100. [ScandiPWA Blog](https://scandipwa.com/blog): ScandiPWA的博客,关注Magento Progressive Web App开发。</span></p><p><br/></p><p><br/></p>