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.
app/design/frontend/[Package]/[Your_Theme]
.app/design/frontend/[Your_Package]/[Your_Theme]
.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.
[Your_Package]/[Your_Theme]
[Your_Package]/default
base/default
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.
[Your_Package]/[Your_Theme]
rwd/default
default/default
base/default
Similar to the core application code, you should keep any of the code from the base/default
and 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 layout
and template
directories.
getChildHtml()
where possible.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 $this->getChildHtml('your_template_alias')
.
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.
$this->escapeHtml()
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 Mage_Core_Block_Abstract
class.
There is also an escapeUrl()
that can be used to escape any URLs output in the template files.
If you have a CSS or JavaScript file that only needs to apply to the product page, for example, you can make use of Magento’s layout handles. In the layout XML files, simply specify the correct layout handle and add in your CSS or JS include. For example, to add a CSS resource to the product page:
<?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.
One of the more difficult aspects in Magento to control is the load order of JavaScript files. There are two ways of JavaScript, using addJs
and addItem
.
addJs
– adds the JavaScript file into the js
directory of the Magento application.addItem
– adds the JavaScript file into your theme’s folder in the skin
directory of the Magento application.Where you add your JavaScript is entirely up to you. One method is to add any third party JavaScript libraries (such as jQuery) into the js
directory via addJs, as these could be used by multiple themes.
Any theme-related JavaScript files would then be added using addItem
.
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 <update>
node.
<?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’); ?>
[/php/
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 core_translate
database table.translate.csv
located under app/design/frontend/[Your_Package]/[Your_Theme]/locale/[Your_Locale]/translate.csv
.app/locale/[Your_Locale]
.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.