Magento – how to change block ordering in layouts

layoutmagento-2.0magento2theme

I am creating a custom theme for Magento 2.

I have a header block defined this way (in Magento_Theme/layout/default.xml file):

<move element="catalog.topnav" destination="header-wrapper"/>
<move element="header.panel" destination="header-wrapper"/>
<referenceContainer name="header-wrapper" label="Page Header" as="header-wrapper" htmlTag="div" htmlClass="header-content">
</referenceContainer>

With above definition, the base header-wrapper is used, which is in module-theme/view/frontend/layout/default.xml

<container name="header-wrapper" label="Page Header" as="header-wrapper" htmlTag="div" htmlClass="header content">
    <block class="Magento\Theme\Block\Html\Header\Logo" name="logo">
        <arguments>
            <argument name="logo_img_width" xsi:type="number">189</argument>
            <argument name="logo_img_height" xsi:type="number">64</argument>
        </arguments>
    </block>
    <block class="Magento\Framework\View\Element\Html\Links" name="top.links">
        <arguments>
            <argument name="css_class" xsi:type="string">header links</argument>
        </arguments>
    </block>
</container>

As you see, block order is:

  1. logo
  2. top.links
  3. cataog.topnav
  4. header.panel

However, when rendering, this HTML is shown:

<div class="header-content">
    <ul class="header links"></ul>
    <div class="logo"></div>
    <div class="minicart-wrapper" data-block="minicart"></div>
    <div class="block block-search"></div>
    <div class="panel header"></div>
    <nav class="navigation" role="navigation"></nav>
</div>

Ordering is different from defined in layout. How can I change it?

Best Answer

To position elements you also need to add before="" or after="" when you define or move a block. But please note the block you are referencing in before or after must share the same parent as the block you're modifying.

For example if you wanted to position the logo before everything you would use:

<move element="logo" destination="header-wrapper" before="-" />

As - tells Magento to position it before everything else, after="-" would position it last.

To position an element before or after another element to use the block name instead of -, for example to position top.links after the logo you would use:

<move element="top.links" destination="header-wrapper" after="logo" />

More on this can be found on the official dev docs

Related Topic