basically containers are the equivalent of the core/text_list
blocks in magento 1.
"philosophically" they work the same, the only difference is that containers
are predefined blocks that only support other child blocks.
Some examples are content
, after.body.start
, header-wrapper
.
You can see all defined containers for example in the Magento/Theme/view/base/page_layout/*
.
Here is an example from empty.xml
.
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_layout.xsd">
<container name="root">
<container name="after.body.start" as="after.body.start" before="-" label="Page Top"/>
<container name="page.wrapper" as="page_wrapper" htmlTag="div" htmlClass="page-wrapper">
<container name="global.notices" as="global_notices" before="-"/>
<container name="main.content" htmlTag="main" htmlId="maincontent" htmlClass="page-main">
<container name="columns.top" label="Before Main Columns"/>
<container name="columns" htmlTag="div" htmlClass="columns">
<container name="main" label="Main Content Container" htmlTag="div" htmlClass="column main"/>
</container>
</container>
<container name="page.bottom" as="page_bottom" label="Before Page Footer Container" after="main.content" htmlTag="div" htmlClass="page-bottom"/>
<container name="before.body.end" as="before_body_end" after="-" label="Page Bottom"/>
</container>
</container>
</layout>
basically what's defined as <container name="..." />
can be accessed by referenceContainer
. what's declared as <block .... />
can be referenced by referenceBlock
A preference is equivalent to class rewriting from Magento 1. It's equivalent to saying, "Whenever code asks for ClassA
, give them MyClassB
instead." MyClassB
is expected to be a complete implementation of ClassA
, plus whatever behavior you add or modify on top.
As in Magento 1, only one preference (rewrite) can be active for a class at one time unless you chain them manually (such that MyClassB
extends OtherClassB
, and OtherClassB
extends ClassA
).
A plugin allows you to execute code before, around, or after methods from the class you're hooking onto. Your plugin class does not replace the target class, and it is not an instance of it. You just have methods before{method}
, around{method}
, after{method}
which get executed at the appropriate time in respect to {method} on the target class.
Since plugins do not replace the target class, any number of plugins can be active on a class simultaneously. Magento just executes them one after another based on the sortOrder parameter in your XML.
Because of that, plugins are much more flexible than preferences. You should use plugins whenever possible, and avoid preferences for rewriting classes unless absolutely necessary.
You can read more about how plugins work and how to use them in the official documentation.
Best Answer