Skip to content

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