Automatic Template Overrides
The compatibility module skeleton that is generated together with the repo by the Hyvä team contains a dependency on
hyva-themes/magento2-compat-module-fallback
in the composer.json
.
Note
Please refer to the step-by-step overview of the compat module development process for details on how to get a skeleton module.
The dependency on the compat-module-fallback
extension allows modules to be registered as compatibility modules using frontend/di.xml
.
When a module is registered as a compatibility module, the compatibility module template directory is automatically injected in the design fallback for the files from the original module.
This allows overriding templates without having to declare layout XML files in the compatibility module.
If the original module injects blocks or changes templates in PHP plugins or event observers, those templates can also be customized using the automatic template overrides. No need to write additional plugins.
Using the automatic fallback is straight forward: we need to create a template file in the compatibility module with the same name as the original, and that is all.
Example scenario:
For this example, let’s assume an original module Orig_Module
and a compatibility module Hyva_OrigModule
.
The original module uses a template file Orig_Module::example.phtml
.
If the compatibility module contains a view/frontend/templates/example.phtml
file, the compatibility module template will be used instead of the original one.
Overriding a compatibility template in a theme
Templates from compatibility modules can be overridden in a theme.
When doing so, the original module name has to be used.
The reason is the automatic compatibility module fallback does not change the template declaration.
Example
Template declaration:
Mirasvit_Gdrp::cookie_bar.phtml
Original Module Template:
Mirasvit/Gdpr/view/frontend/templates/cookie_bar.phtml
Compat Module Template:
Hyva/MirasvitGdpr/view/frontend/templates/cookie_bar.phtml
Theme Override:
app/design/frontend/Vendor/theme/Mirasvit_Gdpr/templates/cookie_bar.phtml
DI Configuration
The initial configuration is automatically included in the compatibility module skeleton.
In most cases no additional tweaking is required.
But in case you need to adjust the configuration manually, you can do so as follows.
Modules can have more than one compatibility module, and compatibility modules can have more than one original module.
Because of this reason, the di.xml
argument map is not a simple associative array, but rather an array of pairs.
The resulting array structure will look something like this:
[
[
'original_module' => 'Foo_Bar',
'compat_module' => 'Hyva_FooBar'
],
[
'original_module' => 'Foo_Bar',
'compat_module' => 'Hyva_MoreFooBar'
],
...
]
Defined in the frontend/di.xml
that structure looks like this:
<type name="Hyva\CompatModuleFallback\Model\CompatModuleRegistry">
<arguments>
<argument name="compatModules" xsi:type="array">
<item name="orig_module_map" xsi:type="array">
<item name="original_module" xsi:type="string">Orig_Module</item>
<item name="compat_module" xsi:type="string">Hyva_OrigModule</item>
</item>
<item name="orig_module2_map" xsi:type="array">
<item name="original_module" xsi:type="string">Other_Module</item>
<item name="compat_module" xsi:type="string">Hyva_OrigModule</item>
</item>
</argument>
</arguments>
</type>
The above example registers the module Hyva_OrigModule
as a compatibility module for both Orig_Module
and Other_Module
.
Note
The keys of the first level of the compatModules
argument array do not matter as long as they are unique, so they don't conflict with another compat module.
(In the example above orig_module_map
and orig_module2_map
).
Price Renderer Templates
The product price renderer uses its own layout instance MagentoFrameworkPricingRenderLayout
. At the time of writing automatic template overrides do not work for price renderer templates.
Instead, the compat module template should be set using layout XML:
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
<referenceBlock name="render.product.prices">
<arguments>
<argument name="the-product-type" xsi:type="array">
<item name="prices" xsi:type="array">
<item name="final_price" xsi:type="array">
<item name="render_template" xsi:type="string">Hyva_OrigModule::product/price/final_price.phtml</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</layout>
More Details
The first example above glossed over some details for sake of clarity.
The fallback actually contains two additional folders for each compatibility module.
This is useful when:
- The compatibility module handles more than one original module.
- Both original modules have a template file with the same name.
The following lists of fallback modules hopefully make it clear:
Native Magento fallback
1. <theme_dir>/<module_name>/templates
2. <module_dir>/view/<area>/templates
3. <module_dir>/view/base/templates
Fallback with one compatibility module for Orig_Module
1. <theme_dir>/<module_name>/templates
2. <compat_module_dir>/view/<area>/templates/Orig_Module
3. <compat_module_dir>/view/<area>/templates
4. <module_dir>/view/<area>/templates
5. <compat_module_dir>/view/base/templates/Orig_Module
6. <compat_module_dir>/view/base/templates
7. <module_dir>/view/base/templates
As you can see, two new possible locations for a template are added to the fallback path.
Example: one compat module for two original modules
Original files:
Orig_Module::cookie_bar.phtml
Other_Module::cookie_bar.phtml
Overrides:
Hyva_OrigModule::Orig_Module/cookie_bar.phtml
Hyva_OrigModule::Other_Module/cookie_bar.phtml