Question

I would like my Magento 2.2.6 store to have two grouped product pages. For some grouped products I would like to use the existing default grouped product layout that ships with Magento 2. For other grouped products I would like to use my own custom grouped product layout. For this question, lets say that I would like my custom grouped product layout to simply move the list of grouped products from the default position (at the right side of the gallery) as shown here:

Grouped products displayed to the right of the gallery

to display them below the gallery as shown here:

Grouped products displayed below the gallery

To attempt to do this I have created the following layout app/code/[COMPANY]/[MODULE]/view/frontend/layout/catalog_product_view_type_grouped.xml to extend the existing vendor/magento/module-grouped-product/view/frontend/layout/catalog_product_view_type_grouped.xml:

<?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>
        <move element="product.info" destination="content" before="product.info.details"/>
    </body>
</page>

With this file alone, the list of grouped products (the product.info block) is correctly moved to below the gallery. However, it is moved for all grouped products, not just my specific grouped products.

I believe (I acknowledge that I could be wrong) that what I need to do is specify a custom page layout for the grouped product under the product design section:

Selecting the page layout in the product admin

To do this I created the following layouts.xml file:

app/code/[COMPANY]/[MODULE]/view/frontend/layouts.xml:

<?xml version="1.0" encoding="UTF-8"?>
<page_layouts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/PageLayout/etc/layouts.xsd">
    <layout id="custom_grouped_product">
        <label translate="true">Custom Grouped Product</label>
    </layout>
</page_layouts>

And added the corresponding app/code/[COMPANY]/[MODULE]/view/frontend/page_layout/custom_grouped_product.xml page layout file:

<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd">
</layout>

I have selected the page layout against the product in the product admin page but this is about as far as I have got.

How do I connect the catalog_product_view_type_grouped.xml layout file to the extended custom_grouped_product.xml page layout file so that the page layout file is only displayed when the custom_grouped_product.xml is selected in the product admin?

And as an aside (and I appreciate this could be another question entirely), should I be using a module or theme to achieve the above? I have used a module here as I understand that themes are mainly for styling so would greatly appreciate any advice regarding this also.

Was it helpful?

Solution

It seems that I was going about trying to achieve this the wrong way by using layouts rather than themes.

Instead, to resolve this issue I have created a theme that only contains the changes I would like for the product page. I didn't realize before but Magento 2 allows you to specify a theme to use against an individual product:

enter image description here

It also allows you to specify a theme to use against a product category and assign it to use against its products (so you don't have to apply the theme to each individual product):

enter image description here

However, this being said, there are currently several known bugs in Magento 2.2.6 and also in the latest release of 2.3.0 where this is not applying the themes as it should. There is some on-going discussion around this so I am hopeful this will be resolved in the next release of 2.3.1.

OTHER TIPS

I have created the custom layout for grouped product using a module

layouts.xml

<page_layouts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/PageLayout/etc/layouts.xsd">
<layout id="retail_bb">
    <label translate="true">Retail BB</label>
</layout>
</page_layouts>

retail_bb.xml

<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd">
    <update handle="1column" />

<!-- Remove the original product attributes block -->
 <referenceContainer name="product.info.details">
    <referenceBlock name="product.attributes" remove="true" />
</referenceContainer>

<referenceContainer name="page.wrapper">
    <!-- Create new product details wrapper under main.content for tabs section -->
    <container name="product.info.details.wrapper" after="main.content" htmlTag="div" htmlClass="page-main page-main-details">
        <container name="product.info.details.wrapper.columns" htmlTag="div" htmlClass="columns">
            <container name="product.info.details.wrapper.main" label="Product Details Main Content Container" htmlTag="div" htmlClass="column main"/>
        </container>
    </container>
    <!-- Create wrapper for description without page-main class which adds gutters -->
    <container name="product.info.description.wrapper" after="main.content" before="product.info.details.after.wrapper" htmlTag="div" htmlClass="page-main-description product-full-width-section" htmlId="description"/>
    <!-- Create a new wrapper to house the custom Page Builder attributes -->
    <container name="product.attributes.pagebuilder.wrapper" after="product.info.description.wrapper" before="product.info.details.after.wrapper" htmlTag="div" htmlClass="page-main-pagebuilder-attributes">
        <block class="Magento\PageBuilder\Block\Catalog\Block\Product\View\Attributes" name="product.attributes.only.pagebuilder" as="additional.pagebuilder" template="Magento_PageBuilder::catalog/product/view/attribute_list.phtml">
            <arguments>
                <argument name="display_attributes" xsi:type="string">pagebuilder_only</argument>
            </arguments>
        </block>
    </container>
    <referenceBlock name="product.info.media.image" remove="true"/> 
    <referenceContainer name="content">
        <block class="Magento\Catalog\Block\Product\View\Gallery" name="product.info.media.image.retailbb" template="Magento_Catalog::product/view/gallery.phtml">
            <arguments>
                <argument name="gallery_options" xsi:type="object">Magento\Catalog\Block\Product\View\GalleryOptions</argument>
                <argument name="imageHelper" xsi:type="object">Magento\Catalog\Helper\Image</argument>
            </arguments>
        </block>
    </referenceContainer>

    <referenceContainer name="product.info.form.content">
        <block class="Magento\GroupedProduct\Block\Product\View\Type\Grouped" name="product.info.grouped.retailbb" before="product.info.addtocart" template="BA_BasysProdLayouts::product/grouped.phtml"/>
        <referenceBlock name="product.info.grouped.retailbb">
            <arguments>
                <argument name="view_model" xsi:type="object">BA\BasysProdLayouts\ViewModel\GetAttributes</argument>
            </arguments>
        </referenceBlock>
        <referenceBlock name="product.info.grouped" remove="true"/>
        <referenceBlock name="product.info.addtocart" remove="true" />
        <container name="product.info.grouped.extra" after="product.info.grouped.retailbb" before="product.info.grouped.retailbb" as="product_type_data_extra" label="Product Extra Info"/>
    </referenceContainer>
    <referenceContainer name="product.info.grouped.extra">
        <block class="Magento\GroupedProduct\Block\Stockqty\Type\Grouped" name="product.info.grouped.stock-composite" template="Magento_CatalogInventory::stockqty/composite.phtml"/>
    </referenceContainer>
    <referenceContainer name="product.info.type">
        <block class="Magento\GroupedProduct\Block\Product\View\Type\Grouped" name="product.info.grouped.stock" as="product.info.grouped.retailbb" template="Magento_GroupedProduct::product/view/type/default.phtml"/>
    </referenceContainer>
    <!-- Create new product details wrapper under main.content for tabs section -->
    <container name="product.info.details.after.wrapper" after="product.attributes.pagebuilder.wrapper" before="product.info.details.wrapper" htmlTag="div" htmlClass="page-main page-main-details product-details">
        <container name="product.info.details.after.wrapper.columns" htmlTag="div" htmlClass="columns">
            <container name="product.info.details.after.wrapper.main" label="Product Details Main Content Container" htmlTag="div" htmlClass="column main product-details">
                <block class="Magento\Framework\View\Element\Template" name="product.attributes.wrapper" template="Magento_PageBuilder::catalog/product/view/section_wrapper.phtml">
                    <arguments>
                        <argument name="title" translate="true" xsi:type="string">More Information</argument>
                    </arguments>
                    <!-- Create a new instance of attributes which excludes Page Builder attributes -->
                    <block class="Magento\PageBuilder\Block\Catalog\Block\Product\View\Attributes" name="product.attributes.exclude.pagebuilder" as="additional" template="Magento_Catalog::product/view/attributes.phtml">
                        <arguments>
                            <argument name="display_attributes" xsi:type="string">non_pagebuilder</argument>
                        </arguments>
                    </block>
                </block>
                <block class="Magento\Framework\View\Element\Template" name="product.reviews.wrapper" after="product.attributes.wrapper" template="Magento_PageBuilder::catalog/product/view/section_wrapper.phtml">
                    <arguments>
                        <argument name="title" translate="true" xsi:type="string">Reviews</argument>
                    </arguments>
                    <block class="Magento\Review\Block\Product\View\ListView" name="product.info.product_additional_data.wrapper" template="Magento_Review::product/view/list.phtml" ifconfig="catalog/review/active">
                        <arguments>
                            <argument name="hide_title" xsi:type="boolean">true</argument>
                        </arguments>
                    </block>
                </block>
            </container>
        </container>
    </container>
</referenceContainer>

<!-- Move details & description into their new wrappers -->
<move element="product.info.details" destination="product.info.details.wrapper.main"/>
<move element="product.info.description" destination="product.info.description.wrapper"/>

<!-- Move reviews into the section after the description -->
<move element="reviews.tab" destination="product.reviews.wrapper"/>

<!-- Move content.aside below the reviews -->
<move element="content.aside" destination="product.info.details.after.wrapper.main" after="product.reviews.wrapper"/>

Magento Admin

enter image description here

Frontend enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top