2009.06.10

I'll see your Groovy and raise you a Python (and Ruby, PHP for good measure)

Inspired by what is clearly an interesting trend in want ads mentioning Groovy, I ran the same query against Python, Ruby & PHP. Groovy is yet to be where Ruby was five years ago but has at least managed to break out from the x axis. Python and PHP keep on gaining traction.

2009.05.14

Handling Errors Using jQuery.load

Following on from my last post on integrating HTML content from another  system into an existing site, I realized I wasn't handling failures very gracefully. To recap, I was using the load method of jQuery:

$(document).ready(function() {
$('#races a').click(function () {
$('#results').load('Racing/' + $(this).attr('href') + ' #wrap');
return false;
});
});

I was surprised to find there wasn't much information about how to go about capturing an error if it occurs. It turns out you can get it by passing a callback function to the load function. This function accepts 3 parameters: responseText, textStatus and an XMLHttpRequest. I'm not exactly sure why they decided to give you responseText and textStatus when you have an XMLHttpRequest (an object that already encapsulates both of these values so passing them as parameters is a violation of the DRY principle).

Anyways, here is how to do it using the callback function:

$(document).ready(function() {
$('#races a').click(function () {
$('#results').load('Racing/' + $(this).attr('href') + ' #wrap', "", function(responseText, textStatus, XMLHttpRequest) {
switch (XMLHttpRequest.status) {
case 200: break;
case 404:
$('#results').html('<p>Looks like the results have not been uploaded to the server yet. Please check back later.</p>');
break;
default:
$('#results').html('<p>' + XMLHttpRequest.status + ': ' + XMLHttpRequest.statusText + '. Please contact the club and let them know.</p>');
break;
}
});
return false;
});
});

Now you can get specific about how you report your error based on the response code. For example, if you see something in the 400 range you know there has been a client problem (e.g. 404 not found), versus a 500 series status for server side problems. In this case, I explicitly handle 404 errors and have a generic catch-all for anything else.

2009.05.13

Integrating SailWave Race Results with jQuery

Swlogo66 Recently I was tasked with incorporating results from the popular sailing race result scoring software SailWave into our club's site - The National Yacht Club. Here is the approach I took.

While SailWave supports exporting HTML that you can customize, there were a couple of problems:

  1. I didn't have access to the club's PC (SailWave is desktop software)
  2. In the event the club upgrades their version I wanted to make sure my changes wouldn't get broken.

So, instead I decided that the uploads should use the out-of-the-box styling, and I would overwrite with my own CSS rules. All I needed to do was access the resulting .htm file that had been uploaded.

Reading the File

I asked the race committee to upload their files using a convention based on the date: YYYYMMDD.htm. I pull the data in asynchronously using the jQuery load function on document load:


$(document).ready(function() {
$('#results').load('results/20090513.HTM #wrap');
});

The magic here is the '#wrap' part. This tells jQuery to filter the document that is being loaded based on an id. In this case, we only want the results table, which is conveniently exported inside a <div id="wrap"> tag by SailWave.

Styling the CSS

The standard HTML upload generates a semantically marked up HTML document. This makes it easy to style the results table to match your site colors. Here are the CSS rules for our site:

.hardleft {text-align: left; float: left; margin: 15px 0 0 25px;}
.hardright {text-align: right; float: right; margin: 15px 25px 0 0;}
table, caption {text-align: left; margin: auto; font-size: 1em; border-collapse: collapse; border: 1px #fff solid;}
table th {background-color: #d7d7c3;}
td, th, caption {padding: 4px; border: 2px #fff solid; vertical-align: top;}
caption {padding-left: 5px; text-align: center; border: 0; font-weight: bold;}
h1 {font-size: 1.5em; color: #9DA075;}
h2 {font-size: 1.4em;}
h3 {font-size: 1.2em;}
p {text-align: center;}
th, {background-color: #aaf;}
.contents {text-align: left; margin-left: 20%;}
.race, .rank {text-align: center;}
.even {background-color: #e1e8f0;}
.odd {background-color: #edece3;}

Pretty straightforward really.

You can see an example here.

If you would like help incorporating this into your club's site please feel free to contact me and I'd be glad to help out.

2009.02.19

Editing a Wikipedia Article is Exasperating

I am trying to edit a Wikipedia page. the one about "Business Process Automation" to be exact.

Specifically, there is a section in there that talks about tools. Now, Karora Technologies, a company I co-founded and still am involved with in an advisory capacity, has been developing one of these tools since 1998 and it has been quite successful with it. I'm thinking hmmm... Shouldn't I add a link to Karora's tool on this page? After all, there are already several other competing vendors and their products listed.

My first attempt was this:

Karora Technologies provides a product [http://www.karora.com/products/appconnector] that supports desktop mashups. Originally developed in 1998, it is now in use in many manufacturing and health care organizations helping automate organizational processes that typically span "silos" such as accounts payable or forms processing.


Mr Ollie subsequently rejected this with the reason "promotion of specific product".

Ok, fair enough. So I removed the link, and tried again:

[[Karora Technologies]] provides a product known as AppConnector that supports desktop mashups. Originally developed in 1998, it is now in use in many manufacturing and health care organizations helping automate organizational processes that typically span "silos" such as accounts payable or forms processing.


I even created a page for Karora. This was rejected ("promotional spam") and the page deleted. I would of thought that not linking to the product specifically, and providing additional information about where BPA is useful would have been Ok.

The thing that bugs me about this is that the ones that are already there are about specific products and are no more or less promtional than what I was attempting to put up there. Wikpedia Quality Control Fail. Me Fail.

2009.02.18

Shopify Liquid Tip: Product Vendor Collection Handle

Here's a rather arcane one for you. It is very technical, very liquid (i.e. pertains to Shopify's templating language), and probably would be of interest to at least 2 people on the planet that I can think of, so please feel free to skip over.

Anyways...

In collection.liquid, you can find out what collection you are operating on using {{ collection.handle }}. For most collections it works quite well:

CollectionURL
{{ collection.handle }}
All products in "shoes"/collections/shoesshoes
All products in "shoes", filtered by those tagged "High Heels"/collections/shoes/high-heelsshoes
All products of type "expensive"/collections/expensiveexpensive
All products made by Manolo Blahnik/collections/vendors?q=blahniknull


Can you spot the odd one out? That's right - collection.handle is null on the collection page when querying by vendors.

So, if you need to find out if you are on a vendor collection page, you will need to do something like this:

{% if collection.handle == null %}
Browsing products lovingly crafted
by {{ collection.products[0].vendor }}.
{% endif %}

Shopify Concierge

2009.02.03

What he said

Ron Jeffries:

Want to succeed at software? Then it can’t be business as usual. Study the material, do the practices, get help. Or get out of the way.

The tricky part is finding people who believe in the same values.

(via Patrick Logan)

2009.02.02

Multi-Level Shopify Sub-Menus

Recently I worked on a Shopify site (moderno theme) that required a multi-level navigation system for their extensive product inventory. Here are the steps:

1. Find a good menu-ing system

Dynamic Drive, Dev Snippets and CSS Play are good places to look. This is the fun part, but be careful as you can spend many hours wading through the plethora of options.

Shopify-assets For this project, I went with cssMenus (a variant of the infamous and totally awesome Suckerfish menus). My main criteria for choosing the menu implementation were:

  • CSS based
  • SEO friendly
  • Supports for nested menus at least 4 levels deep
  • Easy to understand and implement

2. Integrate cssMenus into Shopify

This is straight-forward. First, upload the CSS and Javascript files to your theme (Admin > Assets > Theme Assets).

Now, add the following liquid code in the head section of theme.liquid:

{{ 'nav-vr.css' | asset_url | stylesheet_tag }}
{{ 'nav-vr.js' | asset_url | script_tag }}

Finally, set up your menu structure using standard <ul> and <li> HTML tags in collection.liquid. Here is an excerpt :

<ul id="navmenu-v">
<li><a href="/collections/all">ALL PRODUCTS</a></li>
<li><a href="/collections/dexterity">DEXTERITY</a>
<ul>
<li><a href="/collections/dexterity-usa">USA</a>
<ul>
<li><a href="/collections/dexterity-usa-colmor">Colmor</a></li>
<li><a href="/collections/dexterity-usa-gilbert">Gilbert</a></li>
</ul>
</li>
</ul>
</li>
</ul>

I placed this code inside the "collection-desc" <div>.

3. Creating Collections for each menu item

You will notice in the excerpt above that each menu item is associated with a collection.

Submenu2 I created collections for parent items as well, so that users can click on "USA" to see products across the child menus "Colmor" and "Gilbert". The naming convention I used means the names can be used as a breadcrumb.

The final step is to associate each product with the relevant collections. You do this on the product page - just check off the appropriate collections (listed on the right hand side of the page).

Summing up

Creating this navigation system for Shopify took about 2 hours. A lot of that time was spent coding up the list of menu items as there were a lot! For more information or help with this technique, please feel free to contact at Shopify Concierge.

Shopify Concierge

2008.12.16

The Christmas Kangaroo

It's that time of the year again and I'm looking forward to heading towards the warmer side of the planet for 3 weeks - catching up with family and friends. The highlight of the trip this year will be a week long cruise in The Whitsundays (a group of islands at the bottom end of the Great Barrier Reef) aboard Pacific Sunrise.

I'm hoping (hopping?) to avoid the Christmas Kangaroo:

Merry Christmas Everyone!

2008.12.04

ThingDB - you haven't slayed SQL just yet

I came across ThingDB the other day (via Reg, who pretends he isn't blogging, but one wonders how long until the siren call beckons?!). It is part of the Pharos project from the reddit guys. ThingDB is basically an abstraction layer that sits on an entity table that has a one-to-many relationship to a properties table, with versioning thrown in for good measure. Anyone who has built a system requiring extensible user defined attributes or configurable metadata (e.g. a document management system) would instantly recognize this. It partitions data (i.e. shards) to make it scale beyond a single machine, and they talk of using bloom filters, so it seems pretty cool.

However... what got me to post about this was not so much the technology, but the statements made about SQL. Consider:

But SQL has some problems. For one thing, it's inflexible and poorly-integrated into most programming languages.


Reality check guys: SQL is one of the most successful technical things we have done in our field. I credit that to its flexibility. In fact, I can't think of a situation in my 25 year programming career where I have found SQL to be so inflexible that I need to use something else. Maybe it is because I've predominantly done mainstream CRUD-style enterprise apps, but guess what - that is what the majority of the work is.

I don't get the claim that ThingDB is superior from a language integration point of view. Take a look at the top 9 programming languages (constituting 80% of the space) as at November '08 (according to TIOBE):

  1. Java (20.30%)
  2. C  (15.28%)
  3. C++  (10.36%)
  4. (Visual) Basic (9.27%)
  5. PHP (8.94%)
  6. Python (5.14%)
  7. C# (4.03%)
  8. Delphi (4.01%)
  9. Perl (3.88%)

Everyone one of those languages has excellent support and integration with SQL. In some cases, you can even embed SQL directly into the code (the merits of doing this nowadays are a bit dodgy, but I will say we built a very clean, fast, client/server app in the eighties using this approach). I would go so far as to say that LAMP would not have happened were it not for the integration between the M and P in LAMP.

Side note: check out this cool feature in Netbeans.next - SQL code completion in PHP.

Anyways, a final note on ThingDB. The discussion about how it can be scaled up is very interesting, and I don't want to detract from that as it is very leading edge and well... cool. But, and there is always a 'but', for the average corporate application this is going to be massive overkill. Your typical RDBMS is a very capable technology and isn't going to run out of steam anytime soon. For example, we have a deployment of our product that is tracking issues for 50,000 users worldwide. They are happily running it using Sybase on a 4-way box, and with millions of rows performance is still great.

Bottom line: In spite of claims to the contrary, SQL is still a very useful technology that is entirely appropriate for a large class of applications, and will be be for the foresable future.

2008.11.13

Rogers Is Messing Up My Browser Experience

My internet service is provided by Rogers. They have this annoying "feature" where if you type in a url in the address bar and the site doesn't exist they throw up a Yahoo! search page, passing in whatever you typed.

Why do I find it annoying? Because A) if I wanted to search I would have searched, and B) if I made a simple typo I can't just change it the address bar because now it is the address of their search page. I vaguely remember there was some noise about this a couple of years ago and it went away. Now it is unfortunately back.

Funny thing is they let you turn off the search page, but it still hijacks the address bar anyway - it replaces what I typed with "http://www20.search.rogers.com/not_found" and shows a mimic of the page my browser would have shown you anyway. What possible value does this add? Yeach! Actually it is worse than that because anyone who customized their browser's behaviour on a 404 will find it doesn't work anymore.