Themes in Magento are used to customise the look and feel of your store. Here is a list of the top 10 best theme practices for Magento 1.
Developers may choose a couple of locations to add a theme: within one of the default Magento package directories, or by adding their own package.
There is no advantage of choosing one or the other, it comes down to personal preference. However, if you choose to create your own package and theme, you may need to move some css and image resources from the location in
default/default into the location of your theme.
This is because of the Magento fallback system. Adding your own package and theme means that Magento uses the following fallback.
Many of Magento’s default stylesheets and image files are located in
default/default, and as the above fallback skips the check for this location, you may end up with a broken looking site.
In Magento 1.9, this problem can be avoided by making use of the infinite fallback system via the
theme.xml file. In this file, you can specify a parent theme.
<?xml version="1.0"?> <theme> <parent>rwd/default</parent> </theme>
The fallback then can be seen below.
Similar to the core application code, you should keep any of the code from the
default/default themes unmodified. This is because any upgrades to the Magento system will cause changes made in these themes to be lost.
There are many template files that Magento comes with, some of which you do not need to change at all. Any template and layout files that you do not include in your theme’s directory will still be picked up via Magento’s fallback system.
For example, if your theme was based off
rwd/default, you do not need to copy the whole contents of the
The template files contain a mixture of HTML and PHP code. Depending on how much functionality resides on a page, these files can often become clogged and difficult to read.
It is therefore advised to split any code that represents different functionality into their own template files. Your split template files can still be included in the main template by using
Remember, if you declare a template within a structural block (e.g. header, left, content, right), those are blocks of type
core/text_list, you do not need to use
getChildHtml() as the files will be output automatically.
One of the most important rules of programming: never trust user input! It is for this reason that any output of user input in the template files should be escaped. Thankfully, Magento comes with an
escapeHtml() method that can be accessed in all .phtml files whose block extends the
There is also an
escapeUrl() that can be used to escape any URLs output in the template files.
<?xml version="1.0"?> <layout> <catalog_product_view> <reference name="head"> <action method="addItem"> <type>skin_css</type> <name>css/theme.css</name> </action> </reference> </catalog_product_view> </layout>
This means that other pages will not have to make an additional HTTP request to load a stylesheet that they will not use.
jsdirectory of the Magento application.
skindirectory of the Magento application.
js directory via addJs, as these could be used by multiple themes.
The files added by
addJs will be added before those added by
addItem regardless of the order you specify them in the layout XML.
<?xml version="1.0"?> <layout> <default> <reference name="head"> <action method="addItem"> <type>skin_js</type> <name>js/theme.js</name> </action> <action method="addJs"> <script>js/jquery.js</script><!-- This is included before js/theme.js --> </action> </reference> </default> </layout>
When constructing layout XML configuration, there may be times where you could include the same layout configuration in multiple layout handles.
Let’s assume that you want to add a template file to both the cart and checkout page. Instead of writing code like the below.
<?xml version="1.0"?> <layout> <checkout_cart_index> <reference name="content"> <block type="core/template" name="checkout.sales.banner" as="sales_banner" template="custom/sales_banner.phtml" /> </reference> </checkout_cart_index> <checkout_onepage_index> <reference name="content"> <block type="core/template" name="checkout.sales.banner" as="sales_banner" template="custom/sales_banner.phtml" /> </reference> </checkout_onepage_index> </layout>
Rather than duplicating the declaration, you can add the declaration to a custom layout handle, and then include that handle into the cart and checkout handles using the
<?xml version="1.0"?> <layout> <checkout_cart_index> <update handle="sales_banner" /> </checkout_cart_index> <checkout_onepage_index> <update handle="sales_banner" /> </checkout_onepage_index> <sales_banner> <reference name="content"> <block type="core/template" name="checkout.sales.banner" as="sales_banner" template="custom/sales_banner.phtml" /> </reference> </sales_banner> </layout>
When outputting any kind if price data in Magento, developers often forget that there are inbuilt functions for handling number formatting and printing out the currency symbol.
Often there is code that looks like the following.
<?php echo Mage::app()->getLocale()->currency(Mage::app()->getStore()->getCurrentCurrencyCode())->getSymbol() . number_format($_product->getFinalPrice(), 2); ?>
Whilst this will give you the desired result, it is a lot more code than is needed just to print out the price. This can be better achieved using the
currency() method of the Magento core helper class.
<?php echo $this->helper('core')->currency($_product->getFinalPrice(), true, false); ?>
Magento provides the ability to run multiple store views using the same Magento instance. Usually, merchants have these different views to serve the website in different languages.
Many strings in the Magento template files will look similar to the below.
__(‘Add to Cart’); ?>
This means that this string can be translated into different languages if required. This is done via the use of the
__() translation method.
Merchants can translate strings in Magento using three different methods.
System -> Configuration -> Developer. Translated strings are then saved in the
You may decide that you’ll never need to use translations, however the time taken to wrap the string around the
__() function is negligible, and so it is worth doing for any future development.
Note: This article is based on Magento Community/Open Source version 1.9.