webotech homepage Content © WOT Ltd - licensed under Creative Commons License

It started in the summer of 2006. I was on holiday with my girlfriend on the Black Sea coast in Bulgaria, her native country. As a young girl she used to spend her summer holiday's there and she was telling me how drastically it had all changed in recent years.

"Still, it would be nice to buy a small apartment here," she commented.

Less than six months later that passing remark had become a reality. We planned to use the property ourselves but also to rent it out, if we could. Given my software development skills, it was a natural step to set up a website which we could use to advertise the apartment.

That web site is bulgariaseaview.com. If you are after a more in-depth introduction, have a look at my first entry.

March 2008 Archives

Caching Problem

The problem is that IE does not cache images at all if they are referenced in DOM javascript. The effects of this are obvious: pages are slower to load and bandwidth is consumed unnecessarily. When I came across this, I didn't try and change IE settings so it may be that you can fix the problem by playing with Tools > Internet Options. But more to the point I wouldn't want to fix this by tweaking my settings, I'm operating a public website and it should work well with out of the box settings.

Sadly there is no quick fix and no workaround. I have confirmed it to be a problem in IE 6 and IE 7.


Scenario

Here is a scenario to reproduce
  • create multiple image nodes iNode = document.createElement('img')
  • set the same source attribute on the images iNode.src= uriSrc
  • append the images to an existing DOM node domNode.appendChild(iNode)
IE will download every image as a distinct object, although they have the same src attribute. Maybe I'm going slightly mad but to make it worse it seems to take way longer to do this than it ought to. I'm not going to waste time verifying that so I'll give it the benefit of the doubt.


Real Life

What I've just described is all a bit abstract and you're probably thinking 'yeah, but why would you want to do that? Give me real scenario.' Well, here it is. Have a look at this snapshot:

image caching

There is a main image and below it thumbnails, each with mini icons above and below. The mini icons are used to manage photos, the arrows allow you to move them left and right while the A and X icons allow you to edit the photo title and delete the photo. When you click on any mini icon the meta data for this widget changes and communicates this to the back end asynchronously.

There are two situations where this widget needs to create image nodes and they are when it initialises and when meta data changes (since it synchs with the database). Obviously, when this happens the browser has to render each mini icon. In firefox one loads and they all appear at the same time. In IE one loads, then another, then another. You get bored go and grab a coffee, still loading, come back, still loading, take a sip, the next one appears... OK that's exaggerated but you get the picture.


What To Do?

So what should I do about this on bulgariaseaview.com? This is where my earlier decision to work on this project independently begins to pull it's weight. There is no one to answer to here, so I have opted to leave it working slowly in IE and added a note recommending the use of firefox.

It's a bit naughty, after all who am I to tell anyone what browser they should use? But on the other hand imagine how completely I would be ignored if I asked Microsoft to fix their code and maybe by explaining why it works better in a more compliant browser it will convince users to stop using inferior ones.


Quick Fix

The quick fix is this: do not use CSS styles that begin with an underscore (_) if you want them to be rendered in IE 6. By the way, the bug in IE has been fixed in version 7.


IE CSS Underscore Bug

I was sort of aware of IE's CSS underscore hack but I was doing my best to forget it, since it's a piece of information which is as mundane as it is common with IE, "yet another problem with IE"
.
However, this issue must be related to that hideous hack.

This is a screenshot of what I wanted to achieve in IE 6:

ie6ok.gif
Simple enough, so I put together this HTML which should be absolutely fine:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>IE 6 - styles starting with underscore</title>
<style type="text/css">
._mOuter {position:relative;top:-2px;left:20px;}
._mTabOn,._mTabOff {width:100px;min-width:100px; text-align:center;
 font-size:14px;border:1px solid #000000;border-bottom-width:2px;
 border-top-width:2px;}
._mTabOn {background-color:#79B0D4;border-top-color:#79B0D4;}
._mTabOff {background-color:#497c9d;}
._mTabLn {color:#000000;display:block;padding:4px;}
._mTabSp {width:1px;background-color:#000000;}
a._mTabLn:link {text-decoration:none;}
a._mTabLn:visited {text-decoration:none;}
a._mTabLn:active {text-decoration:none;}
a._mTabLn:hover {background-color:#5c90b3;text-decoration:none;}
</style>
</head><body>
<table cellspacing="0" cellpadding="0" border="0" class="_mOuter">
 <tr>
  <td class="_mTabSp"></td>
  <td>
   <div class="_mTabOn"><a href="#" class="_mTabLn">Tab 1</a></div>
  </td>
  <td>
   <div class="_mTabOff"><a href="#" class="_mTabLn">Tab 2</a></div>
  </td>
  <td class="_mTabSp"></td>
 </tr>
</table>
</body></html>


However IE 6 renders this:

ie6notok.gif

Can you spot what's wrong? Most people would and I would argue that the difference is not acceptable for a public website, even though styles are subjective.

To fix it you simply change all the styles defined in the <style> tag that start with an underscore with styles that don't. Here is the working code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>IE 6 - styles starting with underscore</title>
<style type="text/css">
.XmOuter {position:relative;top:-2px;left:20px;}
.XmTabOn,.XmTabOff {width:100px;min-width:100px; text-align:center;
 font-size:14px;border:1px solid #000000;border-bottom-width:2px;
 border-top-width:2px;}
.XmTabOn {background-color:#79B0D4;border-top-color:#79B0D4;}
.XmTabOff {background-color:#497c9d;}
.XmTabLn {color:#000000;display:block;padding:4px;}
.XmTabSp {width:1px;background-color:#000000;}
a.XmTabLn:link {text-decoration:none;}
a.XmTabLn:visited {text-decoration:none;}
a.XmTabLn:active {text-decoration:none;}
a.XmTabLn:hover {background-color:#5c90b3;text-decoration:none;}
</style>
</head>
<body>
<table cellspacing="0" cellpadding="0" border="0" class="XmOuter">
 <tr>
  <td class="XmTabSp"></td>
  <td>
   <div class="XmTabOn"><a href="#" class="XmTabLn">Tab 1</a></div>
  </td>
  <td>
   <div class="XmTabOff"><a href="#" class="XmTabLn">Tab 2</a></div>
  </td>
  <td class="XmTabSp"></td>
 </tr>
</table>
</body>
</html>


An Afterthought

This blog is an afterthought, one that came to me like so: I was happily doing some web 2.0 development, testing in Firefox with those very useful add-ons and it was all looking good. Then I thought I'd better make sure it worked in IE which is always slightly annoying since the computer that has it installed isn't mine.

Having successfully negotiated use of the test machine, "I'll prepare you a hot chocolate if you let me use your lappy", I was ready to do my 5 minutes of validation before calling it a night. There was no way it was going to take longer than that, after all my code was W3C compliant. What could possibly go wrong?

IE bombed out with it's usual ironic error message (you know, the one that is supposed to be helpful but is actually almost completely pointless). It soon became apparent that the only reliable way to fix the problem was to bombard the search engines with questions until they revealed the answer. On this occasion it came in the form of a tech-site written in that unique form of hispano-germano-cyrillo english that you are probably familiar with.

Anyhow, this got me thinking. Wouldn't it be great to write down all the issues I encounter for the duration of the project with details of how I solve them so that others can benefit? What a unique and genius idea! Then I realised that actually it wasn't unique, that hispano-germano-cyrillo-english guy had already thought of it (along with millions of others). Nonetheless, I concluded that it was still a good idea to document the project since there was bound to be at least one person who would find it useful.

That is why this journal is an afterthought and because it is an afterthought, it has come into existence just over 1 year since the project began. So, let me give you a brief run down of what has happened so far.


My Approach

Firstly, I decided that this would be purely my own work. No partners, no clients (like I can just choose to have clients), no other developers, no time schedules, no one to answer to: fantastic. Embarking on a project with that mindset makes a huge difference.

Being my own client I told myself that all I wanted was a quick brochure site that I could start e-marketing within a few days. I toyed with the idea of using java but then I decided if I wanted to do things quickly it would have to be done in perl. Perl development is fast anyway and on top of that I had tried and tested libraries that I had built up over the years which would make it even faster.

I set to work to get a couple of pages with fresh content, good usability, nicely styled (isn't that subjective?), targeted meta data and compliant mark-up. You know, all the elements needed for SEO if you believe in that particular form of occultism. Then I used a bit of web 2.0 magic so that I could display my holiday snaps in a single compact page. Finally, I implemented the google maps API so that users could get a bearing of where the apartment is, and an AJAX control so that they could send me coords of areas of interest. Next I went shopping for a domain name with my favourite registrar, and set up hosting with them as well.  An hour after that, I had deployed my new web app and registered it with the search engines.

A final step was needed: approval from one of the world's greatest consumers and avid on-line reader. I showed the site to my girlfriend and watched her expectantly. She stared at the monitor for a couple of seconds, then her hand moved tentatively towards the mouse. She retracted it before it got there and turned to face me.

"Shall we go dancing tonight?" she blurted out.

Success!


How The Website Has Grown

The website has changed a lot since then. Without going into great detail this is what I did on the technical front:

  • I packaged it up properly so that it could be reliably deployed in various (linux and FreeBSD) environments by referencing an appropriate configuration file.
  • I improved my publication technology so that it was able to publish in static or dynamic mode.
  • I modified my templating technology so that code was naturally divided into cohesive units.
  • I improved my core javascript library so that it had inherent support for AJAX calls.
  • I added a whole load of custom UI tags.

As far as what is considered creative in the traditional way, even though personally I consider software development just as if not more creative, this is what I got up to:

  • I added guides with photos (my holiday pictures). For the guides I did some on-line research, had conversations with people from the area and added my personal experience.
  • I picked up a few other pictures with appropriate creative commons licenses and in doing so I had to improve my image widget so that I could properly attribute the photos.
  • I integrated skyscanner mini.


The Big Decision

By this time the site was attracting enough traffic to get a couple of enquiries about the property. More importantly, it felt like the code was solid. I had adequate unit test coverage, was working on integration tests using selenium IDE and a proper error notification framework made sure I fixed defects pretty quickly.

Also at this time, it came to be that an acquaintance who owns an apartment in Bulgaria as well, demanded that I add a page for his property to my site. My defences had been weakened by the effect of beer and I responded enthusiastically "Yeah, no problem. Get me another drink, will you?"

So I was faced with this question. Should I
create another static HTML page for his property
- or -
enhance the web app so he could add and manage his property and in doing so allowing anyone to do the same with theirs?

The answer to this dilemma is obvious and as far as I can remember these are the steps (more or less in order) that bring us to today:

Requirement 1: set up a straight through processing form that,
    • creates a user account with contact information,
    • allows the user to enter property address, descriptive details, select from a list of communal and private facilities, property meta data, season dates, rental rates, rental and payment terms, photos with meta data and of course map coordinates.
  • I used the above requirement with bit of agile modelling (scribbled on a piece of paper which was ultimately destined for the bin) to design the relational object model.
  • From the object model I derived a database schema.
  • I set up a data system for my web app which hooks into mysql, and coded up repeatable and reversible scripts for
    • creating the schema
    • populating standing data
    • validating (at a basic level) data integrity
  • Then I wrote a load of perl modules which together forms the data access layer of my web app.
With that my first requirement was satisfied and I deployed code to see if anyone would add their property.

Requirement 2: use the data collected from requirement 1 to create a single HTML page per property.
  • I had most of the technology for this, all I needed was to code up a component that extracted the data and then used my publishing and templating technologies to create the HTML.
  • I added support for scheduled publication of property pages (with cron) and the ability to publish a single page or the whole lot.
With the second requirement completed, I replaced my old static property page with my new database generated one and added the page for the second property as well.

Requirement 3: the property owner should be able to manage the content related to their property.
  • I dug out an old library that I wrote for an authenticated web session. I improved it (a hell of a lot) until it was a proper MVC system using the command and front controller patterns (I know, it's not a J2EE project but it's a good pattern) as the core framework.
  • I added support to the MVC framework so that I could plug my publishing and templating technologies into it.
  • Then for each object model I coded create, read, update and delete functionality.
Well, for almost each one. I have the photos model left and if I hadn't started this blog that would be ready as well.

About this Archive

This page is an archive of entries from March 2008 listed from newest to oldest.

April 2008 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Pages