Google and Microformats – The end of the road for Froogle?
About six weeks ago, Google made an interesting announcement. They basically said that they will
Look for markup formats (microformats and RDFa) that you can easily add to your own web pages
This is an interesting announcement for a bunch of reasons (which I’ll get to soon – I promise!).
Now, I like Google, they build some fairly good stuff, and provide some quite good tools for webmasters. There’s a lot more that they could do I’m sure, however the tools they provide are a lot better than some people. So, I figure if they’re willing to put the effort in, then so should I.
Google helpfully have a bunch of support pages showing which microformats they support, and some immediately jumped out at me since I run a bunch of ecommerce sites – hproduct and hreview. Now, most of my sites don’t actually have reviews on them (Yes, I know – they increase conversion …), so I jumped straight to hproduct.
This supposedly lets you mark up your page so that the key attributes can be picked out easily. Perfect – I can mark up all of my products and have Google easily index them, jump straight to the top of the SERPS and retire a millionaire before I’m 35 …
Well, no actually. Google said:
Currently we recognize product data included in reviews.
Which reads to me like they don’t support it outside of reviews. I find this pretty confusing – especially when one of Google’s aims is to rid the index of “spammy review sites”.
So, I’ve marked up one of my sites with hproduct microformats just to see what happens.
At least I think I have…
You see, there’s no real way to check. I’ve yet to find a validation service (One thing that w3c did right all those years ago), and there’s no way to see if Google has found them and noticed them.
I do however have some observations about my implementation that hint at why I think the format doesn’t quite work (At least when taken alongside Google’s understandable strictness about showing their crawler the same as your users).
1. Categories
When people browse to a category they see the category name right at the top of the page, together with a category description, followed by a list of products.
The hproduct spec suggests that I should put the category inside every hproduct group. Which is fine on a technical level – but in terms of usability – why would I want to display it like that for my users?
display:none here we come …
2. Brand
In my particular case my products are categorised by brand, so I have the same problem here. The spec expects me to put the brand within the hproduct cluster – which means my user will see it 20-30 times on a page unneccesarily (They already know the brand – they chose the category). Not to mention the keyword-stuffiness of it all…
3. URL
Google’s example markup contains this little gem:
<span class="url">http://anvil.example.com</span>
So – let me get this straight. You want me to display a link to the product page, where the anchor text is the URL? Is this 1994 again?
Can’t I just do this and have you work it out?
<a class="url" href="/shop/baby-carriers/ready-made-slings/black-and-contemporary-circles.html"> Nice User-friendly link text </a>
So that’s my moans and gripes out of the way.
Now, I said there was something interesting about all this – and there is. You see, this is a major departure for Google. They’ve made it their business to make sense out of the myriad of unstructured data on the web – and they’re good at it – very good. There’s two problems I see with this proposal:
1. Why are Google abandoning their previous plan – has the spam and unstructuredness of the web got too much for them?
2. If everyone structures their data – that really lowers the barrier to entry for other search engines
And here’s a third because I’m feeling generous:
3. It’s easy to game. I said before I don’t have reviews on my site. That’s not to say I can’t now just whip up a quick <div class=”hreview-aggregate”> <span class=”average”>4.4</span></div> [Not that I would, but someone will]
The other reason I think this is interesting is that it pretty much changes the game for Froogle (Aka Google Base, Aka Google Product Search). That’s a service to allow you to provide structured data to have your products listed in Google … hmmmm.
I guess we’ll have to see where that goes – but with microformats for products, and universal blended search results I can’t see a reason to keep good ole Froogle much longer …
Gzip in Joomla – Tips for a faster website
The average internet connection is much more capable of delivering sizeable web content today than it was even 12 months ago – the UK average broadband connection at time of writing is 4.6Mb/s.
The problem
It’s important to remember that:
- Not everyone has broadband
- Most web browsers don’t take advantage of the bandwidth available
GZIP Compression
If you’re developing a site in Joomla for example you often hear people suggesting “turn on compression” within Joomla. This option compresses the page content created by Joomla before sending it back to the browser in real-time.
While this is a great solution for some sites, there are significant issues with this approach for many sites. It’s important to realise that the HTML page is only 1 of the many requests needed to generate a webpage – you also need all of the images, CSS files, and JS.
Take for example a typical template from YOOtheme – a major Joomla theme provider. The actual HTML for March 2009 theme demo is 1 out of 31 requests, and just 7kB out of a total of 144 kB.
It’s worth noting that if the objective is to make your site “faster” then Joomla’s gzip may not be the best option. The downsides to this approach are:
- It only affects the size of the HTML page
- It does that by compressing the content on-fly
- Cacheing aside – this can result in you compressing the file every time it is requested – adding a significant processor load to your server
- The process of compressing the data adds a delay (However small) before your content can be sent
- It does nothing about the other files that make up the webpage
- It doesn’t maximise your bandwidth usage by minimising total number of requests
My Approach
For the sites that I run I use the following approach:
- Identify files that are included widely, but updated infrequently
- Consolidate multiple files into one (ie, create just one .js file for your site, and one .css file)
- Create a compressed version of these files alongside the original
- Use a bit of .htaccess magic to serve the compressed files to everyone who can deal with them.
This is a good solution for files which don’t change frequently (CSS, template images, JS includes etc.) This approach gives you the best of both worlds, compressed files, but low server CPU impact.
The HOWTO
To implement it simply create a compressed copy of the file(s) you want to compress. If you have shell access to your website files you can do:
This should leave you with your original uncompressed file, and a compressed variant with the suffix “gz”.
Now add the following to your .htaccess file:
ReWriteCond %{HTTP:accept-encoding} (gzip.*)
#make sure there’s no trailing .gz on the url
ReWriteCond %{REQUEST_FILENAME} !^.+gz$
#check to see if a .gz version of the file exists.
RewriteCond %{REQUEST_FILENAME}gz -f
#All conditions met so add .gz to URL filename (invisibly)
RewriteRule ^(.+) $1gz [L]
AddType “text/css;charset=UTF-8″ .cssgz
AddEncoding gzip .cssgz
AddType “text/javascript;charset=UTF-8″ .jsgz
AddEncoding gzip .jsgz
Remember if you do change any of the uncompressed versions you’ll have to re-generate the compressed version otherwise clients that support gzip won’t see the changes.
There are some complications when using Joomla with Virtuemart (Since it insists on loading CSS/JS support files itself) – but that’s a topic for another day!
When we implemented this on SnugBaby it reduced the total number of files required from over 35 to 27, and the total download size from over 200k to 144k – would love to hear other’s experiences.
Featured Products With Virtuemart
Featured Products
e-Commerce stores often want to highlight a particular product or products. This can because they have new products to promote, special offers, stock to clear – or just because they believe it will help conversion.
While the popular Virtuemart e-commerce system will let you mark products as “On Special”, it doesn’t offer an out-of-the box way to highlight these special products on the main shop pages.
This article will show you how you can use this “On Special” functionality to implement “featured products” in your product listing pages on your Virtuemart Site – take a look at the example below:

Standard Functionality
The standard Virtuemart functionality allows you to set a product as “On Special” – as the image below shows.

Unfortunately, this information about your products isn’t available to your theme, so you can’t style your products differently, nor can you sort them to the top of your list (As most designs would require).
Getting the information
The first thing we need to do is make sure that the details about whether the flag is set or not is pulled back from the database. The file we’re interested in is shop_browse_queries.php which is in administrator/components/com_virtuemart/html/.
Line 39 specifies a variable called $field_names, so we need to add the database field product_special to this list, e.g.
We then need to make sure that this information is added to the product array available to the layout code.
$products[$i]['product_special'] = $db_browse->f(”product_special”);
Now, in your browse page template, you can simply check the value of $product_special, and change your HTML output accordingly. For example, on SnugBaby, we wrap featured products in a styled div:
<div class=”featuredheading”>
<h3>Featured Product</h3>
</div>
<div class=”featured”>
<?php } ?>
Bubbling up…
So far we’ve managed to highlight featured products, and the next change is a bit take it or leave it. However, when we were doing our implementation of this on SnugBaby we decided that it looked considerably better if the featured products were first in the list. So, the following change makes special products jump up to the top of your list, with the rest of the product according to your standard ordering rules:
If you want to see the final result, check out the SnugBaby Baby Carrier pages.
Virtuemart Category Discounts
Background
Virtuemart is an excellent Open Source e-Commerce system that integrates with the Joomla content management system. I use it on a number of sites – some with more challenging eCommerce requirements than others.
While Virtuemart offers bulk purchase discounts (£10 each, or 3 or £27 style offers) – it unfortunately only implements these on a per-product basis. This is great if you want to order 3 of the exact same pair of baby shoes.
However, a common request is to implement category-based discounts, so for example you would be able to offer a discount where people buy multiple products from a particular category.
We do just this on SnugBaby, where we periodically run category based discounts on our baby shoes, where the requirement is that you get a discount if you choose to buy multiple products from a particular category.
Caveats
There are some caveats to the approach we’re going to describe below:
- It involves patching the Virtuemart source files – this is not a Plugin, Component, or module. You should attempt this only if you’re comfortable editing PHP code
- Further to the above – if you upgrade Virtuemart this will need re-applying, possibly with some tweaks and tickles
- This assumes you’re running Virtuemart 1.1.3 (Although the theory of the approach works with VM 1.0.x as well)
Summary
This approach uses the Virtuemart bulk pricing model to store the bulk prices. This means you need to go through the products that are on special offer and add in the bulk prices. In the example I’m going to use here we are selling baby shoes. The standard price is £16.50 per pair, but if you buy more than 1 pair (Of any design), then you get them for £15.00 per pair.
We market this as “2 for £30″ – however the reality (Probably should be caveat number 4!) is that it becomes £15 per pair for any number of shoes 2 and over (E.g. you could get 3 pairs for £45, 4 pairs for £60 and so on …).
So. First things first. Add the pricing to Virtuemart. If you’ve never done bulk pricing in Virtuemart here’s a quick guide. For each of your products in turn, edit the product, and choose “List Prices”:

Then you’ll need to specify your pricing:

Once this is done then your customers can get the special price, but only if they buy 2 or more of the same product.
The fun part
We can make all the changes we need to in just one file, administrator/components/com_virtuemart/classes/ps_product.php. This file is responsible for calculating product pricing, taking into account quantity discounts. The function in question is get_price().
This function out-of-the-box is given a product ID and is asked to calculate the price. It has a section relating to quantity pricing which roughly follows the following logic:
- Cycle through all cart contents
- If the product_id of the cart item matches the product_id we’re trying to cost then sum up the quantity of this item
- Retrieve the product price based on total volume of a product in the cart
We’re going to amend the second step such that it sums up the quantities of all products in the same category as the product we’re trying to cost.
The full patch (For the impatient) is here.
The patch is split into 2 main sections. The first gets the category that the product we’re costing belongs to (Caveat #5 – I have no idea what happens if your bulk purchase products are in multiple categories!). It also checks if that category is eligible for bulk discounts. You’ll need to change the 28 below to match your category ID.
$product_parent_id = $this->get_field($product_id, “product_parent_id”);
// LW PATCH – Get the category of this product – used later to drive category-based multiple purchases
$sesq = “SELECT category_id FROM #__{vm}_product_category_xref WHERE product_id=’$product_id’”;
$db->setQuery($sesq); $db->query();
$db->next_record();
$sesprodcat = $db->f(”category_id”);
if ($sesprodcat == 28) {
$ses_cat_discount = TRUE;
} else {
$ses_cat_discount = FALSE;
}
// END LW PATCH
The next section changes the calculation so that instead of comparing the product IDs, we comapre category IDs:
if ($ses_cat_discount) {
$sesq = “SELECT category_id FROM #__{vm}_product_category_xref WHERE product_id=’”.$cart[$i]["product_id"].”‘”;
$db->setQuery($sesq); $db->query();
$db->next_record();
$sesprodchildcat = $db->f(”category_id”);
if ($sesprodchildcat == $sesprodcat) {
$quantity += $cart[$i]["quantity"];
}
} else {
if ($cart[$i]["product_id"] == $product_id) {
if ($parent) {
$parent_id = $cart[$i]["parent_id"];
}
}
}
// END LW PATCH
And that’s that. Give it a try, let me know what you think!
Tracking Twitter Traffic
Twitter is a revolution
So, Twitter is a revolution (Apparently). The important thing about Twitter isn’t that you can find out what Stephen Fry had for lunch, or when Oprah is having her makeup done. No, the important thing, for people trying to use Twitter as a a weapon in their digital marketing arsenal, is that Twitter traffic is 10x higher through their API, than through their website.
What is Twitter doing for you?
So what does that mean for Average Joe Ltd. trying to engage with his customers in a brave new digital world?
Simple – links that you post are likely to get read on a mobile phone, or in any one of hundreds of different desktop clients . There’s every chance that if someone clicks through to your site you will have no idea that they came from a Twitter link (Desktop clients particularly tend not to send the all-important HTTP-Referrer information).
So – what’s to be done?
For SnugBaby, as well as twittering as a normal user, we use the excellent Wordpress “Twitter Tools” plugin to tweet when we update our blog. So – how to track how much traffic we were generating from these links? Fortunately there’s a fairly straightforward solution to the problem. We analyse our traffic using Google Analytics, which provides the ability to “tag” links with extra information. This is commonly used to track inbound links relating to specific marketing, or email campaigns – but we use it to track Twitter as a campaign all of it’s own. This is nothing new.
However – our blog-related links are tweeted automatically – so we needed to make some changes to the Twitter Tools plugin to add on the tracking codes.
The Solution
For those that are interested I’ll step through the changes below – but if you want a quick twitter tracking fix, then you can download a patch (Against version 1.6 of twitter tools), or a complete copy of the twitter-tools.php file.
Step 1. Flexibility is king
We want to make our solution a little bit flexible, so we set up the tagging as a setting which can be controlled through the Wordpress admin pages. We called it extra_query_args:
$this->options = array(
'twitter_username'
, 'twitter_password'
, 'create_blog_posts'
, 'create_digest'
, 'create_digest_weekly'
, 'digest_daily_time'
, 'digest_weekly_time'
, 'digest_weekly_day'
, 'digest_title'
, 'digest_title_weekly'
, 'blog_post_author'
, 'blog_post_category'
, 'blog_post_tags'
, 'notify_twitter'
, 'sidebar_tweet_count'
, 'tweet_from_sidebar'
, 'give_tt_credit'
, 'exclude_reply_tweets'
, 'last_tweet_download'
, 'doing_tweet_download'
, 'doing_digest_post'
, 'install_date'
, 'js_lib'
, 'digest_tweet_order'
, 'notify_twitter_default'
, 'extra_query_args'
);
We also provide a sensible default for people installing the first time:
$this->extra_query_args = '?utm_source=twitter&
utm_medium=twitter&utm_campaign=twitter';
The final step is to build the form that will let users change the value of the new parameter:
<div class="option">
<label for="aktt_extra_query_args">'.__('Text to tag on
the end of URLs in generated tweets', 'twitter-tools').
'</label>
<input type="text" size="30" name="aktt_extra_query_args"
id="aktt_extra_query_args" value="'.$aktt->extra_query_args
.'" />
<span>'.__('Include the leading ? before query args',
'twitter-tools').'</span>
</div>
Step 2. The magic bit
The final change simply adds the contents of your parameter onto the end of the post URL before passing it off to the URL shortener.
$url = $url . $this->extra_query_args;
Job Done
And that’s that. Twitter tools will now post URLs that include tracking information – all you have to do know is keep an eye out for them in Google Analytics!
Life begins at 30…
Or in this case, the blog begins at 31.
This is really not much more than a placeholder for various software bits and bobs that I’ve put together as part of running my wife’s baby carrier business SnugBaby.
SnugBaby runs on a wide combination of software, including Joomla, and Wordpress, together with a bunch of customisations – all the way through from code which takes advantage of standard extension points built in to both Joomla and Wordpress (I have home-brewed Joomla modules, and Wordpress plugins), all the way through to down and dirty core hacks.
So, you can expect hints and tips on using open source software to support a new (non-technology) business. You can also expect the odd patch, frequent hacks, and maybe even the occassional fully featured plugin, module, or extension.
| M | T | W | T | F | S | S |
|---|---|---|---|---|---|---|
| « Jun | ||||||
| 1 | 2 | 3 | 4 | 5 | ||
| 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 |
| 27 | 28 | 29 | 30 | 31 | ||




