고급 제품 옵션에서 옵션 값에 대한 사용자 정의 필드를 추가하는 방법
게시 됨: 2020-11-20이전 기사에서 Magento 사용자 정의 옵션 필드를 만드는 방법을 배웠습니다. 또한 제품 페이지 프런트 엔드와 관리자 패널의 주문 페이지 모두에 필드 데이터를 표시하는 방법을 알아냈습니다.
지금은 무엇입니까?
옵션 값에 대해 동일한 사용자 지정 GTIN 필드를 추가하고 제품 페이지 프런트 엔드에 표시하는 방법을 알아보겠습니다.
목차
- 1 단계. 새 모듈 생성
- 1. 작곡가.json
- 2. etc/module.xml
- 3. 등록.php
- 2 단계. 데이터베이스에 새 필드 추가
- 3단계. 백엔드 작업을 위한 로직 추가
- 4단계. 고급 제품 옵션 구성에 대한 GTIN 필드 표시 비활성화 설정 추가
- 5단계. 제품 페이지 프런트 엔드에 새 필드 표시
1 단계. 새 모듈 생성
이 Mageworx 블로그 게시물에서 프로세스에 대해 자세히 다뤘던 새로운 모듈 생성부터 시작하겠습니다.
따라서 더 이상 고민하지 않고 여기에 필요한 코드가 있습니다.
1. 작곡가.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. 등록.php
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'VendorName_OptionValueGtin', __DIR__ );
2 단계. 데이터베이스에 새 필드 추가
GTIN 필드를 만들고 데이터베이스의 해당 테이블에 추가할 차례입니다.
옵션 값에 대한 필드를 추가함에 따라 `catalog_product_option_type_value` 테이블이 필요합니다.
다음 파일을 만들어 봅시다.
`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(); } }
3단계. 백엔드 작업을 위한 로직 추가
풀 수정자 메커니즘을 사용하여 Magento가 사용자 지정 옵션에 필드를 추가합니다.
다음 파일을 만들어 봅시다.
`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>
여기:
Magento 2용 고급 제품 옵션 확장의 일반 풀에 수정자를 추가합니다―
`MageWorx\OptionBase\Ui\DataProvider\Product\Form\Modifier\Pool`.
`VendorName\OptionValueGtin\Ui\DataProvider\Product\Form\Modifier\OptionValueGtin`은 수정자 클래스입니다.
아래에:
`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; } }
이제 확장 프로그램을 설치하고 모든 작업이 올바르게 수행되었는지 확인합니다. 즉,
- php bin/magento 모듈: VendorName_OptionValueGtin 활성화
- php bin/magento 설정:업그레이드
- PHP bin/magento 캐시:플러시
보시다시피 새로 추가된 필드가 이제 표시됩니다.
4단계. 고급 제품 옵션 구성에 대한 GTIN 필드 표시 비활성화 설정 추가
우리 기사를 약간 섞는 것은 어떻습니까?
제품 페이지 프런트 엔드에서 옵션 값에 대한 GTIN 필드 표시를 활성화/비활성화하는 기능과 같은 몇 가지 새로운 기능을 추가할 것을 제안합니다.
파일을 생성해야 합니다.
`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>
단순함을 위해:
고급 제품 옵션 확장의 구성에 새 옵션 값 GTIN 탭을 추가합니다. 모듈에서도 탭을 만들 수 있어야 합니다.
새 도우미 클래스 를 만들어야 합니다. 거기에서 설정에 대한 데이터를 얻습니다.
따라서 다음 클래스를 만들고 채우도록 합시다.
`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 ); } }
변경 사항을 저장하고 캐시를 지우는 것을 잊지 마십시오.
설정이 관리자 패널에 표시되어야 합니다.
5단계. 제품 페이지 프런트 엔드에 새 필드 표시
이전 기사에서 우리가 말한 것을 기억하십니까?
MageWorx_OptionBase 모듈에는 블록을 통해 프런트 엔드에서 모든 사용자 정의 속성을 수집하고 표시하는 `getExtendedOptionsConfig()` 메서드가 이미 있다고 언급했습니다.
구현 방법을 보려면 다음 클래스를 엽니다.
`앱/코드/MageWorx/OptionBase/Block/Product/View/Options.php`
지금:
속성으로 모델을 만듭니다.
`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'; } }
종속성 주입 을 통해 고급 제품 옵션 확장의 일반 속성 블록에 속성을 추가하고 다음 파일을 생성합니다.
`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>
지금:
새 블록과 이에 대한 템플릿을 만듭니다.
`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); } }
여기에서는 도우미 클래스에서 설정에 대한 데이터를 얻었습니다.
다음:
`getJsonData()` 메서드를 사용하여 만들려는 템플릿을 사용하여 프런트 엔드에 데이터를 렌더링해 보겠습니다.
`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>
GTIN 필드의 값을 표시하기 위해 JavaScript 믹스 인 메커니즘을 사용했습니다.
무엇 향후 계획?
다른 접근 방식을 사용하여 제품 페이지에 새 데이터를 표시하는 데 사용할 js 위젯을 만들어 보겠습니다.
새 js를 정의합니다.
`app/code/VendorName/OptionValueGtin/view/frontend/requirejs-config.js`
var config = { map: { '*': { optionValueGtin: 'VendorName_OptionValueGtin/js/option-value-gtin' } } };
위젯 자체를 만들 시간입니다. 프론트 엔드에 새 속성이 있는 작업의 모든 논리가 포함됩니다.
예제 파일에서 선택 옵션에 대한 GTIN 의 표시 논리를 구현하고 라디오 및 확인란 옵션을 별도로 구현해 보겠습니다.
작업의 논리와 이러한 옵션의 마크업이 서로 다르기 때문에 이러한 논리는 두 가지 다른 논리가 됩니다.
`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; });
스타일을 추가해 보는 건 어떠세요?
`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; }
블록과 스타일을 연결하는 것만 남아 있습니다.
이를 위해 다음 파일을 만듭니다.
`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>
거의 다 끝났습니다.
최종 확인을 실행하기 전에 캐시를 지우고 정적 콘텐츠를 다시 배포하는 것을 잊지 마십시오.
- PHP bin/magento 캐시:플러시
- PHP bin/magento 정적 콘텐츠:배포
그리고 마지막으로:
관리자 패널에 로그인합니다.
Magento 제품에서 사용자 지정 옵션으로 제품을 만듭니다.
이 예에서는 드롭다운, 견본, 라디오 및 확인란을 추가했습니다.
해당 옵션 값에 대해 새 GTIN 필드를 작성하는 것을 잊지 마십시오.
제품을 저장합니다.
프론트 엔드에서 모든 것이 어떻게 보이는지 확인할 시간:
결과에 대해 어떻게 생각하세요?
아래 댓글 필드에서 기사에 대한 피드백을 공유해 주세요. Magento가 사용자 지정 옵션에 필드를 추가하는 것이 얼마나 쉬웠습니까?