Magento supports unparalleled theme flexibility and sophistication that allow for incredibly custom branding while still retaining development efficiency and upgrade compatibility. In particular, the theme asset fallback system allows theme developers to only modify the parts of a theme which actually need to be customized. This feature also enables merchants to quickly deploy stylized stores while still retaining features developed for the overall brand.
Magento Enterprise 1.14 and Community 1.9 introduced a new, more flexible theme fallback mechanism. Each theme can now specify its parent, which can then specify its parent, and so on. This theoretically allows infinite fall back levels instead of the fixed number of fall back “slots” in older versions.
As powerful as this concept is, the core code powering it is relatively straightforward.
While loading the current area in a controller’s preDispatch() method, a singleton instance of
Mage_Core_Model_Design_Configis instantiated. This class’s constructor scans all themes for an etc/theme.xml file, and loads the contents into a in-memory config instance.
The contents of the theme.xml files are not yet interpreted, but the config tree is ready for when the time comes.
When a theme asset (translation, layout update file, template, etc) is loaded,
Mage_Core_Model_Design_Package::getFilename() is used to determine the actual filesystem path to the file.
The package model tries each theme in the fallback path, then finally falls back to base/default if all else fails. The fallback path itself, however, is generated by
Mage_Core_Model_Design_Fallback::getFallbackScheme() as seen below.
For compatibility with themes developed before 1.14/1.9, this method looks for the presence of a node in the design config for the current area/package/theme (which, of course, was directly populated from the contents of that theme’s theme.xml).
In the event that the theme does specify a parent node (and therefore opts-in to the new fallback logic),
Mage_Core_Model_Design_Fallback::_getFallbackScheme() walks up the chain of parent nodes, starting from the current theme’s parent.
Otherwise, _getLegacyFallbackScheme() takes over and emulates the old fallback behavior.
This method returns a fallback path of the following form:
In the event that a translation/template/skin/layout override is specified in System Configuration, the theme fallback is calculated in the same way, but the overridden file type follows an independent fallback path starting with the configured override theme.
Considering the new theme fallback capabilities, current versions of Magento will use this fallback path to load theme asset files.
Magento versions before Enterprise 1.14 and Community 1.9 used much simpler, albeit far less powerful and flexible, fallback logic.
Mage_Core_Model_Design_Package::getFilename() from Enterprise 1.13
Just as the legacy fallback logic used in current versions, the classic fallback logic simply checked the current theme for the given file type, the default theme set in System Configuration, the hard-coded /default theme, then finally fell back to base/default.
With this in mind, classic versions of Magento will use the following fallback path.
By allowing merchants to configure a chain of overriding themes combined with the ability to configure the current theme at the store view level, Magento provides a powerful and efficient mechanism to customize individual stores or landing pages while ensuring that core theme assets are consolidated and centralized. Additionally, Magento Enterprise 1.14 and Community 1.9 support endless flexibility and scalability by providing support for infinite levels of theme fallback.