こんにちは!
Nishiです。前回はMagentoの「referenceBlock と referenceContainer の違いと使い分け」についての記事を書きました。
今回は、Layout XMLでよく利用する before・after・remove について書いていきたいと思います。
これらを利用すると、コアファイルを直接変更することなく、独自テーマ側のLayout XMLから、
・表示順序を変更する
・不要な要素を非表示にする
といったレイアウト変更を行うことができます。
※本記事は、Magento Open Source 2.4.7-p3 を使用しています。
before・after・removeとは?
before・after・remove は、Layout XMLでBlockやContainerの表示位置や表示状態を変更するときに使用します。
それぞれの役割は以下のとおりです。
- before … 指定した要素の前に配置する
- after … 指定した要素の後に配置する
- remove … 指定した要素をレイアウトから除外する
before・after は、block タグや container タグに指定します。
また、remove は既存のBlockやContainerを参照するため、referenceBlock や referenceContainer に指定します。
どのタグで利用できる属性なのかは、以下のコアファイルで確認することができます。
vendor/magento/framework/View/Layout/etc/elements.xsd
[補足]
before・afterで指定できるのは、同じ親要素を持つ要素同士です。
すでに存在している要素を別の場所へ移動したい場合は、<move> タグを使用します。
<move> については次回の記事で詳しく説明します。
今回使用するLayout XML
今回は、以前の記事「Magento: ブロックを使ってみよう」で作成した、
トップページ用のLayout XMLを引き続き使用します。
app/design/frontend/Test/CustomTheme/Magento_Cms/layout/cms_index_index.xml
現在、このファイルには管理画面で作成したCMS Block(test_block)を content Containerへ表示する設定が入っています。
今回は複数のBlockを使用するため、Block名を custom.cms.block から custom.cms.block.a に変更しています。
<?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> <referenceContainer name="content"> <block class="Magento\Cms\Block\Block" name="custom.cms.block.a"> <arguments> <argument name="block_id" xsi:type="string">test_block</argument> </arguments> </block> </referenceContainer> </body></page>
ここに2つCMS Blockを追加して、表示順序を変更してみます。
あらかじめ管理画面で、識別子が test_block_b と test_block_c のBlockも作成しておいてください。
beforeで表示順序を変更してみよう
custom.cms.block.a の前に新しいBlockを表示したい場合は、before を使用します。
<?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> <referenceContainer name="content"> <block class="Magento\Cms\Block\Block" name="custom.cms.block.a"> <arguments> <argument name="block_id" xsi:type="string">test_block</argument> </arguments> </block> <block class="Magento\Cms\Block\Block" name="custom.cms.block.b" before="custom.cms.block.a"> <arguments> <argument name="block_id" xsi:type="string">test_block_b</argument> </arguments> </block> </referenceContainer> </body></page>
before="custom.cms.block.a" と指定することで、
XML上では後に記述している custom.cms.block.b が、custom.cms.block.a より前に表示されます。
このように、Layout XMLでは記述した順番だけではなく、
before・after の指定によって表示順序を変更することができます。
キャッシュをクリアして、画面を確認してみましょう。
$ bin/magento c:c
test_block_b の内容が test_block より上に表示されていることが確認できます。
afterで表示順序を変更してみよう
先ほどとは逆に、後ろへ表示したい場合は after を使用します。
<?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> <referenceContainer name="content"> <block class="Magento\Cms\Block\Block" name="custom.cms.block.b" after="custom.cms.block.a"> <arguments> <argument name="block_id" xsi:type="string">test_block_b</argument> </arguments> </block> <block class="Magento\Cms\Block\Block" name="custom.cms.block.a"> <arguments> <argument name="block_id" xsi:type="string">test_block</argument> </arguments> </block> </referenceContainer> </body></page>
このように指定すると、custom.cms.block.b は custom.cms.block.a の後ろに表示されます。
キャッシュをクリアして、画面を確認してみましょう。
$ bin/magento c:c
test_block_b の内容が test_block より下に表示されていることが確認できます。
先頭・末尾へ配置する場合
before・after には、Block名の代わりに - を指定することもできます。
- before="-" … 同じ親要素内の先頭へ配置する
- after="-" … 同じ親要素内の末尾へ配置する
Block名を指定せず、単純に先頭や末尾へ配置したい場合に便利です。
例えば、3つ目のBlockに before="-" を指定してみます。
<?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> <referenceContainer name="content"> <block class="Magento\Cms\Block\Block" name="custom.cms.block.a"> <arguments> <argument name="block_id" xsi:type="string">test_block</argument> </arguments> </block> <block class="Magento\Cms\Block\Block" name="custom.cms.block.b"> <arguments> <argument name="block_id" xsi:type="string">test_block_b</argument> </arguments> </block> <block class="Magento\Cms\Block\Block" name="custom.cms.block.c" before="-"> <arguments> <argument name="block_id" xsi:type="string">test_block_c</argument> </arguments> </block> </referenceContainer> </body></page>
XML上では最後に記述していますが、before="-" を指定しているため、
custom.cms.block.c が一番先頭に表示されます。
キャッシュをクリアして、画面を確認してみましょう。
$ bin/magento c:c
表示順序は test_block_c → test_block → test_block_b になっています。
removeでBlockを非表示にしてみよう
続いて、remove を使用して既存Blockを非表示にしてみます。
今回は、Magento標準でフッターに用意されている「ニュースレター登録」フォームを非表示にします。
このBlockは以下のLayout XMLで定義されています。
vendor/magento/module-newsletter/view/frontend/layout/default.xml
<?xml version="1.0"?><!--/** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */--><page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="head.components"> <block class="Magento\Framework\View\Element\Js\Components" name="newsletter_head_components" template="Magento_Newsletter::js/components.phtml" ifconfig="newsletter/general/active"/> </referenceBlock> <referenceContainer name="footer"> <block class="Magento\Newsletter\Block\Subscribe" name="form.subscribe" as="subscribe" before="-" template="Magento_Newsletter::subscribe.phtml" ifconfig="newsletter/general/active"> <arguments> <argument name="button_lock_manager" xsi:type="object">Magento\Framework\View\Element\ButtonLockManager</argument> </arguments> </block> </referenceContainer> </body></page>
確認すると、form.subscribe という名前で定義されています。
また、このBlockには before="-" が指定されています。
Magento標準でも、今回紹介した指定方法が実際に利用されています。
全ページ共通で反映させるため、独自テーマ側に default.xml を作成します。
app/design/frontend/Test/CustomTheme/Magento_Theme/layout/default.xml
次に、以下のコードを default.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> <referenceBlock name="form.subscribe" remove="true"/> </body></page>
remove="true" を指定することで、対象Blockをレイアウトから除外できます。
キャッシュをクリアして確認してみましょう。
$ bin/magento c:c
フッターからニュースレター登録フォームが消えていることが確認できます。
before・after・removeを利用するときの注意点
before・after が反映されない場合は、指定しているBlock名が正しいか、また同じ親要素内のBlockを指定しているか確認してみましょう。
Layout XMLを変更した場合は、キャッシュクリアも忘れずに行います。
また、remove="true" はLayout XML上から対象要素を除外する指定です。
PHPファイルやLayout XMLの定義自体を削除するものではありません。
最後に
今回は、Layout XMLで利用する before・after・remove について確認しました。
- before … 指定した要素の前に配置する
- after … 指定した要素の後に配置する
- remove … 指定した要素をレイアウトから除外する
これらを利用することで、コアファイルを直接変更することなく、
独自テーマ側のLayout XMLだけで表示順序の変更や不要なBlockの非表示を行うことができます。
次回は、既存のBlockやContainerを別の場所へ移動する<move>タグについて紹介します。

