Skip to content

Commit 0c63be3

Browse files
committed
MAGETWO-92021: Improving dev experience for Products content type
- Created reusable conditions component for PageBuilder content types - Created reusable widget directive HTML mechanism for PageBuilder content types - Updated setup scripts to not include extra data-* attributes - Updated master format doc - Refactored new implementation to be simpler
1 parent 51c6888 commit 0c63be3

File tree

29 files changed

+769
-451
lines changed

29 files changed

+769
-451
lines changed

app/code/Magento/PageBuilder/Block/Adminhtml/ContentType/Products/Conditions.php renamed to app/code/Magento/PageBuilder/Block/Adminhtml/Form/Element/ProductConditions.php

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@
66

77
declare(strict_types=1);
88

9-
namespace Magento\PageBuilder\Block\Adminhtml\ContentType\Products;
9+
namespace Magento\PageBuilder\Block\Adminhtml\Form\Element;
1010

1111
use Magento\Backend\Block\Template;
1212

1313
/**
1414
* The block used to render the conditions rule tree form within the PageBuilder interface.
1515
*/
16-
class Conditions extends Template
16+
class ProductConditions extends Template
1717
{
1818
/**
1919
*
2020
* @var string
2121
*/
22-
protected $_template = 'Magento_PageBuilder::content_type/products/conditions.phtml';
22+
protected $_template = 'Magento_PageBuilder::form/element/conditions.phtml';
2323

2424
/**
2525
* @var \Magento\Framework\Serialize\Serializer\Json
@@ -41,42 +41,42 @@ public function __construct(
4141
parent::__construct($context, $data);
4242
}
4343

44-
/**
45-
* Returns the form namespace to be used with the JS config
46-
*
47-
* @return string
48-
*/
49-
public function getFormNamespace(): string
50-
{
51-
return 'pagebuilder_products_form';
52-
}
53-
5444
/**
5545
* Returns an array of arguments to pass to the condition tree UIComponent
5646
*
5747
* @return array
5848
*/
5949
private function getConfig(): array
6050
{
51+
$formNamespace = $this->getData('formNamespace');
52+
$attribute = $this->getData('attribute');
53+
6154
return [
62-
'formNamespace' => $this->getFormNamespace(),
55+
'formNamespace' => $formNamespace,
6356
'componentUrl' => $this->getUrl(
64-
'pagebuilder/contenttype/products_conditions',
65-
['form_namespace' => $this->getFormNamespace()]
57+
'pagebuilder/form/element_productconditions',
58+
[
59+
'form_namespace' => $formNamespace,
60+
'prefix' => $attribute,
61+
]
6662
),
67-
'jsObjectName' => $this->getFormNamespace(),
63+
'jsObjectName' => $formNamespace . '_' . $attribute,
6864
'childComponentUrl' => $this->getUrl(
69-
'pagebuilder/contenttype/products_conditions_child',
70-
['form_namespace' => $this->getFormNamespace()]
65+
'pagebuilder/form/element_productconditions_child',
66+
[
67+
'form_namespace' => $formNamespace,
68+
'prefix' => $attribute,
69+
]
7170
),
71+
'attribute' => $attribute,
7272
];
7373
}
7474

7575
public function getConfigJson(): string
7676
{
7777
return $this->serializer->serialize([
78-
'[data-role=pagebuilder-product-conditions-form-placeholder]' => [
79-
'Magento_PageBuilder/js/content-type/products/conditions-loader' => $this->getConfig(),
78+
'[data-role=pagebuilder-conditions-form-placeholder-' . $this->getData('attribute') . ']' => [
79+
'Magento_PageBuilder/js/form/element/conditions-loader' => $this->getConfig(),
8080
]
8181
]);
8282
}

app/code/Magento/PageBuilder/Controller/Adminhtml/ContentType/Products/Conditions.php renamed to app/code/Magento/PageBuilder/Controller/Adminhtml/Form/Element/ProductConditions.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66

77
declare(strict_types=1);
88

9-
namespace Magento\PageBuilder\Controller\Adminhtml\ContentType\Products;
9+
namespace Magento\PageBuilder\Controller\Adminhtml\Form\Element;
1010

1111
use Magento\Rule\Model\Condition\Combine;
1212

1313
/**
1414
* Responsible for rendering the top-level conditions rule tree using the provided params
1515
*/
16-
class Conditions extends \Magento\CatalogWidget\Controller\Adminhtml\Product\Widget
16+
class ProductConditions extends \Magento\CatalogWidget\Controller\Adminhtml\Product\Widget
1717
{
1818
/**
1919
* @var \Magento\CatalogWidget\Model\Rule
@@ -45,9 +45,13 @@ public function __construct(
4545
*/
4646
public function execute()
4747
{
48-
$conditions = $this->getRequest()->getParam('conditions');
49-
$this->rule->loadPost(['conditions'=> $this->serializer->unserialize($conditions)]);
48+
$prefix = $this->getRequest()->getParam('prefix', 'conditions');
49+
$conditionsEncoded = $this->getRequest()->getParam('conditions');
5050
$conditions = $this->rule->getConditions();
51+
$conditions->setData('prefix', $prefix);
52+
// The rule class expects something to be set in the prefix field before the conditions are loaded
53+
$conditions->setData($prefix, []);
54+
$this->rule->loadPost(['conditions' => $this->serializer->unserialize($conditionsEncoded)]);
5155
$formName = $this->getRequest()->getParam('form_namespace');
5256
// Combine class recursively sets jsFormObject so we don't need to
5357
$conditions->setJsFormObject($formName);

app/code/Magento/PageBuilder/Controller/Adminhtml/ContentType/Products/Conditions/Child.php renamed to app/code/Magento/PageBuilder/Controller/Adminhtml/Form/Element/ProductConditions/Child.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66

77
declare(strict_types=1);
88

9-
namespace Magento\PageBuilder\Controller\Adminhtml\ContentType\Products\Conditions;
9+
namespace Magento\PageBuilder\Controller\Adminhtml\Form\Element\ProductConditions;
1010

1111
use Magento\Rule\Model\Condition\AbstractCondition;
12-
use Magento\Rule\Model\Condition\Combine;
1312

1413
/**
1514
* Responsible for rendering the child elements of the conditions rule tree using the provided params
@@ -48,7 +47,7 @@ public function execute()
4847
->setId($id)
4948
->setType($className)
5049
->setRule($this->rule)
51-
->setPrefix('conditions');
50+
->setPrefix($this->getRequest()->getParam('prefix', 'conditions'));
5251

5352
if (!empty($typeData[1])) {
5453
$model->setAttribute($typeData[1]);

app/code/Magento/PageBuilder/Setup/DataConverter/Renderer/Product.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,6 @@ public function render(array $itemData, array $additionalData = [])
134134
'data-role' => 'product',
135135
'data-appearance' => 'grid',
136136
'class' => $eavData['css_classes'] ?? '',
137-
'data-products-count' => $productsCount,
138-
'data-conditions-encoded' => $this->escaper->escapeHtml($this->jsonEncoder->serialize($conditions)),
139-
'data-sku' => $productSku
140137
];
141138

142139
if (isset($itemData['formData'])) {

app/code/Magento/PageBuilder/Setup/DataConverter/Renderer/ProductList.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@ public function render(array $itemData, array $additionalData = [])
105105
'data-role' => 'products',
106106
'data-appearance' => 'grid',
107107
'class' => $itemData['formData']['css_classes'] ?? '',
108-
'data-products-count' => $productsCount,
109-
'data-conditions-encoded' => $this->escaper->escapeHtml($this->jsonEncoder->serialize($conditions))
110108
];
111109

112110
if (isset($itemData['formData'])) {

app/code/Magento/PageBuilder/Test/Mftf/Section/PageBuilderProductsSection.xml

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,26 @@
99
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1010
xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd">
1111
<section name="ProductsOnStage">
12-
<element name="base" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count])[{{arg1}}]" parameterized="true"/>
13-
<element name="product" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count])[{{arg1}}]//ol//li[contains(@class,'product-item')]" parameterized="true"/>
14-
<element name="productImage" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count]//ol//li[contains(@class,'product-item')])[{{arg1}}]//img[@class='product-image-photo']" parameterized="true"/>
15-
<element name="productName" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count]//ol//li[contains(@class,'product-item')])[{{arg1}}]//strong//a[@class='product-item-link' and @href and contains(.,'{{arg2}}')]" parameterized="true"/>
16-
<element name="productPrice" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count]//ol//li[contains(@class,'product-item')])[{{arg1}}]//span[@class='price' and .='${{arg2}}']" parameterized="true"/>
17-
<element name="productAddToCart" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count]//ol//li[contains(@class,'product-item')])[{{arg1}}]//button[contains(@class,'tocart') and @title='Add to Cart']" parameterized="true"/>
18-
<element name="productAddToWishList" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count]//ol//li[contains(@class,'product-item')])[{{arg1}}]//a[contains(@class,'towishlist') and @title='Add to Wish List']" parameterized="true"/>
19-
<element name="productAddToCompare" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count]//ol//li[contains(@class,'product-item')])[{{arg1}}]//a[contains(@class,'tocompare') and @title='Add to Compare']" parameterized="true"/>
12+
<element name="base" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')])[{{arg1}}]" parameterized="true"/>
13+
<element name="product" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')])[{{arg1}}]//ol//li[contains(@class,'product-item')]" parameterized="true"/>
14+
<element name="productImage" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')]//ol//li[contains(@class,'product-item')])[{{arg1}}]//img[@class='product-image-photo']" parameterized="true"/>
15+
<element name="productName" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')]//ol//li[contains(@class,'product-item')])[{{arg1}}]//strong//a[@class='product-item-link' and @href and contains(.,'{{arg2}}')]" parameterized="true"/>
16+
<element name="productPrice" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')]//ol//li[contains(@class,'product-item')])[{{arg1}}]//span[@class='price' and .='${{arg2}}']" parameterized="true"/>
17+
<element name="productAddToCart" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')]//ol//li[contains(@class,'product-item')])[{{arg1}}]//button[contains(@class,'tocart') and @title='Add to Cart']" parameterized="true"/>
18+
<element name="productAddToWishList" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')]//ol//li[contains(@class,'product-item')])[{{arg1}}]//a[contains(@class,'towishlist') and @title='Add to Wish List']" parameterized="true"/>
19+
<element name="productAddToCompare" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')]//ol//li[contains(@class,'product-item')])[{{arg1}}]//a[contains(@class,'tocompare') and @title='Add to Compare']" parameterized="true"/>
2020
<!-- Advanced Configuration -->
21-
<element name="alignment" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count])[{{arg1}}][contains(@style,'text-align: {{arg2}};')]" parameterized="true"/>
22-
<element name="noAlignment" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count])[{{arg1}}][not(contains(@style,'text-align:'))]" parameterized="true"/>
23-
<element name="border" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count])[{{arg1}}][contains(@style,'border-style: {{arg2}};')]" parameterized="true"/>
24-
<element name="borderColor" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count])[{{arg1}}][contains(@style,'border-color: {{arg2}};')]" parameterized="true"/>
25-
<element name="noBorderColor" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count])[{{arg1}}][not(contains(@style,'border-color:'))]" parameterized="true"/>
26-
<element name="borderWidth" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count])[{{arg1}}][contains(@style,'border-width: {{arg2}}px;')]" parameterized="true"/>
27-
<element name="borderRadius" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count])[{{arg1}}][contains(@style,'border-radius: {{arg2}}px;')]" parameterized="true"/>
28-
<element name="cssClasses" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count])[{{arg1}}][contains(@class,'{{arg2}}')]" parameterized="true"/>
29-
<element name="noCssClasses" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count])[{{arg1}}][not(@class)]" parameterized="true"/>
30-
<element name="margins" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count])[{{arg1}}][contains(@style,'margin: {{arg2}}px;')]" parameterized="true"/>
31-
<element name="padding" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[@data-products-count])[{{arg1}}][contains(@style,'padding: {{arg2}}px;')]" parameterized="true"/>
21+
<element name="alignment" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')])[{{arg1}}][contains(@style,'text-align: {{arg2}};')]" parameterized="true"/>
22+
<element name="noAlignment" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')])[{{arg1}}][not(contains(@style,'text-align:'))]" parameterized="true"/>
23+
<element name="border" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')])[{{arg1}}][contains(@style,'border-style: {{arg2}};')]" parameterized="true"/>
24+
<element name="borderColor" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')])[{{arg1}}][contains(@style,'border-color: {{arg2}};')]" parameterized="true"/>
25+
<element name="noBorderColor" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')])[{{arg1}}][not(contains(@style,'border-color:'))]" parameterized="true"/>
26+
<element name="borderWidth" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')])[{{arg1}}][contains(@style,'border-width: {{arg2}}px;')]" parameterized="true"/>
27+
<element name="borderRadius" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')])[{{arg1}}][contains(@style,'border-radius: {{arg2}}px;')]" parameterized="true"/>
28+
<element name="cssClasses" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')])[{{arg1}}][contains(@class,'{{arg2}}')]" parameterized="true"/>
29+
<element name="noCssClasses" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')])[{{arg1}}][not(@class)]" parameterized="true"/>
30+
<element name="margins" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')])[{{arg1}}][contains(@style,'margin: {{arg2}}px;')]" parameterized="true"/>
31+
<element name="padding" type="text" selector="(//div[contains(@class,'pagebuilder-products')]//div[contains(@data-appearance,'grid')])[{{arg1}}][contains(@style,'padding: {{arg2}}px;')]" parameterized="true"/>
3232
</section>
3333
<section name="ProductsContentTypeForm">
3434
<element name="conditionsList" type="text" selector=".rule-param-children"/>

app/code/Magento/PageBuilder/docs/master-format.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -956,14 +956,12 @@ Inline styles
956956
## Products
957957

958958
```
959-
<div data-role="products" data-appearance="grid" data-products-count="4" data-conditions-encoded="">{{widget type="Magento\CatalogWidget\Block\Product\ProductsList" template="Magento_CatalogWidget::product/widget/content/grid.phtml" anchor_text="" id_path="" show_pager="0" products_count="4" type_name="Catalog Products List" conditions_encoded=""}}</div>
959+
<div data-role="products" data-appearance="grid">{{widget type="Magento\CatalogWidget\Block\Product\ProductsList" template="Magento_CatalogWidget::product/widget/content/grid.phtml" anchor_text="" id_path="" show_pager="0" products_count="5" type_name="Catalog Products List" conditions_encoded=""}}</div>
960960
```
961961

962962
Attributes
963963
1. data-role [products]
964964
2. data-appearance [grid]
965-
3. data-products-count
966-
4. data-conditions-encoded
967965

968966
Inline styles
969967
1. text-align

app/code/Magento/PageBuilder/view/adminhtml/templates/content_type/products/conditions.phtml

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
?>
7+
<?php
8+
/** @var $block \Magento\PageBuilder\Block\Adminhtml\Form\Element\ProductConditions */
9+
$attribute = $block->getData('attribute');
10+
$id = $block->getData('formNamespace') . '_' . $attribute;
11+
?>
12+
<label class="admin__field-label">
13+
<span><?= $block->escapeHtml($block->getData('label')) ?></span>
14+
</label>
15+
<div class="admin__field-control">
16+
<div class="rule-tree">
17+
<fieldset id="<?= $block->escapeHtmlAttr($id) ?>" class="fieldset">
18+
<div class="rule-tree-wrapper">
19+
<div data-role="pagebuilder-conditions-form-placeholder-<?= $block->escapeHtmlAttr($attribute) ?>"></div>
20+
</div>
21+
</fieldset>
22+
</div>
23+
</div>
24+
25+
<script type="text/x-magento-init"><?= /* @noEscape */ $block->getConfigJson() ?></script>

app/code/Magento/PageBuilder/view/adminhtml/ui_component/pagebuilder_products_form.xml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,19 @@
7575
<settings>
7676
<label />
7777
</settings>
78-
<htmlContent name="conditions_form" template="Magento_PageBuilder/content-type/products/content">
78+
<htmlContent name="conditions_form" template="Magento_PageBuilder/form/element/widget-conditions">
7979
<settings>
8080
<additionalClasses>
8181
<class name="admin__field">true</class>
8282
</additionalClasses>
8383
</settings>
84-
<block name="conditions_form" class="Magento\PageBuilder\Block\Adminhtml\ContentType\Products\Conditions" />
84+
<block name="conditions_form" class="Magento\PageBuilder\Block\Adminhtml\Form\Element\ProductConditions">
85+
<arguments>
86+
<argument name="formNamespace" xsi:type="string">pagebuilder_products_form</argument>
87+
<argument name="attribute" xsi:type="string">conditions_encoded</argument>
88+
<argument name="label" xsi:type="string" translate="true">Condition</argument>
89+
</arguments>
90+
</block>
8591
</htmlContent>
8692
<field name="products_count" sortOrder="10" formElement="input">
8793
<argument name="data" xsi:type="array">

0 commit comments

Comments
 (0)