Basic introduction

Magento's templating and skinning concepts offer great flexibility to adapt your shop to your visiual requirements. Fallback mechanisms are widely used inside the "Magento framework" and also apply to theming and skinning.

Files that are used for creating the output are located in:

app/design/<area>/<package>/<theme>

and

skin/<area>/<package>/<theme>

"Area" is one of "frontend", "adminhtml" or "install".

In the Magento backend you configure the package and the theme you want to use. Magento ships with a "base" package including a "default" theme. The enterprise edition adds a second package called "enterprise" that also comes with a "default" theme containing a modified design including the additional features of the enterprise edition.

Here is how this is configured in the backend:

By default Magento has a build-in hardcoded fallback strategy for design and skin files:

Package Theme
configuredPackage configuredTheme
configuredPackage default
base default

Actually there is a layer on top of this: You can configure type specific exception. E.g. you could look for layout files in a different theme than the configured default theme first.

In the example shown in the screenshot Magento will first look in to app/design/frontend/mypackage/mytheme/ for a requested design-related file. Then in app/design/mypackage/default and then in app/design/base/default/.

All Magento installations (regardless of the configured theme and package) will fallback to base/default. This is why modules bringing their own templates should put them into the base/default theme, so they will be evaluated independently from the configured settings, while enablening to overwrite them for customizations at the same time.

Custom fallbacks

For some reasons sometimes the hardcoded fallback strategy mentioned above might not fit your concept of structuring your packages and themes. Especially if your building a shop based on the Magento Enterprise Edition you don't want to leave out the enterprise/default theme, as this would require you to copy a big number of files over to your package/theme if you still want to use the additional enterprise features.

Same if you want to build your theme on top of the HTML5 boilerplate for Magento, that comes with "magento-boilerplate" package and a "default" theme.

Or you have slightly different themes for different store views that both have lots of files in common and you would like to add another fallback level.

This is where my new module "Aoe_DesignFallback" might become handy for you:

This module comes with a new store-specific configuration value that allows you to configure the fallback strategy:

The default configuration that is preset in the module matches Magento's default behaviour:

{design/package/name}:{design/theme/default}  
{design/package/name}:default  
base:default

And now you're free to configure your custom fallback on a store view level. You can refer to any configuration option by wrapping the path into curly braces "{...}" or you can specify a concrete package or theme name. Separate the package from the theme name using a colon ":" and add a new line for every fallback level. (Please not that type specific configurations (e.g. locale) still have highest priority and will be looked up in the configured package first.)

Bye bye, 'convention over configuration'. Hello, 'flexibility and transparency' :)

Here's an example of a custom fallback configuration:

The Aoe_DesignFallback module is available on GitHub.

Download the latest version directly from there:

Aoe_DesignFallback

[Update] Version 0.2.0 (introducing [current], supporting type-specific themes and design changes, and checking for duplicates)

In addition to refer to a configuration value using {path/to/configoption} you can also refer to the current package or theme Magento will evaluate using [current]. This does not only cover the configuration options {design/package/name} and {design/theme/default} but also will take type-specific configurations and even Design changs (configurable in System -> Design) into account.

Magento's actual default behavior is reflected by this configuration (I also changed this to be the default configuration shipped with the module).

base:default

Another feature that was added is detecting and avoiding duplicate fallback levels that are neighbours to each other in the configuration. Independently if they were configured referring to a configuration value, to the current theme or specificly. Also taking into account design changes and specific types.

So if you have a base theme you always want to fall back to and you're creating themes on top of that (e.g. special seasonal themes) you can configure the fallback like this:

base:default

Even if the current theme is configured with "mybasetheme" most of the time it won't be checked twice during fallback processing because the duplicate level is detected and will be translated to:

mypackage:mybasetheme  
mypackage:default  
base:default

But if some day you'll have a design change, following levels will be used:

mypackage:myspringtheme (<- configured by a design change)  
mypackage:mybasetheme  
mypackage:default  
base:default

Start playing around and experimenting with the fallback levels. Check the source code to understand what's going on and uncomment the debug lines in the end of Aoe_DesignFallback_Model_Design_Package->getFallbackScheme() to see in the log what fallback levels will be applied.

Let me know if this is useful to you or if you experience any problems...

Comments

This website uses disqus for the commenting functionality. In order to protect your privacy comments are disabled by default.

Enable Comments