Archive for the 'Magento Tips' Category

July 5, 2011

OK, this one is a bit of an edge case, but I’ve dealt with similar issues while trying to set a static block through a template file when you need that static block to change based on the product being viewed.

Sure, it’s easy to call the static block in the product’s custom layout update, but the problem there is that you can’t place that block anywhere between the title and product description. All of those elements are called as childHtml and can’t be referenced by the layout XML. What happens if you need to put a special notice near the price or short description?

You could create a custom theme for each different product, but that could lead to a maintenance nightmare when you need to update a product page. You could also create a custom block and template, but that takes a lot of effort.

We’ll start by looking at calling a static block in the template file. It’s fairly academic to add the static block in the template’s phtml code in Magento:

<?php echo $this->getLayout()->createBlock('cms/block')->setBlockId('my_static_block')->toHtml() ?>

This works great, but every product page will have the exact same static block.

In this particular case, I needed to add some pricing information based on the product’s SKU. For simplicity I’ll say the SKUs were 1, 2, and 3. In this case, I created a static block for each of the three pricing notes, and set the identifier to product1, product2, and product3 respectively.

Magento Dynamically Set Static Block From Template

Now, in the template file, I’ve changed the way the setBlockId is called:

<?php echo $this->getLayout()->createBlock('cms/block')->setBlockId('pricing'.$_product->getSku())->toHtml() ?>

This way the setBlockId would change depending on the product SKU. In theory this can also be done with custom attributes or any other product value. As an added bonus, it fails gracefully if it encounters a static block that doesn’t exist. Say for SKU = 4 I haven’t created a static block, so on that product page, no extra html is generated and no errors occur.

As I said, it’s a bit of an edge case, but it might come in handy in that rare instance.

June 21, 2011

Magento is a great tool, but sometimes adds some unnecessary friction to the buying process. Take Custom Product Options drop-down list for example. There is no way to set an option as a default.

If you have several custom options on a product, but 80% of the customers are buying a certain option there is no point in making those customers actually choose the option from the list – it should be set by default.

There is a relatively easy fix for this one.

CAUTION::To do this requires editing of one of the Core Magento files. If you upgrade your Magento version, it will overwrite this code. Also, this will apply to all Product Custom Option Drop-down lists on your site.

This example is based on Magento 1.4.2.0. so the exact location in the file may be different if you are running a different version.

First make sure you set the most popular option to the first in the sort order on your Custom Options tab. Now you want to fine the file app/code/Mage/Catalog/Block/Product/View/Options/Type/Select.php. Look for the following code (in 1.4.2.0 it starts on line 52):

if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_DROP_DOWN) {

$select->setName('options['.$_option->getid().']')

->addOption('', $this->__('-- Please Select --'));

You’ll want to edit out the line that calls for the addOption():

if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_DROP_DOWN) {

$select->setName('options['.$_option->getid().']') ; //<- don't miss this semi-colon

// ->addOption('', $this->__('-- Please Select --'));

That’s it! Now refresh your browser and your Custom Option Drop-down should default to the first option in the sort order.

October 17, 2010

Magento as a CMS Tool

Magento continues to be one of the best shopping cart solutions in the market space. Although the architecture can be confusing and frightening at times, it is very powerful once you know how to use it. From merchandising your products, to exceptional SEO, all it takes are small adjustments to make your Magento implementation soar.

On many eCommerce sites, the content pages aren’t considered in the overall merchandising strategy. When used correctly, they can provide a wealth of product information, drive SEO results and therefore increase revenues. At first glance, Magento’s CMS pages look like they are just there to manage Terms and Conditions and some brief “About Us” content, so many merchants reach for other tools like WordPress to handle their content.

However, by using the URL rewrites, Static Blocks and a little extra work, Magento can render some rich, categorized content very effectively.

Magento CMS Pages

The first step to making this happen is in the creation of a new content page. Go to CMS->Pages and click on “Add New Page”.

The first thing that happens is you are prompted to input a Page Title and URL Key. Most often users enter a copy of the  page title in the URL Key, changing CAPS to lower case and replacing spaces with hyphens.

But Magento allows for just about any valid URL string you want to put in there. So, you can create content that is ‘category/sub-category/page-title’

Using this method, you can create content in any sub-category you choose.

Magento Static Block Driven Menu

Now that we have categorized content, the next step is to create a menu that links to these content items. This is easily accomplished using static blocks to create the menu lists, then by pulling those lists into the layout as required.

You can use a single block for all of your categories, but you might find it provides more flexibility to create a static block per main category. Either way, the process is essentially the same.

Start by creating a new static block: CMS->Static Block and click on “Add New Block”.

Choose the category, or menu name, you want this static block to control as the Block Title. Use something descriptive for the Identifier. You can also leverage URL rewrites if you want have a multi-lingual shop and effectively switch between languages. (see our article on setting up multi language content in Magento).

Although the WYSIWYG editor in Magento 1.4.x is an excellent addition, I’d recommend using the HTML view for this. Add the nested list of categories, sub-categories, sub-sub-categories, etc as follows (assuming the static block is for a Category):

<ul>
<li><a href="{{store direct_url="category/sub-category1"}}">Sub-Category1</a></li>
<ul>
<li><a href="{{store direct_url="category/sub-category1/sub-sub-category1"}}">Sub-Sub-Category1-1</a></li>
<li><a href="{{store direct_url="category/sub-category1/sub-sub-category2"}}">Sub-Sub-Category2-2</a></li>
</ul>
<li><a href="{{store direct_url="category/sub-category2"}}">Sub-Category2</a></li>
<ul>
<li><a href="{{store direct_url="category/sub-category2/sub-sub-category1"}}">Sub-Sub-Category2-1</a></li>
<li><a href="{{store direct_url="category/sub-category2/sub-sub-category2"}}">Sub-Sub-Category2-2</a></li>
</ul>
</ul>

You can pull this static block into your design by calling the static block in the tempate. You will likely set up the menus in the header.phtml file for example, so you would add a line such as:

<?php echo $this->getLayout()->createBlock('cms/block')->setBlockId('category')->toHtml() ?>

Use your favorite .css or .js technique to expand the menu if you’re putting it in a horizontal menu, or just let it fly as a tree list in the margin. You now have some easy-to-navigate and nicely organized content on your site. Not to mention the search engine optimization lift you’ll get out of having the category descriptor in the URL.

September 2, 2010

Add the Google Analytics Tracking Code

OK, this part is really easy. Once you’ve signed up for your Analytics account, Google will give you a tracking code. It will be a number that looks like “UA-xxxxxx-x”. Copy this tracking code.

Log in to your Magento admin panel. Go to System -> Configuration. In the left hand menu, click on the “Google API” tab under the Sales heading and open the Google Analytics accordion menu. Set Enable to “Yes” and paste the Google tracking code in the Account Number field.

Magento Google Analytics Tracking Code Setup

Click “Save Config” at the top right and you’re done.

Top or Bottom?

If you’ve ever checked you may notice that the Google Analytics tracking code was typically placed at the bottom of the page, just before the </body> tag. If you’re running Magento 1.4.x.x, you may notice that the analytics code is now placed right at the top of the page.

Google’s original code looked like this:

<!-- BEGIN GOOGLE ANALYTICS CODE -->

<script type="text/javascript">
//<![CDATA[
var gaJsHost = (("https:" == document.location.protocol) ? 
"https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js'
 type='text/javascript'%3E%3C/script%3E"));
//]]>
</script>
<script type="text/javascript">
//<![CDATA[
var pageTracker = _gat._getTracker("UA-xxxxxxxx-x");
pageTracker._trackPageview("/");
//]]>
</script>
<!-- END GOOGLE ANALYTICS CODE -->

The old code could slow down the pageload time while Google loaded some fairly hefty javascript libraries to handle the analytics tracking. While the library downloaded, nothing else could happen on the page. Slow page load times make for bad user experience, and with Google’s recent changes in it’s Page Rank algorithms, page load times have an impact on SEO. By placing the code snippet at the bottom of the page, it would ensure that the analytics library was the last thing done on the page.

One concern with this method was that if a user bounced or otherwise left the page before the library downloaded, then any tracking of that event was lost.

Google recently changed the javascript code snipped to utilize ajax to asynchronously handle loading the libraries. This means that the time to load the library is no longer a factor. Google’s new best practices suggest that the code snippet should be added close to the top of the page so that all page events will be captured no matter how fast the user reacts.

Google’s new ajax code snippet looks like:

<!-- BEGIN GOOGLE ANALYTICS CODE -->

<script type="text/javascript">
//<![CDATA[
    (function() {
        var ga = document.createElement('script'); ga.type = 
'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 
'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        (document.getElementsByTagName('head')[0] || 
document.getElementsByTagName('body')[0])
.appendChild(ga);
    })();

    var _gaq = _gaq || [];
    _gaq.push(["_setAccount", "UA-xxxxxxxx-x"]);
    _gaq.push(["_trackPageview", "/"]);
//]]>
</script>
<!-- END GOOGLE ANALYTICS CODE -->

Configuring Analytics Code in Magento

If you are inclined to update Magento 1.3.x.x to the new asynchronous code snippet or want to move the code snippet around the site, there are two files you’ll want to concern yourself with.

Change the old ga.js Code to the Asynchronous

The first is the code snippet itself. It is located in ‘/app/code/core/Mage/GoogleAnalytics/Block/Ga.php’. You will want to find the _toHtml() method and look for:

$this->addText('
<!-- BEGIN GOOGLE ANALYTICS CODE -->
<script type="text/javascript">
//<![CDATA[
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src=\'" + gaJsHost + "google-analytics.com/ga.js\' type=\'text/javascript\'%3E%3C/scri$
//]]>
</script>
<script type="text/javascript">
//<![CDATA[
var pageTracker = _gat._getTracker("' . $this->getAccount() . '");
pageTracker._trackPageview("'.$this->getPageName().'");
//]]>
</script>
<!-- END GOOGLE ANALYTICS CODE -->
');

You can update that code to:

$this->addText('

<!-- BEGIN GOOGLE ANALYTICS CODE -->

<script type="text/javascript">

//<![CDATA[

(function() {

var ga = document.createElement(\'script\'); ga.type = \'text/javascript\'; ga.async = true;

ga.src = (\'https:\' == document.location.protocol ? \'https://ssl\' : \'http://www\') + \'.google-analytics.com/ga.js\';

(document.getElementsByTagName(\'head\')[0] || document.getElementsByTagName(\'body\')[0]).appendChild(ga);

})();

var _gaq = _gaq || [];

_gaq.push(["_setAccount", "' . $this->getAccount() . '"]);

_gaq.push(["_trackPageview", "'.$this->getPageName().'"]);

//]]>

</script>

<!-- END GOOGLE ANALYTICS CODE -->
');

Change the Location of the Code Snippet on the Page

Once that is updated, you can change the position of the code snippet on the page by modifying the ‘/app/design/frontend/base/default/default/googleanalytics.xml’ file (or in the correct sub-directory for your template if applicable).

Look for the following code:

<reference name="before_body_end">

<block type="googleanalytics/ga" name="google_analytics" as="google_analytics" />

</reference>

and change “before_body_end” to “after_body_start” to move the code snippet to the top of the page.

Magento Multi-Language CMS

Author: Geoff Kliza
August 9, 2010

The problem: no language settings in Magento’s CMS pages causes 404 errors

If you are developing or planning to develop a multi-lingual site in Magento, you may have noticed that there are no language settings in the CMS content pages. You can select the store view where the page will display and have different content pages show up in each view of the store, , say one called ‘english-content-item’ enabled only for the English view and called ‘french-content-item’ enabled only for the French view. Using static blocks and different templates for each language you can make this work.

For example, we have some English language menu links in a static block called ‘header_links’ with a list of menu items pointing to the English content pages , and we have some French language menu links in a static block called “header_links_fr’ with a list of menu items pointing to the French content pages. We would modify the template/page/html/header.phtml file in our English view template with the following code:

getLayout()->createBlock('cms/block')->setBlockId('header_links')->toHtml() ?>

and the French view template with the following code:

getLayout()->createBlock('cms/block')->setBlockId('header_links_fr')->toHtml() ?>

That’s pretty straight forward, but here’s the rub. If you are in the English content item and switch to the French language, you’ll get a 404 error. The reason for this is that the URL in the English view is http://yoursite.com/english-content-item, for example. When you switch to the French language, the URL is http://yoursite.com/fr/english-content-item.

Since the ‘english-content-item’ isn’t enabled for the French store view, you get a 404. This is unlike the product pages, which can have separate content defined per store view.

The solution: URL rewrites to the rescue

The solution to Magento’s lack of multi-language CMS is to use the built in Catalog URL Rewrites under Catalog->URL Rewrite Management. By using permanent 301 redirects, not only can you avoid the 404 errors, but you can keep the URLs specific to each language – that’s good SEO!

In the URL rewrite manager, you’ll want to click on Add URL Rewrite and select “Custom” from the drop down list.

magento-url-rewrites

Under “Store” you will want to pick the first store, in this case we’ll start with the English store. “ID Path” and “Request Path” in the case of the CMS pages are going to be the same. In this case we want the French language site to properly redirect when switching to English, so we will use the “french-content-item” for the ID and Request paths.

Next we fill in the target path. In the case of the switch to the English site, we want it to redirect to “english-content-item”. We want it to be a 301 Permanent Redirect. You can add whatever description you need and Save.

Now, do the same for the French site, so use “english-content-item” for the ID and Request paths and “french-content-item” for the target path. Be sure select the French view under “Store”. Save that.

Of course, don’t forget to refresh your cache and make sure you re-index the catalog rewrites if needed. Now when you change languages on the front-end, the CMS page will switch to the appropriate page for you. No more 404′s and you get nice clean URLs, which means happy robots and better SEO results.