Always show shipping costs in Magento


Sometimes you just need one shipping method, or perhaps 99% of your customers use a specific method. This is often the case for European shops serving just one country. By default, Magento allows customers to get a quote estimate for shipping costs in the cart page.

The customer has to set it’s country and select the appropriate method in order to get a correct quote, including the shipping costs. In the scenario I mentioned earylier, it could be best to just set the country and shipping method by default. This way the customer will always get a price including shipping costs. Never again will they be surprised by a higher then expected price at the end of the checkout process!

A solution
So how to achieve this? Well… One can write a small extension that catches Magento’s sales_quote_collect_totals_before and set a shipping method if none is set. This shipping method then should be configurable from Magento’s backend. Not into writing code? Check the attachment. Download the extension here. I tested it in Magento CE 1.4, 1.5, 1.6. Should work in 1.7 as well.

Magento always show shopping costs

Magento always show shopping costs

Instructions for installing this extension:
1. Download the zip (DUH!)
2. Extract it’s contents to the root of your Magento installation. You can use FTP to do that. It’s the directory containing index.php [App] [Skin] [Media] among others
3. Log in to your Magento backend
4. Go to System -> Cache Management, select all options, and in the action dropdown select “Refresh”. Then click Submit.
5. Log out/in to your backend
6. Go to System -> Configuration -> Shipping Settings and drop down the “Origin” selection
7. This extension adds two new options here; “Apply defaults to empty quote” and “Default shipping method”
8. Set “Apply defaults to empty quote” to “Yes” , set “Default shipping method” to your preferred shipping method. And make sure “Country” is set.
9. Click save config.
10. All done!

When a customer visits your site and starts adding stuff to his shopping cart, all prices will be shown including shipping costs! (If this does not happen the first time you visit your site yourself, clear all your cookies, as you might still have an active quote present, in which case the extension will leave it alone).

How does this work… I mean in code…?
Well… The extension uses a simple observer to check if the shipping address has a country set. If it does not (which is the case for an empty quote) it will set one including the default method. Pretty simple stuff!!

Update 7/9/12: Idev OneStepChecout bug
Stevan from Enigma Webdesign reported an issue with Idev OneStepChecout. As it turns out the Idev OSC extension “assumes” a billing address is present in the quote when a shipping address is found. This causes the OSC to load with no valid billing address, and as a result, it will show the default country with just the default payment method.

One can work around this by using this version of the extension when using Idev OneStepChecout. This update will set a billing address as well as the shipping address, to enable Idev OCS to work. Set the “Apply defaults to billing address” option in “System -> Configuration -> Shipping Settings” to Yes. Download the update here.

Like this free extension?
Let us know, and like our Facebook page!

Remove ‘Orders and Returns’ from default Magento footer

In Magento 1.6 they’ve added an extra link to the footer called ‘orders and returns’. This link however is added using an ‘addLinkBlock’ call, which doesn’t have a remove equivalent. Normal links added using addLink can be removed using removeLinkByUrl. But as I said, this isn’t possible with addLinkBlock.

First I tried removing the block with a <remove name=”return_link”/> but this generates an error (call to a method on a non object in page/template_links). One solution would be to just copy sales.xml to your own theme and remove the addLinkBlock action. But I find this a nasty solution as it isn’t update compatible.

Another solution, which also will work and doesn’t require you to copy a layout.xml file, is setting the template to an empty template file. This can be done using the following XML in your layout file (you probably want to place it in the <default> handle):

<reference name="return_link">
    <action method="setTemplate"><template></template></action>

This makes “toHtml” on the block return nothing (an empty string) and thus doesn’t add anything to the footer_links

Magento infinite HTML escape for attribute option values and labels

Magento 1.6 seems to contain a bug that infinitly escapes dropdown and multiselect attribute values.

For you as the end user this means that when you add an option like “M&M” Magento will escape this to “M&M” on this first save. When you open the attribute you will see “M&M”. However when you save it again, Magento will escape it once more to “M&amp;M” and it will keep adding for each save you do.

This means your users will get weird values in their layered navigation and so on.

A bug report is filed here:

A quick fix is to comment out line 164 to 171 of app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php.
If the bug is not fixed when a new version of Magento is released, you will have to make a patch or move the code to local (or just comment these lines out again).

An even better fix by the way would be to unescape the options before displaying them. Will get back to you on how doing that later.

Magento 1.6 clear multiselect bug

Magento and appear to contain a nasty bug that makes it impossible to clear all values assigned to an attribute.
In older versions of Magento there was an “empty” option that you could select to clear the selection.

A quick and dirty fix would be to add this;

$html .= $this->_optionToHtml('', ''); 

right before

$value = $this->getValue();

around line 62 of the file /lib/Varien/Data/Form/Element/Multiselect.php

This however is a quick fix with two notes;
1. If you don’t expect this thing to be fixed in the next upgrade you install, make a copy of the file in /app/code/local or make a patch. Because if you don’t, the fix will be overwritten on upgrade and the bug will reappear if the Magento team ignores to fix it.
2. The actual problem is not caused in this file, it was however the easiest way to fix it. So when I have the time I will make a better fix. This should however work without side effects.

Magento: Help the tabs aren’t working in IE9!

If you’re running Magento and on the product detail page the tabs, for description, tags et cetera aren’t working in IE9 the problem lies in a prototype or IE9 bug. The easiest way of fixing this is changing one line of javascript.

When you open the template file of the tabs, which is catalog/product/view/tabs.phtml, you’ll find a line which says:

ul.getElementsBySelector('li', 'ol').each(function(el){

The solution is to remove the second parameter of this getElementsBySelector method, so the line looks like:


Another solution I found on the internet is adding a meta tag which makes IE9 render the page in IE8 mode. But this is the same as sticking your head in the sand, or putting some buck-tape on a flashing warning light in your car.

Configuration files with sensitive information are accessible from the outside.

So you’re migrating your Magento installation to another domain and you’re not wanting to wait for your domain name to transfer or for DNS to sync you get this warning in the Magento admin panel: “As a result, configuration files with sensitive information are accessible from the outside.”. That, when you do some research, seems to be associated with the /app/etc/local.xml being accessible from the outside.

But being the good system administrator you are, you made sure that either AllowOverride All was enabled on you Magento base directory or for the better administrators, you moved the config for each directory to Apache and set AllowOverride None, and you’re still getting this message?!

The problem resides in the code Magento uses to check if your config file with sensitive database password is accessible from the outside. It does this in Mage_Adminhtml_Block_Notification_Security.php;

    private function _isFileAccessible()
        $defaultUnsecureBaseURL = (string) Mage::getConfig()->getNode('default/' . Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_URL);

        $http = new Varien_Http_Adapter_Curl();
        $http->setConfig(array('timeout' => $this->_verificationTimeOut));
        $http->write(Zend_Http_Client::POST, $defaultUnsecureBaseURL . $this->_filePath);
        $responseBody = $http->read();
        $responseCode = Zend_Http_Response::extractCode($responseBody);

        return $responseCode == 200;

This needs to be able to resolve itself. If the address still resolves to another address that will return an 200 OK page (perhaps your old domain) then the error will be displayed. This will fix itself when DNS syncs. Or alternatively you can make sure your new domain name is added to /etc/hosts file or c:\Windows\System32\Drivers\etc\hosts.

Link object popup failing in XAF after deployment

Last week I deployed an XAF Web application to one of our production servers running IIS 7. All seemed well until I noticed that all Object Link windows (the popup that allows you to make associations between existing objects) missed the grid control and the image. The button where there but without the grid the popup isn’t very useful is it…

Turned out that the web.config (which was generated at project creation trough a New Project -> XAF template) contained this line;

The problem being here this handler will not used unless “runtimeVersionv2.0″, which in my production IIS 7 server was not the case. Removing the runtimeVersionv2.0 precondition fixed things…

Magento back to overview button in product detail view

The breadcrumbs block provide the user with the ability to seamlessly navigate your Magento webshop. Sometimes however it’s nice to have a big, fat, BACK TO OVERVIEW button for visitors that have problems reading or who see no further than (the end of) one’s nose. In Magento it’s possible to navigate to a product in several ways (search, catalog, CMS etc etc) and a product can exists in several categories.

So for the back button I would rely on the breadcrumbs, as they present us with all the functionality we need for our back to overview button. So adding the button to our breadcrumbs block template is the way to go (it actually came in handy considering the design in this case, but you can use the layout XML to add more breadcrum children with different templates if this is not the case).

Edit app/design/frontend/YOURTEMPLATE/default/template/page/html/breadcrumbs.phtml and change it to something like this:


This will provide you with a nice button. One that only shows up in the product detail view. Or remove the Mage::registry(‘current_product’) check to make it work everywhere.

Magento: Set number of columns in grid

A quick Magento tip.

If you would like to set the number of columns in a grid, you can do this using the layout.xml. Just call setColumnCount using <action />. This has to be done on the grid block.

For example, if you would like to set the number of columns in the product grid on the category page, you could do this using the following XML.

    <reference name="product_list">
        <action method="setColumnCount"><count>3</count></action>

The name of the parameter (<count/>) could be anything, but must be specified. Just specifying 3 between <action/> doesn’t work.

Change translations on a theme basis

So you’re developing a Magento skin and want to change some text. For example, you want to change the text “Currently shopping by:” to “Filtering on”. Of course you don’t want to change the localization in app/locale, because that would affect every skin you have installed.

The solution is easy, create a locale for the skin. Every skin can have it’s own locales. Just make a folder for the language (en_US, for example) in the folder of the skin and place a translate.csv in it. For example, create the file:


The content of this translate.csv should be the same as the translation files in app/locale. So following the example, the content would be

“Currently shopping by:”,”Filtering on”

Naturally you could also use your own texts. If in the template file you have the text “Search in our catalog”, coded as

$this->__('Search in our catalog');

You could translate this to all the different languages your shop supports by creating a translate.csv file for every supported language and place it in the locale folder for the language.