Sağ Temel Ayarlar altında, ürün düzenleme sayfasında yeni bir sekme ekleyecek özel bir modül oluşturmaya çalışıyorum. Birisi cevap verebilir mi?
Sağ Temel Ayarlar altında, ürün düzenleme sayfasında yeni bir sekme ekleyecek özel bir modül oluşturmaya çalışıyorum. Birisi cevap verebilir mi?
Yanıtlar:
[EDIT] bu artık magento 2.1 için çalışmıyor
kendi modülünüzü oluşturabilirsiniz.
Bu modülde, view/adminhtml/layout/catalog_product_new.xml
bu içerikle adlandırılan bir dosya oluşturun
<?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="product_tabs">
<action method="addTabAfter">
<argument name="tabId" xsi:type="string">tab-code-here</argument>
<argument name="tab" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Tab label here</item>
<item name="class" xsi:type="string">ajax</item>
<item name="url" xsi:type="helper" helper="[Namespace]\[Module]\Helper\Url::getUrl" />
<item name="group_code" xsi:type="string">basic</item>
</argument>
<argument name="after" xsi:type="string">product-details</argument>
</action>
</referenceBlock>
</body>
</page>
ardından Helper/Url.php
bu içeriğe sahip dosyayı oluşturun :
<?php
namespace [Namespace]\[Module]\Helper;
class Url
{
/**
* @var \Magento\Framework\UrlInterface
*/
protected $urlBuilder;
/**
* @param \Magento\Framework\UrlInterface $urlBuilder
*/
public function __construct(
\Magento\Framework\UrlInterface $urlBuilder
)
{
$this->urlBuilder = $urlBuilder;
}
public function getUrl()
{
return $this->urlBuilder->getUrl('your_tab/url/here', ['_current' => true]);
}
}
bu, sekmeyi "Ürün Ayrıntıları" sekmesinden hemen sonra ekler. Yeniden konumlandırmak için xml dosyasındaki parametrelerle oynayın.
**
Aşağıdaki kod Özellikle Magento 2.2.0 ve üstü için
**
Satıcı / Modül / registration.php kodun altına koyulur.
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Vendor_Module',
__DIR__
);
module.xml dosyasını aşağıdaki kodun altına Satıcı / Modül / etc / module.xml dosyasına ekleyin.
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
<module name="Vendor_Module" setup_version="1.0.0"></module>
</config>
Şimdi uicomponent formunu oluşturun xml Satıcı / Modül / view / adminhtml / ui_component / product_form.xml kodun altına yerleştirin.
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<fieldset name="testingproduct">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Testing Group</item>
<item name="provider" xsi:type="string">product</item>
<item name="dataScope" xsi:type="string">data.product</item>
<item name="sortOrder" xsi:type="number">2</item>
<item name="collapsible" xsi:type="boolean">true</item>
<item name="opened" xsi:type="boolean">false</item>
<item name="ns" xsi:type="string">product_form</item>
</item>
</argument>
<container name="testing_group">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="sortOrder" xsi:type="number">1</item>
</item>
</argument>
<htmlContent name="html_content">
<argument name="block" xsi:type="object">Vendor\Module\Block\Adminhtml\Product\Edit\Tab\CustomData</argument>
</htmlContent>
</container>
</fieldset>
</form>
Blok Satıcısı / Modülü / Blok / Adminhtml / Ürün / Düzenle / CustomData.php'de aşağıdaki kodu yazın.
<?php
namespace Vendor\Module\Block\Adminhtml\Product\Edit\Tab;
use Magento\Backend\Block\Template\Context;
use Magento\Framework\Registry;
class CustomData extends \Magento\Framework\View\Element\Template
{
protected $_template = 'customdata.phtml';
protected $_coreRegistry = null;
public function __construct(
Context $context,
Registry $registry,
array $data = []
)
{
$this->_coreRegistry = $registry;
parent::__construct($context, $data);
}
public function getProduct()
{
return $this->_coreRegistry->registry('current_product');
}
}
Şablonlarda Satıcı / Modül / görünüm / adminhtml / templates / customdata.phtml kodun altına koyun.
<div>
<span><?php echo __("Some Custom Data");?></span>
</div>
Magento 2.1: -Megento 2.1 varsa, ürün düzenleme sayfasında basit sekme eklemek için de bu kodu kullanın. Kendi modülünü oluşturun ve aşağıdaki kodu view / adminhtml / layout / catalog_product_new.xml dizinine yerleştirin
<?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="product_form">
<block class="Vendor\Module\Block\Adminhtml\Product\Edit\Tab\Welcome" name="product.welcome" as="custom-tab" >
<arguments>
<argument name="config" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Product Welcome</item>
<item name="collapsible" xsi:type="boolean">true</item>
<item name="opened" xsi:type="boolean">true</item>
<item name="sortOrder" xsi:type="string">2</item>
<item name="canShow" xsi:type="boolean">true</item>
<item name="componentType" xsi:type="string">fieldset</item>
</argument>
</arguments>
</block>
</referenceBlock>
</body>
</page>
Blokta Satıcı / Modül / Blok / Adminhtml / Ürün / Düzenle / Sekme / Welcome.php kodunu aşağıya yazın.
<?php
namespace Vendor\Module\Block\Adminhtml\Product\Edit\Tab;
use Magento\Backend\Block\Template\Context;
use Magento\Framework\Registry;
class Welcome extends \Magento\Framework\View\Element\Template
{
protected $_template = 'catalog/product/edit/welcome.phtml';
protected $_coreRegistry = null;
public function __construct(
Context $context,
Registry $registry,
array $data = []
)
{
$this->_coreRegistry = $registry;
parent::__construct($context, $data);
}
public function getProduct()
{
return $this->_coreRegistry->registry('current_product');
}
}
Şablonlarda Satıcı / Modül / görünüm / adminhtml / şablonlar / katalog / ürün / edit / welcome.phtml kodun altına koyun.
<div class="welcome">
<?php echo __('Welcome !'); ?>
</div>
Şimdi Ürün düzenleme sayfasını kontrol edin. Mükemmel çalışıyor.
Magento 2.1.0 sürümüne sekme eklemek için aşağıdaki kodu kullanın
oluşturmak satıcı / modül / etc / di.xml
<?xml version="1.0"?>
<!--
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool" type="Magento\Ui\DataProvider\Modifier\Pool">
<arguments>
<argument name="modifiers" xsi:type="array">
<item name="customertab" xsi:type="array">
<item name="class" xsi:type="string">Vendor\Module\Ui\DataProvider\Product\Modifier\Customertab</item>
<item name="sortOrder" xsi:type="number">200</item>
</item>
</argument>
</arguments>
</virtualType>
<type name="Vendor\Module\Ui\DataProvider\Product\Modifier\Customertab">
<arguments>
<argument name="scopeName" xsi:type="string">product_form.product_form</argument>
</arguments>
</type>
</config>
dosya oluştur Satıcı \ Modül \ Ui \ DataProvider \ Product \ Modifier \ Customertab.php
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Vendor\Module\Ui\DataProvider\Product\Modifier;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Api\Data\ProductLinkInterface;
use Magento\Catalog\Api\ProductLinkRepositoryInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Locator\LocatorInterface;
use Magento\Eav\Api\AttributeSetRepositoryInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Phrase;
use Magento\Framework\UrlInterface;
use Magento\Ui\Component\DynamicRows;
use Magento\Ui\Component\Form\Element\DataType\Number;
use Magento\Ui\Component\Form\Element\DataType\Text;
use Magento\Ui\Component\Form\Element\Input;
use Magento\Ui\Component\Form\Field;
use Magento\Ui\Component\Form\Fieldset;
use Magento\Ui\Component\Modal;
use Magento\Catalog\Helper\Image as ImageHelper;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
/**
* Class Customertab
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Customertab extends AbstractModifier
{
const DATA_SCOPE = '';
const DATA_SCOPE_CUSTOMER = 'customertab';
const GROUP_CUSTOMERTAB = 'customertab';
/**
* @var string
*/
private static $previousGroup = 'search-engine-optimization';
/**
* @var int
*/
private static $sortOrder = 90;
/**
* @var LocatorInterface
*/
protected $locator;
/**
* @var UrlInterface
*/
protected $urlBuilder;
/**
* @var ProductLinkRepositoryInterface
*/
protected $productLinkRepository;
/**
* @var ProductRepositoryInterface
*/
protected $productRepository;
/**
* @var ImageHelper
*/
protected $imageHelper;
/**
* @var Status
*/
protected $status;
/**
* @var AttributeSetRepositoryInterface
*/
protected $attributeSetRepository;
/**
* @var string
*/
protected $scopeName;
/**
* @var string
*/
protected $scopePrefix;
/**
* @var \Magento\Catalog\Ui\Component\Listing\Columns\Price
*/
private $priceModifier;
/**
* @param LocatorInterface $locator
* @param UrlInterface $urlBuilder
* @param ProductLinkRepositoryInterface $productLinkRepository
* @param ProductRepositoryInterface $productRepository
* @param ImageHelper $imageHelper
* @param Status $status
* @param AttributeSetRepositoryInterface $attributeSetRepository
* @param string $scopeName
* @param string $scopePrefix
*/
public function __construct(
LocatorInterface $locator,
UrlInterface $urlBuilder,
ProductLinkRepositoryInterface $productLinkRepository,
ProductRepositoryInterface $productRepository,
ImageHelper $imageHelper,
Status $status,
AttributeSetRepositoryInterface $attributeSetRepository,
$scopeName = '',
$scopePrefix = ''
) {
$this->locator = $locator;
$this->urlBuilder = $urlBuilder;
$this->productLinkRepository = $productLinkRepository;
$this->productRepository = $productRepository;
$this->imageHelper = $imageHelper;
$this->status = $status;
$this->attributeSetRepository = $attributeSetRepository;
$this->scopeName = $scopeName;
$this->scopePrefix = $scopePrefix;
}
/**
* {@inheritdoc}
*/
public function modifyMeta(array $meta)
{
$meta = array_replace_recursive(
$meta,
[
static::GROUP_CUSTOMERTAB => [
'children' => [
$this->scopePrefix . static::DATA_SCOPE_CUSTOMER => $this->getCustomerFieldset(),
],
'arguments' => [
'data' => [
'config' => [
'label' => __('Customer'),
'collapsible' => true,
'componentType' => Fieldset::NAME,
'dataScope' => static::DATA_SCOPE,
'sortOrder' =>
$this->getNextGroupSortOrder(
$meta,
self::$previousGroup,
self::$sortOrder
),
],
],
],
],
]
);
return $meta;
}
/**
* {@inheritdoc}
*/
public function modifyData(array $data)
{
/** @var \Magento\Catalog\Model\Product $product */
$product = $this->locator->getProduct();
$productId = $product->getId();
if (!$productId) {
return $data;
}
$priceModifier = $this->getPriceModifier();
/**
* Set field name for modifier
*/
$priceModifier->setData('name', 'price');
foreach ($this->getDataScopes() as $dataScope) {
$data[$productId]['links'][$dataScope] = [];
foreach ($this->productLinkRepository->getList($product) as $linkItem) {
if ($linkItem->getLinkType() !== $dataScope) {
continue;
}
/** @var \Magento\Catalog\Model\Product $linkedProduct */
$linkedProduct = $this->productRepository->get(
$linkItem->getLinkedProductSku(),
false,
$this->locator->getStore()->getId()
);
$data[$productId]['links'][$dataScope][] = $this->fillData($linkedProduct, $linkItem);
}
if (!empty($data[$productId]['links'][$dataScope])) {
$dataMap = $priceModifier->prepareDataSource([
'data' => [
'items' => $data[$productId]['links'][$dataScope]
]
]);
$data[$productId]['links'][$dataScope] = $dataMap['data']['items'];
}
}
$data[$productId][self::DATA_SOURCE_DEFAULT]['current_product_id'] = $productId;
$data[$productId][self::DATA_SOURCE_DEFAULT]['current_store_id'] = $this->locator->getStore()->getId();
return $data;
}
/**
* Get price modifier
*
* @return \Magento\Catalog\Ui\Component\Listing\Columns\Price
* @deprecated
*/
private function getPriceModifier()
{
if (!$this->priceModifier) {
$this->priceModifier = ObjectManager::getInstance()->get(
\Magento\Catalog\Ui\Component\Listing\Columns\Price::class
);
}
return $this->priceModifier;
}
/**
* Prepare data column
*
* @param ProductInterface $linkedProduct
* @param ProductLinkInterface $linkItem
* @return array
*/
protected function fillData(ProductInterface $linkedProduct, ProductLinkInterface $linkItem)
{
return [
'id' => $linkedProduct->getId(),
'thumbnail' => $this->imageHelper->init($linkedProduct, 'product_listing_thumbnail')->getUrl(),
'name' => $linkedProduct->getName(),
'status' => $this->status->getOptionText($linkedProduct->getStatus()),
'attribute_set' => $this->attributeSetRepository
->get($linkedProduct->getAttributeSetId())
->getAttributeSetName(),
'sku' => $linkItem->getLinkedProductSku(),
'price' => $linkedProduct->getPrice(),
'position' => $linkItem->getPosition(),
];
}
/**
* Retrieve all data scopes
*
* @return array
*/
protected function getDataScopes()
{
return [
static::DATA_SCOPE_CUSTOMER,
];
}
/**
* Prepares config for the Related products fieldset
*
* @return array
*/
protected function getCustomerFieldset()
{
$content = __(
'Related products are shown to customers in addition to the item the customer is looking at.'
);
return [
'children' => [
'button_set' => $this->getButtonSet(
$content,
__('Add Related Products'),
$this->scopePrefix . static::DATA_SCOPE_CUSTOMER
),
'modal' => $this->getGenericModal(
__('Add Related Products'),
$this->scopePrefix . static::DATA_SCOPE_CUSTOMER
),
static::DATA_SCOPE_CUSTOMER => $this->getGrid($this->scopePrefix . static::DATA_SCOPE_CUSTOMER),
],
'arguments' => [
'data' => [
'config' => [
'additionalClasses' => 'admin__fieldset-section',
'label' => __('Customer'),
'collapsible' => false,
'componentType' => Fieldset::NAME,
'dataScope' => '',
'sortOrder' => 10,
],
],
]
];
}
/**
* Retrieve button set
*
* @param Phrase $content
* @param Phrase $buttonTitle
* @param string $scope
* @return array
*/
protected function getButtonSet(Phrase $content, Phrase $buttonTitle, $scope)
{
$modalTarget = $this->scopeName . '.' . static::GROUP_CUSTOMERTAB . '.' . $scope . '.modal';
return [
'arguments' => [
'data' => [
'config' => [
'formElement' => 'container',
'componentType' => 'container',
'label' => false,
'content' => $content,
'template' => 'ui/form/components/complex',
],
],
],
'children' => [
'button_' . $scope => [
'arguments' => [
'data' => [
'config' => [
'formElement' => 'container',
'componentType' => 'container',
'component' => 'Magento_Ui/js/form/components/button',
'actions' => [
[
'targetName' => $modalTarget,
'actionName' => 'toggleModal',
],
[
'targetName' => $modalTarget . '.' . $scope . '_product_listing',
'actionName' => 'render',
]
],
'title' => $buttonTitle,
'provider' => null,
],
],
],
],
],
];
}
/**
* Prepares config for modal slide-out panel
*
* @param Phrase $title
* @param string $scope
* @return array
*/
protected function getGenericModal(Phrase $title, $scope)
{
$listingTarget = $scope . '_product_listing';
$modal = [
'arguments' => [
'data' => [
'config' => [
'componentType' => Modal::NAME,
'dataScope' => '',
'options' => [
'title' => $title,
'buttons' => [
[
'text' => __('Cancel'),
'actions' => [
'closeModal'
]
],
[
'text' => __('Add Selected Products'),
'class' => 'action-primary',
'actions' => [
[
'targetName' => 'index = ' . $listingTarget,
'actionName' => 'save'
],
'closeModal'
]
],
],
],
],
],
],
'children' => [
$listingTarget => [
'arguments' => [
'data' => [
'config' => [
'autoRender' => false,
'componentType' => 'insertListing',
'dataScope' => $listingTarget,
'externalProvider' => $listingTarget . '.' . $listingTarget . '_data_source',
'selectionsProvider' => $listingTarget . '.' . $listingTarget . '.product_columns.ids',
'ns' => $listingTarget,
'render_url' => $this->urlBuilder->getUrl('mui/index/render'),
'realTimeLink' => true,
'dataLinks' => [
'imports' => false,
'exports' => true
],
'behaviourType' => 'simple',
'externalFilterMode' => true,
'imports' => [
'productId' => '${ $.provider }:data.product.current_product_id',
'storeId' => '${ $.provider }:data.product.current_store_id',
],
'exports' => [
'productId' => '${ $.externalProvider }:params.current_product_id',
'storeId' => '${ $.externalProvider }:params.current_store_id',
]
],
],
],
],
],
];
return $modal;
}
/**
* Retrieve grid
*
* @param string $scope
* @return array
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
protected function getGrid($scope)
{
$dataProvider = $scope . '_product_listing';
return [
'arguments' => [
'data' => [
'config' => [
'additionalClasses' => 'admin__field-wide',
'componentType' => DynamicRows::NAME,
'label' => null,
'columnsHeader' => false,
'columnsHeaderAfterRender' => true,
'renderDefaultRecord' => false,
'template' => 'ui/dynamic-rows/templates/grid',
'component' => 'Magento_Ui/js/dynamic-rows/dynamic-rows-grid',
'addButton' => false,
'recordTemplate' => 'record',
'dataScope' => 'data.links',
'deleteButtonLabel' => __('Remove'),
'dataProvider' => $dataProvider,
'map' => [
'id' => 'entity_id',
'name' => 'name',
'status' => 'status_text',
'attribute_set' => 'attribute_set_text',
'sku' => 'sku',
'price' => 'price',
'thumbnail' => 'thumbnail_src',
],
'links' => [
'insertData' => '${ $.provider }:${ $.dataProvider }'
],
'sortOrder' => 2,
],
],
],
'children' => [
'record' => [
'arguments' => [
'data' => [
'config' => [
'componentType' => 'container',
'isTemplate' => true,
'is_collection' => true,
'component' => 'Magento_Ui/js/dynamic-rows/record',
'dataScope' => '',
],
],
],
'children' => $this->fillMeta(),
],
],
];
}
/**
* Retrieve meta column
*
* @return array
*/
protected function fillMeta()
{
return [
'id' => $this->getTextColumn('id', false, __('ID'), 0),
'thumbnail' => [
'arguments' => [
'data' => [
'config' => [
'componentType' => Field::NAME,
'formElement' => Input::NAME,
'elementTmpl' => 'ui/dynamic-rows/cells/thumbnail',
'dataType' => Text::NAME,
'dataScope' => 'thumbnail',
'fit' => true,
'label' => __('Thumbnail'),
'sortOrder' => 10,
],
],
],
],
'name' => $this->getTextColumn('name', false, __('Name'), 20),
'status' => $this->getTextColumn('status', true, __('Status'), 30),
'attribute_set' => $this->getTextColumn('attribute_set', false, __('Attribute Set'), 40),
'sku' => $this->getTextColumn('sku', true, __('SKU'), 50),
'price' => $this->getTextColumn('price', true, __('Price'), 60),
'actionDelete' => [
'arguments' => [
'data' => [
'config' => [
'additionalClasses' => 'data-grid-actions-cell',
'componentType' => 'actionDelete',
'dataType' => Text::NAME,
'label' => __('Actions'),
'sortOrder' => 70,
'fit' => true,
],
],
],
],
'position' => [
'arguments' => [
'data' => [
'config' => [
'dataType' => Number::NAME,
'formElement' => Input::NAME,
'componentType' => Field::NAME,
'dataScope' => 'position',
'sortOrder' => 80,
'visible' => false,
],
],
],
],
];
}
/**
* Retrieve text column structure
*
* @param string $dataScope
* @param bool $fit
* @param Phrase $label
* @param int $sortOrder
* @return array
*/
protected function getTextColumn($dataScope, $fit, Phrase $label, $sortOrder)
{
$column = [
'arguments' => [
'data' => [
'config' => [
'componentType' => Field::NAME,
'formElement' => Input::NAME,
'elementTmpl' => 'ui/dynamic-rows/cells/text',
'component' => 'Magento_Ui/js/form/element/text',
'dataType' => Text::NAME,
'dataScope' => $dataScope,
'fit' => $fit,
'label' => $label,
'sortOrder' => $sortOrder,
],
],
],
];
return $column;
}
}
Bunu Magento Ürün İncelemesi Modülünü takip ederek yaptım.
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="product_tabs">
<block class="Namespace\Module\Block\Adminhtml\Product\Edit\Tab\Mymodule" name="product.mymodule">
<arguments>
<argument name="label" xsi:type="string" translate="true">My Module Title</argument>
<argument name="group_code" xsi:type="string">basic</argument> <!-- "advanced" for Advance Settings -->
</arguments>
</block>
<action method="addTab">
<argument name="name" xsi:type="string">product-mymodule</argument>
<argument name="block" xsi:type="string">product.mymodule</argument>
</action>
</referenceBlock>
</body>
</page>
Belirli bir yola göre özel modülünüzde Mymodule.php dosyasını oluşturun.
Umarım yardımcı olur.