추천 레이블 표시 - Magento 2

22784 단어 magento2
다음은 사이트의 상품 상세 페이지 및 모든 상품 목록 섹션에 상품 라벨을 표시해 달라는 요청이 있는 경우에 도움이 됩니다.
섹션 나열:
  • 제품 상세 페이지 - 제품 콘텐츠 영역(catalog_product_view.xml)
  • 카테고리 페이지(catalog_category_view.xml)
  • 페이지 빌더 제품 위젯(catalog_widget_product_list.xml)
  • 상향 판매 및 관련 제품(catalog_product_view.xml)
  • 크로스셀(checkout_cart_index.xml)
  • 검색(catalogsearch_result_index.xml)
  • 고급 검색(catalogsearch_advanced_result.xml)

  • 1) 사용자 정의 속성 생성

    앱/코드/공급업체/FeaturedLabel/Setup/Patch/Data/AddFeaturedLabelProductAttribute.php

    namespace Vendor\FeaturedLabel\Setup\Patch\Data;
    
    use Magento\Catalog\Model\Product;
    use Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend;
    use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
    use Magento\Eav\Setup\EavSetup;
    use Magento\Eav\Setup\EavSetupFactory;
    use Magento\Framework\Setup\ModuleDataSetupInterface;
    use Magento\Framework\Setup\Patch\DataPatchInterface;
    use Magento\Framework\Setup\Patch\PatchRevertableInterface;
    
    class AddFeaturedLabelProductAttribute implements DataPatchInterface, PatchRevertableInterface
    {
        /**
         * @var ModuleDataSetupInterface
         */
        private $moduleDataSetup;
        /**
         * @var EavSetupFactory
         */
        private $eavSetupFactory;
    
        /**
         * Constructor
         *
         * @param ModuleDataSetupInterface $moduleDataSetup
         * @param EavSetupFactory $eavSetupFactory
         */
        public function __construct(
            ModuleDataSetupInterface $moduleDataSetup,
            EavSetupFactory $eavSetupFactory
        ) {
            $this->moduleDataSetup = $moduleDataSetup;
            $this->eavSetupFactory = $eavSetupFactory;
        }
    
        /**
         * {@inheritdoc}
         */
        public function apply()
        {
            $this->moduleDataSetup->getConnection()->startSetup();
            /** @var EavSetup $eavSetup */
            $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
            $eavSetup->addAttribute(
                Product::ENTITY,
                'featured_label',
                [
                    'type' => 'int',
                    'label' => 'Featured Label',
                    'input' => 'select',
                    'source' => '',
                    'required' => false,
                    'backend' => ArrayBackend::class,
                    'sort_order' => '30',
                    'global' => ScopedAttributeInterface::SCOPE_STORE,
                    'default' => null,
                    'visible' => true,
                    'user_defined' => true,
                    'searchable' => true,
                    'filterable' => true,
                    'comparable' => false,
                    'visible_on_front' => false,
                    'unique' => false,
                    'apply_to' => '',
                    'group' => 'General',
                    'used_in_product_listing' => true,
                    'is_used_in_grid' => true,
                    'is_visible_in_grid' => false,
                    'is_filterable_in_grid' => false,
                    'option' => ''
                ]
            );
    
            $this->moduleDataSetup->getConnection()->endSetup();
        }
    
        public function revert()
        {
            $this->moduleDataSetup->getConnection()->startSetup();
            /** @var EavSetup $eavSetup */
            $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
            $eavSetup->removeAttribute(Product::ENTITY, 'featured_label');
    
            $this->moduleDataSetup->getConnection()->endSetup();
        }
    
        /**
         * {@inheritdoc}
         */
        public function getAliases()
        {
            return [];
        }
    
        /**
         * {@inheritdoc}
         */
        public static function getDependencies()
        {
            return [
    
            ];
        }
    }
    


    2) 레이블을 표시할 하나의 템플릿을 만듭니다.

    app/code/Vendor/FeaturedLabel/view/frontend/templates/product/featured_label.phtml

    /** @var $block \Magento\Catalog\Block\Product\View */
    /* @var $product Vendor\FeaturedLabel\ViewModel\Product */
    /* @var $featuredLabel Vendor\FeaturedLabel\ViewModel\FeaturedLabel */
    
    $product = $block->getData('product');
    $featuredLabel = $block->getData('featured_label_widget');
    ?>
    <?php $currentProduct = $product->getCurrentProduct() ?: $product; ?>
    
    <?php if ($featuredLabel->getFeaturedLabel($currentProduct)): ?>
        <div class="featured-label">
            <?= $block->escapeHtml(__($featuredLabel->getFeaturedLabel($currentProduct))) ?>
        </div>
    <?php endif; ?>
    


    3) 레이블용 viewModel 생성
    참고: 현재 제품은 제품 인터페이스로 전달됩니다.

    앱/코드/공급업체/FeaturedLabel/ViewModel/FeaturedLabel.php

    namespace Vendor\FeaturedLabel\ViewModel;
    
    use Magento\Catalog\Api\Data\ProductInterface;
    use Magento\Framework\View\Element\Block\ArgumentInterface;
    
    class FeaturedLabel implements ArgumentInterface
    {
        /**
         * @param ProductInterface $product
         * @return false|\Magento\Framework\Phrase
         */
        public function getFeaturedLabel(ProductInterface $product)
        {
            if ($product->getAttributeText('featured_label')) {
                return $product->getAttributeText('featured_label');
            } 
    }
    


    4) 모델을 보고 현재 제품을 가져옵니다.

    앱/코드/공급업체/카탈로그/ViewModel/Product.php

    namespace Vendor\Catalog\ViewModel;
    
    use Magento\Catalog\Api\Data\ProductInterface;
    use Magento\Framework\Registry;
    use Magento\Framework\View\Element\Block\ArgumentInterface;
    
    class Product implements ArgumentInterface
    {
        /**
         * @var Registry
         */
        private $registry;
    
        /**
         * @var ProductInterface
         */
        private $product;
    
        public function __construct(
            Registry $registry,
            array $data = []
        ) {
            $this->registry = $registry;
        }
    
        public function getCurrentProduct(): ProductInterface
        {
            if (is_null($this->product)) {
                $this->product = $this->registry->registry('current_product');
            }
            return $this->product;
        }
    }
    


    5) 상품 상세 페이지에 라벨 추가 - 상품 콘텐츠 영역, 상향 판매, 관련 상품

    앱/코드/공급업체/FeaturedLabel/view/frontend/layout/catalog_product_view.xml

    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
        <body>
            <referenceContainer name="product.info.media">
                <block class="Magento\Catalog\Block\Product\View"
                       name="product.featured.label"
                       template="Vendor_FeaturedLabel::product/featured_label.phtml"
                       before="-">
                    <arguments>
                        <argument name="product" xsi:type="object">Vendor\FeaturedLabel\ViewModel\Product</argument>
                        <argument name="featured_label_widget" xsi:type="object">Vendor\FeaturedLabel\ViewModel\FeaturedLabel</argument>
                    </arguments>
                </block>
            </referenceContainer>
    
            <referenceBlock name="catalog.product.related" template="Magento_Catalog::product/list/items.phtml">
                <block name="product.related.featured.label"
                       as="featured.label"
                       template="Vendor_FeaturedLabel::product/featured_label.phtml">
                    <arguments>
                        <argument name="product" xsi:type="object">Vendor\FeaturedLabel\ViewModel\Product</argument>
                        <argument name="featured_label_widget" xsi:type="object">Vendor\FeaturedLabel\ViewModel\FeaturedLabel</argument>
                    </arguments>
                </block>
            </referenceBlock>
    
            <referenceBlock name="product.info.upsell" template="Magento_Catalog::product/list/items.phtml">
                <block name="product.upsell.featured.label"
                       as="featured.label"
                       template="Vendor_FeaturedLabel::product/featured_label.phtml">
                    <arguments>
                        <argument name="product" xsi:type="object">Vendor\FeaturedLabel\ViewModel\Product</argument>
                        <argument name="featured_label_widget" xsi:type="object">Vendor\FeaturedLabel\ViewModel\FeaturedLabel</argument>
                    </arguments>
                </block>
            </referenceBlock>
        </body>
    </page>
    


    6) 카테고리 페이지 app/code/Vendor/FeaturedLabel/view/frontend/layout/catalog_category_view.xml

    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
        <body>
            <referenceBlock name="category.products.list" template="Vendor_Catalog::product/list.phtml">
                <block name="category.product.featured.label"
                       as="featured.label"
                       template="Vendor_FeaturedLabel::product/featured_label.phtml">
                    <arguments>
                        <argument name="product" xsi:type="object">Vendor\Catalog\ViewModel\Product</argument>
                        <argument name="featured_label_widget" xsi:type="object">Vendor\FeaturedLabel\ViewModel\FeaturedLabel</argument>
                    </arguments>
                </block>
            </referenceBlock>
        </body>
    </page>
    


    7) 페이지 빌더 제품 위젯
    a) 앱/코드/벤더/카탈로그/블록/제품/제품목록.php

    namespace Vendor\Catalog\Block\Product;
    
    use Magento\Catalog\Api\CategoryRepositoryInterface;
    use Magento\Catalog\Api\Data\ProductInterface;
    use Magento\Catalog\Block\Product\Context as ProductContext;
    use Magento\Catalog\Model\Product\Visibility;
    use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
    use Magento\CatalogWidget\Block\Product\ProductsList as DefaultProductsList;
    use Magento\CatalogWidget\Model\Rule;
    use Magento\Framework\App\Http\Context;
    use Magento\Framework\DataObject\IdentityInterface;
    use Magento\Framework\Serialize\Serializer\Json;
    use Magento\Framework\Url\EncoderInterface;
    use Magento\Framework\View\Element\BlockInterface;
    use Magento\Framework\View\LayoutFactory;
    use Magento\Rule\Model\Condition\Sql\Builder;
    use Magento\Widget\Block\BlockInterface as WidgetBlockInterface;
    use Magento\Widget\Helper\Conditions;
    
    class ProductsList extends DefaultProductsList implements WidgetBlockInterface, IdentityInterface
    {
        /**
         * @var LayoutFactory
         */
        private $layoutFactory;
    
        /**
         * @var Json
         */
        private $json;
    
        /**
         * @var EncoderInterface
         */
        private $urlEncoder;
    
        /**
         * @var array
         */
        private $layoutBlocks = [];
    
        /**
         * ProductsList constructor.
         * @param ProductContext $context
         * @param CollectionFactory $productCollectionFactory
         * @param Visibility $catalogProductVisibility
         * @param Context $httpContext
         * @param Builder $sqlBuilder
         * @param Rule $rule
         * @param Conditions $conditionsHelper
         * @param CategoryRepositoryInterface $categoryRepository
         * @param LayoutFactory $layoutFactory
         * @param Json $json
         * @param EncoderInterface $urlEncoder
         * @param array $data
         */
        public function __construct(
            ProductContext $context,
            CollectionFactory $productCollectionFactory,
            Visibility $catalogProductVisibility,
            Context $httpContext,
            Builder $sqlBuilder,
            Rule $rule,
            Conditions $conditionsHelper,
            CategoryRepositoryInterface $categoryRepository,
            LayoutFactory $layoutFactory,
            Json $json,
            EncoderInterface $urlEncoder,
            array $data = []
        ) {
            $this->layoutFactory = $layoutFactory;
            $this->json = $json;
            $this->urlEncoder = $urlEncoder;
    
            parent::__construct(
                $context,
                $productCollectionFactory,
                $catalogProductVisibility,
                $httpContext,
                $sqlBuilder,
                $rule,
                $conditionsHelper,
                $categoryRepository,
                $data,
                $json,
                $layoutFactory,
                $urlEncoder
            );
        }
    
        /**
         * @param $name
         * @return mixed|null
         * @throws \Magento\Framework\Exception\LocalizedException
         */
        public function getBlockFromLayout($name)
        {
            $layoutBlock = isset($this->layoutBlocks[$name]) ? $this->layoutBlocks[$name] : null;
    
            if (!$layoutBlock) {
                $layout = $this->layoutFactory->create(['cacheable' => false]);
                $layout->getUpdate()->addHandle('catalog_widget_product_list')->load();
                $layout->generateXml();
                $layout->generateElements();
                $layoutBlock = $layout->getBlock($name);
                $this->layoutBlocks[$name] = $layoutBlock;
            }
    
            return $layoutBlock;
        }
    }
    


    b) 앱/코드/공급업체/FeaturedLabel/etc/widget.xml

    <widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Widget:etc/widget.xsd">
        <widget id="products_list" class="Vendor\Catalog\Block\Product\ProductsList">
            <label translate="true">Catalog Products List</label>
            <description translate="true">List of Products</description>
        </widget>
    </widgets>
    


    c) app/code/Vendor/FeaturedLabel/view/adminhtml/web/js/content-type/products/mass-converter/carousel-widget-directive.js

    define([
        'Magento_PageBuilder/js/content-type/products/mass-converter/carousel-widget-directive',
        'Magento_PageBuilder/js/utils/object'
    ], function (OriginalCarouselWidgetDirective, _object) {
        'use strict';
    
        function CarouselWidgetDirective() {
            OriginalCarouselWidgetDirective.apply(this, arguments);
        }
    
        CarouselWidgetDirective.prototype = Object.create(OriginalCarouselWidgetDirective.prototype);
    
        /**
         * Override the toDom function to pass new 'type' and 'template' parameters.
         *
         * @param data
         * @param config
         * @returns {*}
         */
        CarouselWidgetDirective.prototype.toDom = function toDom(data, config) {
            var attributes = {
                type: "Vendor\\Catalog\\Block\\Product\\ProductsList",
                template: "Vendor_FeaturedLabel::product/widget/content/carousel.phtml",
                anchor_text: "",
                id_path: "",
                show_pager: 0,
                products_count: data.carousel_products_count,
                condition_option: data.condition_option,
                condition_option_value: "",
                type_name: "Catalog Products Carousel",
                conditions_encoded: this.encodeWysiwygCharacters(data.conditions_encoded || "")
            };
    
            if (data.sort_order) {
                attributes.sort_order = data.sort_order;
            }
    
            if (typeof data[data.condition_option] === "string") {
                attributes.condition_option_value = this.encodeWysiwygCharacters(data[data.condition_option]);
            }
    
            if (attributes.conditions_encoded.length === 0) {
                return data;
            }
    
            _object.set(data, config.html_variable, this.buildDirective(attributes));
            return data;
        };
    
        return CarouselWidgetDirective;
    });
    


    d) app/code/Vendor/FeaturedLabel/view/adminhtml/web/js/content-type/products/mass-converter/widget-directive.js

    define([
        'Magento_PageBuilder/js/content-type/products/mass-converter/widget-directive',
        'Magento_PageBuilder/js/utils/object'
    ], function (OriginalWidgetDirective, _object) {
        'use strict';
    
        function WidgetDirective() {
            OriginalWidgetDirective.apply(this, arguments);
        }
    
        WidgetDirective.prototype = Object.create(OriginalWidgetDirective.prototype);
    
        /**
         * Override the toDom function to pass new 'type' and 'template' parameters.
         *
         * @param data
         * @param config
         * @returns {*}
         */
        WidgetDirective.prototype.toDom = function toDom(data, config) {
            var attributes = {
                type: "Vendor\\Catalog\\Block\\Product\\ProductsList",
                template: "Vendor_FeaturedLabel::product/widget/content/grid.phtml",
                anchor_text: "",
                id_path: "",
                show_pager: 0,
                products_count: data.products_count,
                condition_option: data.condition_option,
                condition_option_value: "",
                type_name: "Catalog Products List",
                conditions_encoded: this.encodeWysiwygCharacters(data.conditions_encoded || "")
            };
    
            if (data.sort_order) {
                attributes.sort_order = data.sort_order;
            }
    
            if (typeof data[data.condition_option] === "string") {
                attributes.condition_option_value = this.encodeWysiwygCharacters(data[data.condition_option]);
            }
    
            if (attributes.conditions_encoded.length === 0) {
                return data;
            }
    
            _object.set(data, config.html_variable, this.buildDirective(attributes));
            return data;
        };
    
        return WidgetDirective;
    });
    


    e) 앱/코드/공급업체/FeaturedLabel/view/adminhtml/pagebuilder/content_type/products.xml

    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_PageBuilder:etc/content_type.xsd">
        <type name="products">
            <appearances>
                <appearance name="grid">
                    <converters>
                        <converter component="Vendor_FeaturedLabel/js/content-type/products/mass-converter/widget-directive" name="widget_directive">
                            <config>
                                <item name="html_variable" value="html"/>
                            </config>
                        </converter>
                    </converters>
                </appearance>
                <appearance name="carousel">
                    <converters>
                        <converter component="Vendor_FeaturedLabel/js/content-type/products/mass-converter/carousel-widget-directive" name="widget_directive">
                            <config>
                                <item name="html_variable" value="html"/>
                            </config>
                        </converter>
                    </converters>
                </appearance>
            </appearances>
        </type>
    </config>
    


    f) 앱/코드/공급업체/FeaturedLabel/view/frontend/layout/catalog_widget_product_list.xml

    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
        <body>
            <block name="category.products.list.featured.label"
                   as="featured.label.top"
                   template="Vendor_FeaturedLabel::product/featured_label.phtml">
                <arguments>
                    <argument name="product" xsi:type="object">Vendor\Catalog\ViewModel\Product</argument>
                    <argument name="featured_label_widget" xsi:type="object">Vendor\FeaturedLabel\ViewModel\FeaturedLabel</argument>
                </arguments>
            </block>
        </body>
    </page>
    


    8) 템플릿 파일
  • 제품 상세 페이지 - 제품 콘텐츠 영역(catalog_product_view.xml)
  • 카테고리 페이지(catalog_category_view.xml)
  • 페이지 빌더 제품 위젯(catalog_widget_product_list.xml)
  • 상향 판매 및 관련 제품(catalog_product_view.xml)
  • 크로스셀(checkout_cart_index.xml)
  • 검색(catalogsearch_result_index.xml)
  • 고급 검색(catalogsearch_advanced_result.xml)

  • a) 카테고리 페이지/고급 검색/검색 - view/frontend/templates/product/list.phtml

    <?php if ($featuredLabel = $block->getChildBlock('featured.label')): ?>
        <?= /* @noEscape */ $featuredLabel->setData('product', $product)->toHtml() ?>
    <?php endif; ?>
    


    b) Crossell/Upsell 및 관련 제품 목록
    보기/프론트엔드/템플릿/제품/목록/항목

    <?php if ($featuredLabel = $block->getChildBlock('featured.label')): ?>
        <?= /* @noEscape */ $featuredLabel->setData('product', $item)->toHtml() ?>
    <?php endif; ?>
    


    b) 페이지 빌더 제품 위젯(carosal)

    <?php if ($featureLabel = $block->getBlockFromLayout('category.products.list.featured.label')): ?>
        <?= /* @noEscape */ $featureLabel->setData('product', $_item)->toHtml() ?>
    <?php endif; ?>
    


    c) 페이지 빌더 제품 위젯(그리드)

    <?php if ($featuredLabel = $block->getBlockFromLayout('category.products.list.featured.label')): ?>
        <?= /* @noEscape */ $featuredLabel->setData('product', $_item)->toHtml() ?>
    <?php endif; ?>
    

    좋은 웹페이지 즐겨찾기