magento2 支付页面如何给shipping method添加自定义属性
magento2 支付页面如何给shipping method添加自定义属性
在开发过程中,我们需要在所选运输方式(shipping method)里显示一些说明文本,这个说明文本在后台设置,需要在前台输出来。
比如要显示的属性字段为intro_text。运输方式为ysfs。
假设你已经创建了运输方式,不会的请自行谷歌。
一,先在system.xml里添加intro_text
<field id="intro_text" translate="label" type="text" sortOrder="81" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Intro Text</label> </field>
二,在etc/extension_attributes.xml里定义
<?xml version="1.0"?> <!-- /* * * * @author DCKAP Team * @copyright Copyright (c) 2018 DCKAP (https://www.dckap.com) * @package Dckap_CustomFields */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nOnamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd" <extension_attributes for="MagentoQuoteApiDataShippingMethodInterface"> <attribute code="intro_text" type="string" /> </extension_attributes> </config>
在m2里 我们不能直接修改核心模块,并且shipping method这些显示的字段都是通过api/data来定义的,非常不好理解,里面的字段都是写死了的。我们要扩展的话 只能通过extension_attributes来扩展。不能直接改源码,重写api/data也不合理。
只能按照m2的规则来做,通过extension_attributes来添加扩展属性。
我这里加的扩展属性是intro_text,字符串类型。
三,扩展重写MagentoQuoteModelCartShippingMethodConverter
因为我们前台显示的shipping method内容,都是在这个类里 赋值,并输出来的。
所以我们需要改写这个类,在这个类里 把intro_text的值加进去。那样的话 前台页面才会显示intro_text的值。
我们一般用plugin来扩展某个类具体的某个方法
1,在etc/di.xml里定义
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nOnamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd" <type name="MagentoQuoteModelCartShippingMethodConverter"> <plugin name="demo_ShippingMethodConverter" type="ZouDemoPluginQuoteCartShippingMethodConverter"/> </type> </config>
2,创建ZouDemoPluginQuoteCartShippingMethodConverter.php
<?php namespace ZouDemoPluginQuote; use MagentoQuoteModelCartShippingMethodConverter; use MagentoQuoteApiDataShippingMethodInterface; use MagentoQuoteApiDataShippingMethodExtensionFactory; class CartShippingMethodConverter { protected $extensionFactory; public function __construct( ZouDemoHelperData $helper, ShippingMethodExtensionFactory $extensionFactory ) { $this->extensionFactory = $extensionFactory; $this->helper = $helper; } public function afterModelToDataObject( MagentoQuoteModelCartShippingMethodConverter $subject, $result, $rateModel, $quoteCurrencyCode ) { $code = $rateModel->getCarrier();//获取该运输方式的code if($code != &#39;ysfs&#39;){ return $result; } //读取后台设置的intro_text文本 $introText = $this->helper->getConfig(&#39;carriers/ysfs/intro_text&#39;); $extensibleAttribute = ($result->getExtensionAttributes()) ? $result->getExtensionAttributes() : $this->extensionFactory->create(); //$rateModel->getIntroText() // $extensibleAttribute->setIntroText($introText); $result->setExtensionAttributes($extensibleAttribute); return $result; } }
注意:这里要先判断getExtensionAttributess是否存在,不存在的话 需要$this->extensionFactory->create()下,不然的话 加不进去 会报错。
四,改写前台shipping method模版
1,创建ZouDemoviewfrontendlayoutcheckout_index_index.xml
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nOnamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="checkout.root"> <arguments> <argument name="jsLayout" xsi:type="array"> <item name="components" xsi:type="array"> <item name="checkout" xsi:type="array"> <item name="children" xsi:type="array"> <item name="steps" xsi:type="array"> <item name="children" xsi:type="array"> <item name="shipping-step" xsi:type="array"> <item name="children" xsi:type="array"> <item name="shippingAddress" xsi:type="array"> <item name="config" xsi:type="array"> <item name="shippingMethodItemTemplate" xsi:type="string">Zou_Demo/shipping-address/shipping-method-item</item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </argument> </arguments> </referenceBlock> </body> </page>
也就是说把默认的shipping method模版改成我们自己的,这样的话 我们就是任意修改了。
2,创建ZouDemoviewfrontendwebtemplateshipping-addressshipping-method-item.html
<tr class="row" click="element.selectShippingMethod"> <td class="col col-method"> <input type="radio" class="radio" ifnot="method.error_message" ko-checked="element.isSelected" ko-value="method.carrier_code + &#39;_&#39; + method.method_code" attr="&#39;aria-labelledby&#39;: &#39;label_method_&#39; + method.method_code + &#39;_&#39; + method.carrier_code + &#39; &#39; + &#39;label_carrier_&#39; + method.method_code + &#39;_&#39; + method.carrier_code, &#39;checked&#39;: element.rates().length == 1 || element.isSelected" /> </td> <td class="col col-price"> <each args="element.getRegion(&#39;price&#39;)" render="" /> </td> <td class="col col-method" attr="&#39;id&#39;: &#39;label_method_&#39; + method.method_code + &#39;_&#39; + method.carrier_code" text="method.method_title" /> <td class="col col-carrier" attr="&#39;id&#39;: &#39;label_carrier_&#39; + method.method_code + &#39;_&#39; + method.carrier_code" text="method.carrier_title" /> </tr> <!-- ko if: ((method.method_code + &#39;_&#39; + method.carrier_code == "ysfs_ysfs") && element.selectedMethod() == "ysfs_ysfs") --> <tr class="custom-shipping-method-fields-shipping-information" > <td colspan="4"> <p class="small-text" text="method.extension_attributes.intro_text"></p </td> </tr> <!-- /ko --> <tr class="row row-error" if="method.error_message"> <td class="col col-error" colspan="4"> <div role="alert" class="message error"> <div text="method.error_message"></div> </div> <span class="no-display"> <input type="radio" attr="&#39;value&#39; : method.method_code, &#39;id&#39;: &#39;s_method_&#39; + method.method_code" /> </span> </td> </tr>
我们在ysfs这个运输方式里下面显示里intro_text文本。
直接读取method.extension_attributes.intro_text这里的值就ok了。这个值我们在第三步里已经赋值了,是有值的。
五,测试
m2顺便改个东西 都麻烦的很 要改很多东西 才能匹配他的尿性。不然的话 就寸步难行。