Magento – Creating a new container and placing it where I want in Magento 2

containerslayoutmagento2

I've search for some answers to this but I can't seem to find anything.

I understand how to create the container and then move the blocks in there (which I've done), so this article wasn't that helpful.

And I understand where I'm supposed to place up update code, so this one wasn't that helpful either.

My question is more about how to choose a placement for my new container.

Currently on my single product page, my related products are showing to the left of everything, instead of the bottom where I'd like it.

enter image description here

I've gone into

vendor\magento\module-catalog\view\frontend\layout

and found the layout file that I could then try to create the new container under. However I find pages in Magento 2 are laid out weird and there is no easy way to place a full width area under the content container. Unless I'm missing something?

In myvendor/mytheme/Magento_Theme/layout/default.xml I have this:

<referenceContainer name="content">
            <container name="product.details.info.panel" as="block-wrapper-to-style-details-related" htmlTag="div" htmlClass="product-content-details-related-container" after="content.aside"/>
        </referenceContainer> 

        <move element="catalog.product.related" destination="product.details.info.panel" after=""/>

I've thrown in that after="content.aside" in hopes it would move it down but it won't. It just hangs out there at the top.

Can anyone help me add my new container after the content container and before the footer?

Any help is appreciated.

UPDATE 1

Thanks for the help Ben & Quisse!

Below is the catalog_product_view.xml file:

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<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="mage/gallery/gallery.css"/>
    </head>
    <update handle="catalog_product_opengraph" />
    <update handle="page_calendar"/>
    <body>
        <attribute name="itemtype" value="http://schema.org/Product" />
        <attribute name="itemscope" value="itemscope"/>
        <referenceBlock name="head.components">
            <block class="Magento\Framework\View\Element\Js\Components" name="checkout_page_head_components" template="Magento_Catalog::js/components.phtml"/>
        </referenceBlock>
        <referenceBlock name="page.main.title">
            <arguments>
                <argument name="css_class" xsi:type="string">product</argument>
                <argument name="add_base_attribute" xsi:type="string">itemprop="name"</argument>
            </arguments>
        </referenceBlock>
        <referenceBlock name="root">
            <arguments>
                <argument name="add_attribute" xsi:type="string">itemscope itemtype="http://schema.org/Product"</argument>
            </arguments>
        </referenceBlock>
        <referenceContainer name="content">
            <container name="product.info.main" htmlTag="div" htmlClass="product-info-main" before="-">
                <container name="product.info.price" label="Product info auxiliary container" htmlTag="div" htmlClass="product-info-price" after="product.info.review">
                    <container name="product.info.stock.sku" label="Product auxiliary info" htmlTag="div" htmlClass="product-info-stock-sku">
                        <container name="product.info.type" before="-"/>
                        <block class="Magento\Catalog\Block\Product\View\Description" name="product.info.sku" template="product/view/attribute.phtml" after="product.info.type">
                            <arguments>
                                <argument name="at_call" xsi:type="string">getSku</argument>
                                <argument name="at_code" xsi:type="string">sku</argument>
                                <argument name="css_class" xsi:type="string">sku</argument>
                                <argument name="at_label" xsi:type="string">default</argument>
                                <argument name="add_attribute" xsi:type="string">itemprop="sku"</argument>
                            </arguments>
                        </block>
                    </container>
                    <block class="Magento\Catalog\Block\Product\View" name="product.info.review" template="product/view/review.phtml" after="product.info.stock.sku" />
                    <block class="Magento\Catalog\Pricing\Render" name="product.price.final" after="product.info.sku">
                        <arguments>
                            <argument name="price_render" xsi:type="string">product.price.render.default</argument>
                            <argument name="price_type_code" xsi:type="string">final_price</argument>
                            <argument name="zone" xsi:type="string">item_view</argument>
                        </arguments>
                    </block>
                </container>
                <block class="Magento\Catalog\Pricing\Render" name="product.price.tier" after="product.info.price">
                    <arguments>
                        <argument name="price_render" xsi:type="string">product.price.render.default</argument>
                        <argument name="price_type_code" xsi:type="string">tier_price</argument>
                        <argument name="zone" xsi:type="string">item_view</argument>
                    </arguments>
                </block>
                <container name="alert.urls" as="alert_urls" label="Alert Urls" after="product.price.tier"/>
                <block class="Magento\Catalog\Block\Product\View" name="product.info" template="product/view/form.phtml" after="alert.urls">
                    <container name="product.info.form.content" as="product_info_form_content">
                        <block class="Magento\Catalog\Block\Product\View" name="product.info.addtocart" as="addtocart" template="product/view/addtocart.phtml"/>
                    </container>
                    <block class="Magento\Framework\View\Element\Template" name="product.info.form.options" as="options_container">
                        <block class="Magento\Catalog\Block\Product\View" name="product.info.options.wrapper" as="product_options_wrapper" template="product/view/options/wrapper.phtml">
                            <block class="Magento\Catalog\Block\Product\View\Options" name="product.info.options" as="product_options" template="product/view/options.phtml">
                                <block class="Magento\Catalog\Block\Product\View\Options\Type\DefaultType" as="default" template="product/view/options/type/default.phtml"/>
                                <block class="Magento\Catalog\Block\Product\View\Options\Type\Text" as="text" template="product/view/options/type/text.phtml"/>
                                <block class="Magento\Catalog\Block\Product\View\Options\Type\File" as="file" template="product/view/options/type/file.phtml"/>
                                <block class="Magento\Catalog\Block\Product\View\Options\Type\Select" as="select" template="product/view/options/type/select.phtml"/>
                                <block class="Magento\Catalog\Block\Product\View\Options\Type\Date" as="date" template="product/view/options/type/date.phtml"/>
                            </block>
                            <block class="Magento\Framework\View\Element\Html\Calendar" name="html_calendar" as="html_calendar" template="Magento_Theme::js/calendar.phtml"/>
                        </block>
                        <block class="Magento\Catalog\Block\Product\View" name="product.info.options.wrapper.bottom" as="product_options_wrapper_bottom" template="product/view/options/wrapper/bottom.phtml">
                            <block class="Magento\Catalog\Block\Product\View" name="product.info.addtocart.additional" as="product.info.addtocart" template="product/view/addtocart.phtml"/>
                        </block>
                    </block>
                </block>
                <container name="product.info.extrahint" as="extrahint" label="Product View Extra Hint">
                    <container name="product.info.social" label="Product social links container" htmlTag="div" htmlClass="product-social-links" after="product.info.overview">
                        <block class="Magento\Catalog\Block\Product\View" name="product.info.addto" as="addto" template="product/view/addto.phtml">
                            <block class="Magento\Catalog\Block\Product\View\AddTo\Compare" name="view.addto.compare" after="view.addto.wishlist"
                                   template="Magento_Catalog::product/view/addto/compare.phtml" />
                        </block>
                        <block class="Magento\Catalog\Block\Product\View" name="product.info.mailto" template="product/view/mailto.phtml"/>
                    </container>
                </container>
                <block class="Magento\Catalog\Block\Product\View\Description" name="product.info.overview" template="product/view/attribute.phtml" group="detailed_info" after="product.info.extrahint">
                    <arguments>
                        <argument name="at_call" xsi:type="string">getShortDescription</argument>
                        <argument name="at_code" xsi:type="string">short_description</argument>
                        <argument name="css_class" xsi:type="string">overview</argument>
                        <argument name="at_label" translate="true" xsi:type="string">none</argument>
                        <argument name="title" translate="true" xsi:type="string">Overview</argument>
                        <argument name="add_attribute" xsi:type="string">itemprop="description"</argument>
                    </arguments>
                </block>
            </container>
            <container name="product.info.media" htmlTag="div" htmlClass="product media" after="product.info.main">
                <block class="Magento\Catalog\Block\Product\View\Gallery" name="product.info.media.image" template="product/view/gallery.phtml"/>
            </container>
            <block class="Magento\Catalog\Block\Product\View\Description" name="product.info.details" template="product/view/details.phtml" after="product.info.media">
                <block class="Magento\Catalog\Block\Product\View\Description" name="product.info.description" template="product/view/attribute.phtml" group="detailed_info">
                    <arguments>
                        <argument name="at_call" xsi:type="string">getDescription</argument>
                        <argument name="at_code" xsi:type="string">description</argument>
                        <argument name="css_class" xsi:type="string">description</argument>
                        <argument name="at_label" xsi:type="string">none</argument>
                        <argument name="title" translate="true" xsi:type="string">Details</argument>
                    </arguments>
                </block>
                <block class="Magento\Catalog\Block\Product\View\Attributes" name="product.attributes" as="additional" template="product/view/attributes.phtml" group="detailed_info">
                    <arguments>
                        <argument translate="true" name="title" xsi:type="string">More Information</argument>
                    </arguments>
                </block>
            </block>
            <block class="Magento\Cookie\Block\RequireCookie" name="require-cookie" template="Magento_Cookie::require_cookie.phtml">
                <arguments>
                    <argument name="triggers" xsi:type="array">
                        <item name="compareProductLink" xsi:type="string">.action.tocompare</item>
                    </argument>
                </arguments>
            </block>
        </referenceContainer>
        <referenceContainer name="content.aside">
            <block class="Magento\Catalog\Block\Product\ProductList\Related" name="catalog.product.related" template="Magento_Catalog::product/list/items.phtml">
                <arguments>
                    <argument name="type" xsi:type="string">related</argument>
                </arguments>
                <block class="Magento\Catalog\Block\Product\ProductList\Item\Container" name="related.product.addto" as="addto">
                    <block class="Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare"
                           name="related.product.addto.compare" as="compare"
                           template="Magento_Catalog::product/list/addto/compare.phtml"/>
                </block>
            </block>
            <block class="Magento\Catalog\Block\Product\ProductList\Upsell" name="product.info.upsell" template="Magento_Catalog::product/list/items.phtml">
                <arguments>
                    <argument name="type" xsi:type="string">upsell</argument>
                </arguments>
                <block class="Magento\Catalog\Block\Product\ProductList\Item\Container" name="upsell.product.addto" as="addto">
                    <block class="Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare"
                           name="upsell.product.addto.compare" as="compare"
                           template="Magento_Catalog::product/list/addto/compare.phtml"/>
                </block>
            </block>
            <block class="Magento\Catalog\Block\Product\View\Additional" name="product.info.additional" as="product_additional_data"/>
        </referenceContainer>
        <referenceBlock name="product.info.addtocart">
            <block class="Magento\Catalog\Block\ShortcutButtons\InCatalog" name="addtocart.shortcut.buttons"/>
        </referenceBlock>
        <referenceBlock name="product.info.addtocart.additional">
            <block class="Magento\Catalog\Block\ShortcutButtons\InCatalog" name="addtocart.shortcut.buttons.additional"/>
        </referenceBlock>
    </body>
</page>

You are mostly probably wanting to see this part though?

<referenceContainer name="content.aside">
            <block class="Magento\Catalog\Block\Product\ProductList\Related" name="catalog.product.related" template="Magento_Catalog::product/list/items.phtml">
                <arguments>
                    <argument name="type" xsi:type="string">related</argument>
                </arguments>
                <block class="Magento\Catalog\Block\Product\ProductList\Item\Container" name="related.product.addto" as="addto">
                    <block class="Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare"
                           name="related.product.addto.compare" as="compare"
                           template="Magento_Catalog::product/list/addto/compare.phtml"/>
                </block>
            </block>
            <block class="Magento\Catalog\Block\Product\ProductList\Upsell" name="product.info.upsell" template="Magento_Catalog::product/list/items.phtml">
                <arguments>
                    <argument name="type" xsi:type="string">upsell</argument>
                </arguments>
                <block class="Magento\Catalog\Block\Product\ProductList\Item\Container" name="upsell.product.addto" as="addto">
                    <block class="Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare"
                           name="upsell.product.addto.compare" as="compare"
                           template="Magento_Catalog::product/list/addto/compare.phtml"/>
                </block>
            </block>
            <block class="Magento\Catalog\Block\Product\View\Additional" name="product.info.additional" as="product_additional_data"/>
        </referenceContainer>

I've already moved my block around I want, just trying to see how to get my new container product.details.info.panel to the content.bottom area (instead of a footer area unless that's my only option?)

Then if that is my only option I'll have to create my own template for this as Ben says to then have it layout the way I'd like?

UPDATE #2

This sounds like it should be an easy thing to figure out but it's quite difficult..

So as both Ben & Quisse have suggested I have placed <move element="catalog.product.related" destination="content" after="-"/> in my child theme default.xml

enter image description here

It's either ignoring that move command completely or this is the after content area in my theme??

Then, upon Quisse's previous suggestion I update that move command with <move element="catalog.product.related" destination="page.bottom.container" after="-"/>

enter image description here

Which then it ends up at the bottom of the page like I want, but it ends up in the footer where I need it to be in the content bottom area (within the content container indicated by the dashed blue line). I can't just put all my elements that I want under my description in my footer. There has to be a way to place this block in the bottom of the content container..

To answer Ben's confusion, I'm looking at the vendor\magento\module-theme\view\frontend\layout\defualt.xml to see the main theme layout and the containers I can call.

Here is a little snippet I've been looking at

<referenceContainer name="main">
            <container name="content.top" label="Main Content Top"/>
            <container name="content" label="Main Content Area"/>
            <container name="content.aside" label="Main Content Aside"/>
            <container name="content.bottom" label="Main Content Bottom"/>
        </referenceContainer>

I would assume that I could reference the content.bottom container and place my related products in there but it looks like that is not the case.

I've played with it a bit and now it's getting there. I've updated the move command to be <move element="catalog.product.related" destination="main.content" after="-"/>

enter image description here

It now shows up in my #maincontent like I would like but not in the content container (indicated by the dashed blue line), how might I be able to get it in there?

UPDATE 3

So I've just made a template in my Magento_Theme and linked it exactly as you have and it's STILL showing up at the top. No matter what I do. I completely deleted all the includes in the styles.scss file so there were no styles either.

enter image description here

So I'm not really sure what I can do at this point..

Thanks guys!

Best Answer

Like Quisse said it's hard to give an accurate answer without knowing the full details, but this may help:

after and before only work when the block you're moving/declaring and the block you're positioning it before/after share the same parent.

For example if you have this structure:

  • Block A
    • Block B
    • Block C
  • Block D
    • Block E

If you tried to set block E after block B nothing would happen as they don't share the same parent. But if you tried to set block C to display before block B it would work.

The exception for this is when blocks are rendered via getChildHtml() in a template file, in which case you can only move it by changing the template.

Also, you need to add a hyphen if you want to display it before/after everything. after="-" and before="-"

Update

Adding

I have added a block to content.bottom and it works as expected:

<referenceContainer name="content.bottom">
    <block class="Magento\Framework\View\Element\Template" name="test" template="Magento_Theme::test.phtml" />
</referenceContainer>

enter image description here

Moving

I've also tried moving my custom related products to content.bottom and this works fine:

<move element="catalog.product.related.tab" destination="content.bottom" after="-" />

enter image description here

It doesn't appear to be an XML issue, could it be a CSS issue?

Related Topic