Magento – Magento 2: Creating a custom layout

customlayoutmagento2module

I'm having trouble creating a custom layout. I have successfully created a layout called home_page.xml which is a copy of the default 1column layout.

I have selected this layout for my home page, but can't seem to add any content to it. Am I limited to only adding containers to the home_page.xml file? No HTML that I add will appear on my home page.

I've been reading on how to create and reference containers but it doesn't make a lot of sense, and I'm not sure what files I need to create in order to do so.

Here is my home_page.xml file:

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd">
    <update handle="empty"/>
    <referenceContainer name="page.wrapper">
        <container name="header.container" as="header_container" label="Page Header Container"  htmlTag="header" htmlClass="page-header" before="main.content"/>

        <div id="test123"><p>This is a test</p></div>

        <container name="page.top" as="page_top" label="After Page Header" after="header.container"/>
        <container name="footer-container" as="footer" before="before.body.end" label="Page Footer Container" htmlTag="footer" htmlClass="page-footer" />
    </referenceContainer>
</layout>

The div doesn't show up. I can successfully remove the header and footer containers however, so I know that the layout file is working successfully.

My ultimate goal is to add a full width content slider directly under the header on the home page. Any help is extremely appreciated. I've been searching around for a couple days and have run out of new content to study.

Best Answer

The problem here is that you're misunderstanding containers and blocks.

In M2, there is a new concept of containers which are containers for blocks but not real block, they are used to define the structure of a page in the XML and then blocks are assigned to containers.

A container exists for the sole purpose of assigning content structure to a page. A container has no additional content except the content of included elements. Examples of containers include the header, left column, main column, and footer.

A block represents each feature on a page and employs templates to generate the HTML to insert into its parent structural block. Examples of blocks include a category list, a mini cart, product tags, and product listing.

Definition of a container from the official doc:

A structure without content that holds other layout elements such as blocks and containers.

Details: A container renders child elements during view output generation. It can be empty or it can contain an arbitrary set of <container> and <block> elements.

Only blocks are being rendered even if the framework generates the container based on the attributes you specified.

You can find more informations at the following links:

To implement your new layout you need to create a container instead of your div:

<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd">
    <update handle="empty"/>
    <referenceContainer name="page.wrapper">
        <container name="header.container" as="header_container" label="Page Header Container"  htmlTag="header" htmlClass="page-header" before="main.content"/>

        <container name="content" label="Main Content Container" htmlTag="div" htmlClass="column content"/>

        <container name="page.top" as="page_top" label="After Page Header" after="header.container"/>
        <container name="footer-container" as="footer" before="before.body.end" label="Page Footer Container" htmlTag="footer" htmlClass="page-footer" />
    </referenceContainer>
</layout>

Then in the layout XML related to your new page you can use the following code to add a block to your container:

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

Finally you can write the following code in your test.phtml template:

<div id="test123"><p>This is a test</p></div>

On the other hand, if you need the div to be a container you can simply do:

<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd">
    <update handle="empty"/>
    <referenceContainer name="page.wrapper">
        <container name="header.container" as="header_container" label="Page Header Container"  htmlTag="header" htmlClass="page-header" before="main.content"/>

        <container name="test" label="Main Content Container" htmlTag="div" htmlClass="column content" htmlId="test123" />

        <container name="page.top" as="page_top" label="After Page Header" after="header.container"/>
        <container name="footer-container" as="footer" before="before.body.end" label="Page Footer Container" htmlTag="footer" htmlClass="page-footer" />
    </referenceContainer>
</layout>

That will give you the following container which then you can use (as explained above) to add blocks into it.

<div id="test123" class="content column"></div>