Cum să adăugați un câmp personalizat pentru valorile opțiunilor în Opțiuni avansate de produs
Publicat: 2020-11-20Din articolul anterior, ați învățat cum să creați câmpuri de opțiuni personalizate Magento. Am aflat, de asemenea, cum să afișăm datele câmpului atât pe front-end-ul paginii de produs, cât și pe pagina de comandă din panoul de administrare.
Ce este acum?
Să învățăm cum să adăugăm același câmp GTIN personalizat pentru valorile opțiunilor și să-l afișam pe pagina de produs.
Cuprins
- Pasul 1. Crearea unui nou modul
- 1. compozitor.json
- 2. etc/module.xml
- 3. înregistrare.php
- Pasul 2. Adăugarea unui câmp nou la baza de date
- Pasul 3. Adăugarea de logică la lucrul cu backend
- Pasul #4. Adăugarea setărilor pentru a dezactiva afișarea câmpului GTIN pentru Configurarea opțiunilor avansate de produs
- Pasul #5. Afișarea câmpului nou pe pagina de produs front-end
Pasul 1. Crearea unui nou modul
Să începem cu crearea noului modul, proces care a fost tratat în detaliu în această postare de blog Mageworx.
Astfel, fără alte prelungiri, iată codul de care vom avea nevoie:
1. compozitor.json
{ "name": "mageworx/module-optionvaluegtin", "description": "N/A", "require": { "magento/framework" : ">=100.1.0 <101", "magento/module-catalog": ">=101.0.0 <104" }, "type": "magento2-module", "version": "1.0.0", "license": [ "OSL-3.0", "AFL-3.0" ], "autoload": { "files": [ "registration.php" ], "psr-4": { "VendorName\\OptionValueGtin\\": "" } } }
2. etc/module.xml
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="VendorName_OptionValueGtin" setup_version="1.0.0"> <sequence> <module name="Magento_Catalog"/> <module name="MageWorx_OptionBase"/> </sequence> </module> </config>
3. înregistrare.php
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'VendorName_OptionValueGtin', __DIR__ );
Pasul 2. Adăugarea unui câmp nou la baza de date
Este timpul să creați câmpul GTIN și să îl adăugați la tabelul corespunzător din baza de date.
Pe măsură ce adăugăm un câmp pentru valorile opțiunilor, va fi necesar tabelul `catalog_product_option_type_value`.
Să creăm următorul fișier:
`app/code/VendorName/OptionValueGtin/Setup/InstallSchema.php`
<?php namespace VendorName\OptionValueGtin\Setup; use Magento\Framework\Setup\InstallSchemaInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\SchemaSetupInterface; use Magento\Framework\DB\Ddl\Table; class InstallSchema implements InstallSchemaInterface { public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) { $setup->startSetup(); $setup->getConnection()->addColumn( $setup->getTable('catalog_product_option_type_value'), 'gtin', [ 'type' => Table::TYPE_TEXT, 'nullable' => true, 'default' => null, 'comment' => 'Gtin (added by MageWorx Option Value Gtin)', ] ); $setup->endSetup(); } }
Pasul 3. Adăugarea de logică la lucrul cu backend
Utilizați mecanismul de modificare a grupului pentru a adăuga câmp Magento la opțiunea personalizată.
Să creăm următorul fișier:
`app/code/VendorName/OptionValueGtin/etc/adminhtml/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"> <virtualType name="MageWorx\OptionBase\Ui\DataProvider\Product\Form\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> <item name="mageworx-option-value-gtin" xsi:type="array"> <item name="class" xsi:type="string">MageWorx\OptionValueGtin\Ui\DataProvider\Product\Form\Modifier\OptionValueGtin</item> <item name="sortOrder" xsi:type="number">72</item> </item> </argument> </arguments> </virtualType> </config>
Aici:
Adăugăm modificatorul nostru la pool-ul general al extensiei Advanced Product Options pentru Magento 2―
`MageWorx\OptionBase\Ui\DataProvider\Product\Form\Modifier\Pool`.
`VendorName\OptionValueGtin\Ui\DataProvider\Product\Form\Modifier\OptionValueGtin` este clasa modificatoare.
De mai jos:
Vedeți codul care permite adăugarea câmpului nostru la formularul „app/code/VendorName/OptionValueGtin/Ui/DataProvider/Product/Form/Modifier/OptionValueGtin.php”:
<?php namespace VendorName\OptionValueGtin\Ui\DataProvider\Product\Form\Modifier; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions; use Magento\Ui\Component\Form\Element\Input; use Magento\Ui\Component\Form\Element\DataType\Number; use Magento\Ui\Component\Form\Field; use MageWorx\OptionBase\Ui\DataProvider\Product\Form\Modifier\ModifierInterface; class OptionValueGtin extends AbstractModifier implements ModifierInterface { /** * @var array */ protected $meta = []; /** * {@inheritdoc} */ public function modifyData(array $data) { return $data; } /** * {@inheritdoc} */ public function modifyMeta(array $meta) { $this->meta = $meta; $this->addFields(); return $this->meta; } /** * Adds fields to the meta-data */ protected function addFields() { $groupCustomOptionsName = CustomOptions::GROUP_CUSTOM_OPTIONS_NAME; $optionContainerName = CustomOptions::CONTAINER_OPTION; // Add fields to the values $valueFeaturesFields = $this->getValueFieldsConfig(); $this->meta[$groupCustomOptionsName]['children']['options']['children']['record']['children'] [$optionContainerName]['children']['values']['children']['record']['children'] = array_replace_recursive( $this->meta[$groupCustomOptionsName]['children']['options']['children']['record']['children'] [$optionContainerName]['children']['values']['children']['record']['children'], $valueFeaturesFields ); } /** * The custom option fields config * * @return array */ protected function getValueFieldsConfig() { $fields['gtin'] = $this->getGtinFieldConfig(); return $fields; } /** * Get gtin field config * * @return array */ protected function getGtinFieldConfig() { return [ 'arguments' => [ 'data' => [ 'config' => [ 'label' => __('GTIN'), 'componentType' => Field::NAME, 'formElement' => Input::NAME, 'dataType' => Number::NAME, 'dataScope' => 'gtin', 'sortOrder' => 92 ], ], ], ]; } /** * Check is current modifier for the product only * * @return bool */ public function isProductScopeOnly() { return false; } /** * Get sort order of modifier to load modifiers in the right order * * @return int */ public function getSortOrder() { return 32; } }
Acum, instalați extensia și verificați dacă totul este făcut corect, adică,
- php bin/modul magento: activați VendorName_OptionValueGtin
- php bin/magento setup:upgrade
- php bin/magento cache:flush
După cum puteți vedea, câmpul nou adăugat este afișat acum:
Pasul #4. Adăugarea setărilor pentru a dezactiva afișarea câmpului GTIN pentru Configurarea opțiunilor avansate de produs
Ce zici să amestecăm puțin articolul nostru?
Ofer să adaug o nouă funcționalitate - capacitatea de a activa/dezactiva afișarea câmpului GTIN pentru valorile opțiunilor de pe pagina de produs front-end.
Va trebui să creați fișierul:
`app/code/VendorName/OptionValueGtin/etc/adminhtml/system.xml`
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd"> <system> <tab sortOrder="2001"> <label>MageWorx</label> </tab> <section translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> <label><![CDATA[Advanced Product Options]]></label> <tab>mageworx</tab> <resource>VendorName_OptionValueGtin::config_optionvaluegtin</resource> <group translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1"> <label><![CDATA[Option Value GTIN]]></label> <field translate="label" type="select" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1"> <label><![CDATA[Enable Option's Value 'GTIN']]></label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> </group> </section> </system> </config>
Pentru simplitate:
Vom adăuga noua filă Option Value GTIN la configurația extensiei noastre Advanced Product Options. Ar trebui să puteți crea și o filă în modulul dvs.
Noua clasă de ajutor ar trebui creată. Acolo vom obține date despre setare.
Deci, să creăm și să completăm următoarea clasă:
`app/code/VendorName/OptionValueGtin/Helper/Data.php`
<?php namespace VendorName\OptionValueGtin\Helper; use Magento\Framework\App\Helper\AbstractHelper; use Magento\Store\Model\ScopeInterface; use Magento\Framework\App\Helper\Context; class Data extends AbstractHelper { const XML_PATH_DEFAULT_OPTION_VALUE_GTIN = 'mageworx_apo/optionvaluegtin/use_optionvaluegtin'; /** * Additional product attributes for product_attributes table * * @var array */ protected $additionalProductAttributes; /** * @param Context $context */ public function __construct( Context $context ) { parent::__construct($context); } /** * Check if option value GTIN enabled * * @param int|null $storeId * @return string */ public function isOptionValueGtinEnabled($storeId = null) { return $this->scopeConfig->getValue( self::XML_PATH_DEFAULT_OPTION_VALUE_GTIN, ScopeInterface::SCOPE_STORE, $storeId ); } }
Nu uitați să salvați modificările și să ștergeți memoria cache.

Setarea ar trebui să fie afișată în panoul de administrare.
Pasul #5. Afișarea câmpului nou pe pagina de produs front-end
Îți amintești despre ce am vorbit în articolul anterior?
Am menționat că modulul nostru MageWorx_OptionBase are deja metoda `getExtendedOptionsConfig()` care colectează și afișează toate atributele noastre personalizate pe front-end prin intermediul blocurilor.
Pentru a vedea cum este implementat, deschideți următoarea clasă:
`app/code/MageWorx/OptionBase/Block/Product/View/Options.php`
Acum:
Creați un model cu atributul nostru:
`app/code/VendorName/OptionValueGtin/Model/Attribute/OptionValue/Gtin.php`
<?php namespace VendorName\OptionValueGtin\Model\Attribute\OptionValue; use MageWorx\OptionBase\Model\Product\Option\AbstractAttribute; class Gtin extends AbstractAttribute { /** * @return string */ public function getName() { return 'gtin'; } }
Prin injecția de dependență , adăugați atributul la blocul de atribute generale al extensiei Advanced Product Options și creați următorul fișier:
`app/code/VendorName/OptionValueGtin/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"> <!-- Data --> <type name="MageWorx\OptionBase\Model\Product\Option\Value\Attributes"> <arguments> <argument name="data" xsi:type="array"> <item name="gtin" xsi:type="object">VendorName\OptionValueGtin\Model\Attribute\OptionValue\Gtin</item> </argument> </arguments> </type> </config>
Acum:
Creați noul nostru bloc și un șablon pentru acesta:
`app/code/VendorName/OptionValueGtin/Block/ValueGtin.php`
<?php namespace MageWorx\OptionValueGtin\Block; use Magento\Framework\Json\EncoderInterface; use Magento\Framework\View\Element\Template; use Magento\Framework\View\Element\Template\Context; use MageWorx\OptionValueGtin\Helper\Data as Helper; class ValueGtin extends Template { /** * @var EncoderInterface */ protected $jsonEncoder; /** * @var Helper */ protected $helper; /** * @param Context $context * @param EncoderInterface $jsonEncoder * @param Helper $helper * @param array $data */ public function __construct( Context $context, EncoderInterface $jsonEncoder, Helper $helper, array $data = [] ) { parent::__construct( $context, $data ); $this->jsonEncoder = $jsonEncoder; $this->helper = $helper; } /** * @return string */ public function getJsonData() { $data = [ 'isOptionValueGtinEnabled' => $this->helper->isOptionValueGtinEnabled($this->_storeManager->getStore()) ]; return $this->jsonEncoder->encode($data); } }
Aici, am obținut date despre setare de la Clasa de ajutor.
Următorul:
Folosind metoda `getJsonData()`, să redăm date către front-end folosind șablonul pe care urmează să-l creăm:
`app/code/VendorName/OptionValueGtin/view/frontend/templates/config.phtml`
<?php /** @var \VendorName\OptionValueGtin\Block\ValueGtin $block */ ?> <script> require([ 'jquery', 'optionValueGtin', 'uiRegistry' ], function ($, optionValueGtin, registry) { var optionBase = registry.get('mageworxOptionBase'); if (optionBase) { optionBase.addUpdater(7, optionValueGtin(<?= /* @noEscape */ $block->getJsonData() ?>)); } else { var updaters = registry.get('mageworxOptionUpdaters'); if (!updaters) { updaters = {}; } updaters[7] = optionValueGtin(<?= /* @noEscape */ $block->getJsonData() ?>); registry.set('mageworxOptionUpdaters', updaters); } }); </script>
Am folosit mecanismul mixins JavaScript pentru a afișa valorile pentru câmpul GTIN .
Ce urmeaza?
Să adoptăm o abordare diferită și să creăm un widget js, care va fi folosit pentru a afișa noile date pe pagina produsului.
Definiți noul js:
`app/code/VendorName/OptionValueGtin/view/frontend/requirejs-config.js`
var config = { map: { '*': { optionValueGtin: 'VendorName_OptionValueGtin/js/option-value-gtin' } } };
Este timpul să creați widgetul în sine. Acesta va conține toată logica în lucru cu noul atribut pe front-end.
În fișierul exemplu, să implementăm separat logica de afișare a GTIN pentru opțiunile de selectare și pentru opțiunile radio și casete de selectare.
Acestea vor fi două logici diferite, deoarece logica în lucru și marcarea unor astfel de opțiuni diferă una de cealaltă:
`app/code/VendorName/OptionValueGtin/view/frontend/web/js/option-value-gtin.js`
define([ 'jquery', 'Magento_Catalog/js/price-utils', 'underscore', 'jquery/ui' ], function ($, utils, _) { 'use strict'; $.widget('mageworx.optionValueGtin', { options: { optionConfig: {} }, /** * * @param optionConfig * @param productConfig * @param base * @param self */ firstRun: function firstRun(optionConfig, productConfig, base, self) { if (parseFloat(this.options.isOptionValueGtinEnabled)) { var extendedOptionsConfig = typeof base.options.extendedOptionsConfig != 'undefined' ? base.options.extendedOptionsConfig : {}; for (var option_id in optionConfig) { if (!optionConfig.hasOwnProperty(option_id)) { continue; } var $option = base.getOptionHtmlById(option_id); this._addValueGtin($option, optionConfig, extendedOptionsConfig); } } }, /** * Add description to the values * @param $option * @param optionConfig * @param extendedOptionsConfig * @private */ _addValueGtin: function _addValueGtin($option, optionConfig, extendedOptionsConfig) { var self = this, $options = $option.find('.product-custom-option'); //selectable options $options.filter('select').each(function (index, element) { var $element = $(element), optionId = utils.findOptionId($element), value = extendedOptionsConfig[optionId]['values']; if ($element.attr('multiple') && !$element.hasClass('mageworx-swatch')) { return; } if (typeof value == 'undefined' || _.isEmpty(value)) { return; } var gtinTitle = 'GTIN: '; var $gtin = $('<div class="option-value-gtin"></div>', { style: 'display: none' }); var $label = $option.find('.control'); $element.parent().prepend($gtin); $element.on('change', function (e) { var valueId = $element.val(); if (!_.isUndefined(value[valueId]) && !_.isEmpty(value[valueId]['gtin']) ) { if ($label.length > 0) { $label .first() .after($gtin.text(gtinTitle + value[valueId]['gtin'])); } $gtin.show(); } else { $gtin.hide(); } }); if ($element.val()) { $element.trigger('change'); } }); $options.filter('input[type="radio"], input[type="checkbox"]').each(function (index, element) { var $element = $(element), optionId = utils.findOptionId($element), value = extendedOptionsConfig[optionId]['values']; if ($element.attr('multiple') && !$element.hasClass('mageworx-swatch')) { return; } if (typeof value == 'undefined' || _.isEmpty(value)) { return; } var gtinTitle = 'GTIN: '; var $gtin = $('<div class="option-value-gtin-redio-check"></div>'); var $label = $option.find('.control'); $element.parent().append($gtin); var valueId = $element.val(); if (!_.isUndefined(value[valueId]) && !_.isEmpty(value[valueId]['gtin'])) { $gtin.text(gtinTitle + value[valueId]['gtin']); } if ($element.val()) { $element.trigger('change'); } }); }, }); return $.mageworx.optionValueGtin; });
Ce zici de adăugarea unor stiluri?
`app/code/VendorName/OptionValueGtin/view/frontend/web/css/valueGtin.css`
.option-value-gtin, .option-value-gtin-redio-check { color: #1da0e0; font-weight: 700; margin-top: 5px; } .option-value-gtin-redio-check { display: contents; }
Rămâne doar să ne conectăm blocul și stilurile.
Pentru asta, creați următorul fișier:
`app/code/VendorName/OptionValueGtin/view/frontend/layout/catalog_product_view.xml`
<?xml version="1.0"?> <page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <head> <css src="VendorName_OptionValueGtin::css/valueGtin.css"/> </head> <body> <referenceBlock name="product.info.options.wrapper"> <container name="vendorname.option.value.gtin.container" after="product.info.options"> <block class="VendorName\OptionValueGtin\Block\ValueGtin" name="vendorname.option.value.gtin" template="VendorName_OptionValueGtin::config.phtml"/> </container> </referenceBlock> </body> </page>
Aproape am terminat.
Înainte de a efectua verificarea finală, nu uitați să ștergeți memoria cache și să implementați din nou conținutul static:
- php bin/magento cache:flush
- php bin/magento static-content:deploy
Și, în sfârșit:
Conectați-vă la panoul de administrare.
Creați un produs cu opțiuni personalizate în produsul Magento.
În exemplul nostru, am adăugat meniul drop-down, swatch, radio și caseta de selectare.
Nu uitați să completați noile noastre câmpuri GTIN pentru valorile opțiunilor corespunzătoare.
Salvați produsul.
E timpul să vezi cum arată totul pe front-end:
Ce parere aveti despre rezultat?
Vă rugăm să împărtășiți feedbackul dvs. despre articol în câmpul de comentarii de mai jos. Cât de ușor a fost să adăugați un câmp Magento la opțiunile personalizate?