An exciting time to be a web craftsmen…

One of my favourite blogs has mentioned one of my favourite words, and I like what Craig says. It is an exciting time to be working on software, especially web software, as there is a real feeling of the sky being the limit. Google, Flickr, Youtube, they all did it – why can’t I?

The fact is that while there is a lot of buzz and hype surrounding the current internet boom (2.0) there’s a distinct lack of what I would call craftsmen. Those people, like Craig said, who strive not just to finish a project but to do it right. And when it comes to doing it right, it’s all down to the end users.

They are the ones who will sit there looking at this stuff we make day in, day out. They’ll be clicking things a lot more than we ever will, they’ll find those niggly little things that we just don’t have a clue about. As I walk round my company I’m always slightly wary when I see one of my systems on somebodys screen – after all, if it doesn’t work they’re the ones who will complain because I haven’t ‘done my job properly’. Cans of worms, anyone?

So it’s important, no – vital, that we take what we do seriously. I’m not saying come to work in a suit and tie every day, or never have a laugh, but to always bear in mind the end user. And put the effort in to do things properly. I recently worked on a site that was nominally built with web standards (no tables, divs, paragraphs etc) but was completely unusable, broke in every browser by that one and was basically a mess. It had all the right components, but no craftsmanship had gone into it.

Last year my wife and I went to the beautiful island of Guernsey and while there went to a jewellery workshop. Let me tell you, those guys are true craftsmen. The hours they spend cutting, etching, shaping and polishing would put even the most nit-picky of web designers to shame. And all for something that’s just a few millimetres across. But how beautiful does that stuff look? They aren’t just making a piece of jewellery, they are making something that someone will one day consider an essential part of themselves. Something with potentially a massive amount of sentimental value, something to help make people’s lives more special.

It’s a challenging thought, but why can’t we make software with that attitude? As Kathy says, we don’t want to be just liked – we want to be loved. And we should want our software to be loved as well, because it makes people’s lives better (easier, quicker etc). After all, making people’s lives better is a worthy aim.

Content management – a fresh approach…

Further to my article on the power of the niche I read this interesting article by highly acclaimed uber-geek Eric Sink. In it he describes how, when writing a computer application at least, going for a small portion of a large market may not be the best idea.

He’s absolutely right. I have a tendency to “open my mind” far too often when forming ideas for an app.I start thinking about related features, additional uses for the app, plugins, new markets, additional functions. And before I know it, instead of the streamlined sportscar I originally started out with, I have a double-decker bus.

And that’s a problem. A huge problem. Because I can’t please all the people all of the time, not even close, so why should I bother. If I try to do too many things I’ll end up failing at all of them, but if I just do a handful of things really, really well then I have a good chance of getting it right.

So I’ve been thinking of the smallest market I could possibly go for, the narrowest niche I could develop a product for. And, of course, that market is me. just me. No-one else. I just need to do something that does what I need it to do, and ignore those voices in my head that shout about making “a viable business opportunity”. Instead I should just do something that fits my needs perfectly.

So, what am I going to make? Well, there’s just one thing that I really need at the moment, and that’s a decent piece of software for managing my websites more easily. While I could use one of the many content management systems already out there, the fact is I want to do things in a particular way.

For one thing I don’t want there to the any difference between a page and a folder. As I am fanatical about clean URLs this makes sense. Consider these examples:

mysite.com/my-page
mysite.com/my-page/more-info

Now some people would say that “my-page” is a folder, when that folder is accessed in a web browser an index page is shown. However I don’t agree, because it can be accessed directly and it has it’s own content. Therefore it’s just a page which happens to have a child (“more-info”). And “more-info” is just a page, whether it has any children or not.

Strange though it may seem for people used to using more traditional CMSs, it’s actually pretty easy to visualise if you think of it in database terms. Here’s my table with some sample data:

ItemID ParentID ItemName Content Permalink
1 1 Homepage Welcome to the homepage homepage
2 1 My Page Welcome to my page my-page
3 2 More Infomation Some more infomation more-info

So you can see I have three items in my database. The first item is the website homepage, cunningly called “homepage”. The next item is a child of the homepage – notice it has a ParentID of 1? That means the ID of the parent of that item is the item with the ID 1. If that sentence makes sense to you you’re doing very well. The next item has a ParentID of 2, because it is a child of the “My Page” item.

One thing to note is the Permalink colum. That stores a URL-safe version of the page name, and is the bit that will appear in the address bar of the browser when each page is loaded, for example “mysite.com/my-page/more-info”.

Using this system I can have as many pages as I want, all with a logical relationship to each other. I can easily set the content of each page, change the title (and the permalink if I want) but know that my menu system will always know where each page is and how to get to it. Fantastic.

However I want more. Much more. For example, I want to be able to create an image gallery anywhere I want in my website, with different sizes available for each image. I want to be able to create a wiki if I want, or a forum, or a blog. And that means I need to set the type of each item, like this:

ItemID ParentID ItemType ItemName Content Permalink
1 1 Page Homepage Welcome to the homepage homepage
2 1 Page My Page Welcome to my page my-page
3 2 Gallery My Pictures Here are some holiday snaps my-pictures
4 1 Blog Bloggity blog Welcome to my blog blog

So now I have the following site:

mysite.com/ (site homepage)
mysite.com/my-page (a normal page)
mysite.com/my-page/my-pictures (an image gallery)
mysite.com/blog (a blog)

You might be thinking why would I want to do that? Well, I just do. Remember this is for me, no-one else. It’s my app and I’ll code what I like :0)

So now my system knows what type each item is I can do all manner of things. In my administration system I can load the correct forms and functions – so where the item is a gallery it would allow me to upload images and create photosets, for instance, or for a blog it would allow me to create a new entry that would automatically be added to a date-specific archive. And on the public pages I could do what I want too, like load some JavaScript just for gallery pages that allows me to use a lightbox.

Obviously there’s a lot more floating round my head than just that. However if I get something that does exactly what I want it to, and works exactly how I want it to, then that would be great. The only problem is, if I’m developing this just for myself, who’s going to tell me when to stop?

Wearing different hats…

It’s one of the main things I enjoy about my job that I have to wear different hats. Not real hats, of course, I’m talking about metaphorical hats signifying different roles. Some of these hats I enjoy wearing more than others, and some I absolutely resent even going near as they are way outside my responsibility. It seems like web guys are lumped alongside general IT people when they clearly aren’t the same breed. But I digress.

Here’s a quick rundown of the hats I wear, how much time I wear them (in percent), and how well-fitting they are to me.

Developer Hat: Worn 40% of the time

My main hat is the Developer Hat. It’s plain black with a very small purple PHP logo on it. It fits pretty well, although sometimes I see people wearing the same hat and it’s quite obvious that they were born wearing the Developer Hat and I only got my one relatively late in life.

What most people can’t see is the intricate and complex mesh of technologies that make up the inside of the hat, a mesh that I concieved and constructed with my own two fingers (hmm, note to self, learn to type properly). A mesh of objects, functions, expressions and tricks that I’ve picked up over the last decade and now carry around with me. This is my Developer Hat, and I wear it with pride. It’s a pity that other people see it as a…

Technical Support Person Hat: Worn 25% of the time

That’s right, many people seem to see me as a general helpdesk dogsbody. Just because I work on the internet they ask me things like “Are my credit card details safe on this site?”, or “My screen has frozen, what do I do?” (reboot, muppet) or even “My mouse is going a bit funny, can you help?”.

The Technical Support Person hat is very distinctive. It is bright yellow with a big badge on it that says “Happy to help!”. I hate wearing this hat, it just Isn’t Me.

Let me say this once, in the hope I don’t have to say it again: there are people who are paid to answer these questions, they are called Technical Support. Ask them, not me. I am too busy to figure out how you can print every other page of your document.

Secretarial Dogsbody Hat: worn 10% of the time

Quite a lot of the time I find myself doing menial tasks that could be easily done by a much more junior person than me. The Secretarial Dogsbody Hat, therefore, covers a whole range of scenarios; from checking spelling in web pages to resizing images. While this brain-light work is sometimes a welcome change from the heavy development brain-ache stuff, it’s more often than not an annoying distraction from more important work.

Still, at the moment, there isn’t anyone else available to wear this hat, so I’m stuck with it.

Designer Hat: Worn 10% of the time

The Designer Hat is also quite distinctive. It has a set of tools down the left hand side containing things like ‘Gradiated Fill’ and ‘Bezier Curve’ and sucks up memory like nothing else on earth. It’s not a natural fit for me, but very occasionally I get it a a good angle and someone says “That looks nice”. I’d like to fit inside the Designer Hat better, but most of the time it’s a case of just jamming it on and hoping it doesn’t fall off.

Marketer Hat: worn 5% of the time

The Marketer Hat is slightly wierd. On the ouside it is all smiles and flashy graphics and low, low prices. But on the inside it is hollow, built with bits of string and devoid of soul. The kind of Marketing Hat I’d like to wear is one that is big enough for a whole community to get inside, but those hats are few and far between in big business.

Business Development Person Hat: worn 5% of the time

I like the Business Development Person Hat. It’s a no-nonsense sort of hat, plain and strong, with several useful compartments. The problem is I don’t get to wear it very often because people think that I am only capable of wearing the Technical Support Person Hat. And the few times I do get to wear the Business Development Person Hat most people tend to think I dont know what I’m on about because I don’t have an MBA or wear expensive suits.

Community Facilitator Hat: worn 5% if the time

The Community Facilitator Hat is a fun hat to wear, even if it does mean hard work. It comes with a mop for cleaning up messes, and a megaphone for making announcements. Wearing this hat means you have some degree of power, but it definitely doesn’t mean you have some degree of respect. The Community Facilitator Hat is the rarest of hats to find a perfect fit of, but once you find the right hat it’s there for life.

What most business people don’t realise is that the Community Facilitator Hat, Business Development Person Hat and Marketer Hat could (and should be one and the same.

Modern JavaScript – a primer…

Soon I’m meeting with a couple of fellow web geeks and they’ve asked me to provide a quick talk about modern JavaScript including that whole pesky AJAX thing. In return they’ll be giving me some help with the .net thing. Anyway, I thought I’d better write something down so I don’t look like a complete muppet, so here’s what I intend to say.

The old way – onclick and javascript: hell

Let’s face it, separation is a good thing. And just as all good web people use HTML to describe the page content, and a separate CSS file(s) to style that content, so a separate JavaScript file(s) to describe the behaviour of the page should be used. That means no more ‘onclick=’ attributes or ‘a href=”javascript:”‘ psuedo-links. Those things were OK for a time, but people who know better now use different methods to apply certain JavaScript behaviours to elements using element type names, IDs and classes.

It’s better for lots of reasons: reusability of code, readibility of HTML, compatibility with a wider array of devices, accessibility to a wider range of users, separateion of content and behaviour, and quite a few more. It’s simply the Right Thing To Do.

The new way – listen up!

So how do we make that funky JavaScript function happen when someone clicks the link? An example would be useful. Let’s say we want to change an image when someone clicks a link, like in a simple image gallery. Here’s our link and image HTML:

View image 2

Image 1

And here it is, in all it’s glory. What we want to do is listen for when a user clicks the link, then hijack the request and load the right image in using JavaScript. Eh? Listen? What are you going on about?

Listeners are the unobtrusive way to assign behaviours to events performed on elements. An element is any HTML element – a link, a button, an image, the page body itself etc. An event is something that can happen to an element – a link can be clicked, an button pressed, a the page body loaded. And a behaviour is something that happens when that event is fired – a popup window appearing, changing the text size, checking the validity of a forms fields.

It’s pretty simple, really. Rather than shove a link to the JavaScript function in the actual link or button (as described above) we simply set a load of listeners that sit there patiently until something happens. They then jump up and say “Hey! Someone clicked that link! Now I have to do something!”. That’s separation of behaviour and content in action.

So how do we actually set listeners? Here’s a simple one that listens for our link with the id ‘image2link’ being clicked:

// the addEvent and removeEvent functions are from http://ejohn.org/projects/flexible-javascript-events/

// This function adds a listener for a particular event
// (from http://ejohn.org/projects/flexible-javascript-events/)
function addEvent( obj, type, fn ) {
if ( obj.attachEvent ) {
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
obj.attachEvent( 'on'+type, obj[type+fn] );
} else
obj.addEventListener( type, fn, false );
}
function removeEvent( obj, type, fn ) {
if ( obj.detachEvent ) {
obj.detachEvent( 'on'+type, obj[type+fn] );
obj[type+fn] = null;
} else
obj.removeEventListener( type, fn, false );
}

// And here's where it happens

// this line adds a listener to listen for then the page loads and then runs the getImageLink function
addEvent(window,'load',getImageLink,false);

// Here's where we get the image link from it's ID
function getImageLink(){
// This line gets a reference to the element with the ID 'image2link'
var thisLink = document.getElementById('image2link');
// this line adds the listener to listen for then that element is clicked, then runs the 'showImage' function
addEvent(thisLink,'click',showImage,false);
thisLink.onclick = cancelClick;
}

// this function shows the image
function showImage() {
// get a reference to the element with the ID 'image'
var imagePlaceholder = document.getElementById('image');
// set the new src attribute
imagePlaceholder.setAttribute('src','image_2.jpg');
// set the new alt attribute
imagePlaceholder.setAttribute('alt','Image 2');
// stop anything else from happening
cancelClick();
}

// This function stops the default click from happening
function cancelClick() {
return false;
}

Make sense? That’s pretty much it, to be honest. I’ve added this JavaScript into our simple page and you can see the results here. Clicky linky! I love it long time. The problem is it’s long and complicated and way beyond the means of any but the most geeky of coders. This is where frameworks come in, which I’ll talk about in a little while.

Graceful degradation and progressive enhancement

Using this method you can set up as many functions as you like, and set listeners to any event on any element to start them. And perhaps the best bit about this is that because you’re not messing about with the actual href of the link at all, it can point to the actual image you want to load so that if a user doesn’t support JavaScript (or has it disabled) they can still follow the link as normal and see the image.

That is known as graceful degradation, or progressive enhancement. What it means in this example is that if a user can’t or won’t support JavaScript they at least get something. It’s another way for websites to be accessible and, again, is simply the Right Thing To Do.

Manipulating the DOM

In that example we changed the src and alt attributes of an image element. That’s an example of manipulating the DOM. The DOM, or Document Object Model, is the current rendering of a web page – the treeview of nested element, if you like. For example, the html element has a body element inside it. The body element has li and p elements inside it. We can walk through the DOM just like we’re walking through an XML document. In fact, a properly-written XHTML is an XML document.

So what else can we do with JavaScript to change our web page? Here’s a partial list of functions that are part of the core JavaScript language. Try to guess what they do:

  • getElementById
  • getElementsByName
  • getElementsByTagName
  • createAttribute
  • setAttribute
  • removeAttribute
  • createTextNode
  • appendChild
  • removeChild
  • cloneNode

A more complete list can be seen at JavaScriptKit.com.

Now, this is where it gets a bit complicated, and where opinion on modern JavaScript best practices hits a fork in the road. I’ll give you an example. Let’s say that we have a list of options, like this:

  • Item 1
  • Item 2
  • Item 3

And here it is, looking lovely. We want to add another item to the bottom of the list, cleverly called ‘Item 4’. One way to do this could be:

// create the new list item
var newitem = document.createElement('li');

// set the text for this new list item
var newtext = document.createTextNode("Item 4")

// add the new text to the new list item
newitem.appendChild(newtext);

// get a reference to the list and add the new item with it's text to the list
// this line demonstrates the ability to string together object methods and properties
// this method can save a lot of typing and bandwidth
document.getElementById('list').appendChild(newitem);

That should all make sense, and while it is perfect from a code point of view (well, notwithstanding my fumbling fingers ;0) If you want to see this in action you can’t do better thank to click here. This page adds a new item to the list 3 seconds after the page is loaded. I won’t pretend it’s quick and easy. Can you imagine adding a complex block of HTML to a page this way? Nasty, I think you’ll agree. But that’s the way the DOM cookie has crumbled, and we’re stuck with it.

Or are we? There is another non-standard method which is helpfully supported by all the major browsers and is used extensively by thousands of modern sites. It’s called ‘innerHTML’ and I bet you can guess what it does from the name. That’s right, it can get and set the entire HTML code inside a referenced element. Here’s an example:

// here's the HTML

This is my text!

// get a reference to our paragraph and get the innerHTML property
var text = document.getElementById('innertest').innerHTML;

// the variable 'text' now contains 'This is my text!'

// set some new text
document.getElementById('innertest').innerHTML = "No! It's my text!";

// the HTML will now be

No! It's my text!

Now, is that easier or what? You can see it working here. The innerHTML property can contain any HTML you want – links, images, tables, forms, the lot. So it’s a really easy way to get and set large amounts of HTML. And there’s even some evidence to say it’s faster than a totally DOM-only method for writing HTML.

Of course, not everyone agrees that this is a good method, but it works, is well supported, and is likely to be included in the official DOM specification eventually.

AJAX

So now we can change huge chunks of a web page using JavaScript easily, surely there’s some really cool way we could use this? Why, yes there is, and it’s called AJAX. That stands for Asynchronous JavaScript and XML and was coined by the clever chaps at Adaptive Path to describe a collection of technologies working together to do a simple thing: send messages to and from the web server without refreshing the page.

It might not sound much, but that technology (which was originally developed by Microsoft several years ago) is the breakthrough that web developers needed to get on an (almost) level footing with desktop application developers. For too many years we’ve provided cool online apps that look great, do great stuff, but every time we wanted to ‘do’ something – change a password, request a different ordering for a data table, send a form – we’ve had to sit back and wait for the whole damn page to be sent, and then another whole damn page to be returned. Only to tell us that ‘Sorry, your password is not valid. It must contain letters, numbers and a Klingon war-cry’.

No more! We’re even. We’ve got it all: the looks, the worldwide reach, the sexiness, the coolness and now the responsiveness. AJAX has made this possible, and it’s all down to a little set of functions like this:

// these are my AJAX functions from my projectGenie application

// function to send some data and receive the response
function sendReceive(divID,scriptPath,variables,divClass)
{
if (document.getElementById){
var thedate = new Date;
var datestamp = escape(thedate.getTime());
url = scriptPath + '?datestamp=' + datestamp + '&' + variables + '';
if (window.XMLHttpRequest)
{
request = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
request = new ActiveXObject("Microsoft.XMLHTTP");
}
request.onreadystatechange = processReqChange;
request.open("GET", url, false);
request.send(null);
contentText = request.responseText;
updateDiv(divID,contentText,divClass);
}
}

// function to process the request status change
function processReqChange()
{
if (request.readyState == 4){
if (request.status == 200){
} else {
if (request.status == 404) {
alert("There was a problem retrieving the data, the page was not found.");
} else if (request.status == 500) {
alert("There was a problem retrieving the data, there was a server error.");
} else {
alert("There was a general problem and the data could not be loaded.");
}
}
}
}

// function to update an element (notice the innerhtml?)
function updateDiv(divID,textContent,divClass)
{
if (document.getElementById){
var element = document.getElementById(divID);
element.innerHTML = textContent;
element.className = divClass;
addListeners();
}
}

There’s not really much there, so I won’t explain it. Oh, OK then, I will :0)

// function to send some data and receive the response
// this takes the following parameters:
// divID = the element that should receive the response
// scriptPath = the path (relative or absolute) of the server-side processing page
// variables = the variables to send to the processing page
// divClass = the class to set the receiving element when the response has been received
// (this is useful for unhiding things, highlighting things etc)
function sendReceive(divID,scriptPath,variables,divClass)
{
// check if the browser supports the document.getElementById method
// if not the function is not run
if (document.getElementById){
// set a new datestamp, this ensures we don't see cached versions of the processing page
var thedate = new Date;
var datestamp = escape(thedate.getTime());
// set up the URL we will be sending to and receiving from
url = scriptPath + '?datestamp=' + datestamp + '&' + variables + '';
// check if the browser supports the window.XMLHttpRequest method
// if so use this method
if (window.XMLHttpRequest)
{
// create the new request
request = new XMLHttpRequest();
}
// otherwise check if the browser supports the window.ActiveXObject method
// if so use this method as we're in IE
else if (window.ActiveXObject)
{
request = new ActiveXObject("Microsoft.XMLHTTP");
}
// set the function to run whenever the state of the processing page changes
request.onreadystatechange = processReqChange;
// open the connection to the processing page using GET
// the 'false' means this is asynchronous, so the browser doesn't lock up while we process the data
request.open("GET", url, false);
// send the data - this is null because all the variables we are sending are by GET (querystring)
request.send(null);
// get the response of the processing page
contentText = request.responseText;
// run the updateDiv function to write the response to the page
updateDiv(divID,contentText,divClass);
}
}

// function to process the request status change
function processReqChange()
{
// these are all pretty obvious, as they are standard HTTP status codes
if (request.readyState == 4){
if (request.status == 200){
} else {
if (request.status == 404) {
alert("There was a problem retrieving the data, the page was not found.");
} else if (request.status == 500) {
alert("There was a problem retrieving the data, there was a server error.");
} else {
alert("There was a general problem and the data could not be loaded.");
}
}
}
}

// function to update an element (notice the innerhtml?)
function updateDiv(divID,textContent,divClass)
{
// check if the browser supports the document.getElementById method
// if not the function is not run
if (document.getElementById){
// get a reference to the element
var element = document.getElementById(divID);
// set the innerHTML of the element to be the textContent
element.innerHTML = textContent;
// change the class name of the element (this could be done as element.setAttribute('class', divClass);)
element.className = divClass;
// now we reset the listeners so we can catch the next click
startListeners();
}
}

// and to kick all this off we do this:
sendReceive('result','add.php','a=1&b=2','success');

// of course, this line could be included in a function that has a listener attached to it

The ‘add.php’ file Would then take the values for the variables ‘a’ and ‘b’ and add them together (giving us 3 in total, in case you didn’t know) and then send the result back to the requesting page to be displayed in the ‘result’ element. While that example is pretty simple, there really is everything in there to build advanced web applications with the responsiveness of desktop apps. Depending on connection speed, responsiveness of your web server, of course. There is loads more help on this on the web, a lot of it very very complicated, but it all boils down to that principle.

There’s a really simple example here that just loads a line of text from an HTML file.

Object-oriented JavaScript

I want to touch on object-oriented JavaScript, as some of you might not believe that JavaScript is a powerful object-oriented language. Well it is, in fact everything in JavaScript is an object – functions, the lot. Perhaps the best way to demonstrate this is to use an example from The Wild.

JavaScript frameworks – Prototype

A framework, as you may know, is ‘defined support structure in which another software project can be organized and developed‘ – basically a way to stop you from having to reinvent the wheel every time you create some code. The Prototype JavaScript framework provides an easy way to use all of the functions I’ve touched on above – and a huge boatload more – in just a few simple lines of code.

I can’t possibly do justice to Prototype’s fantastic feature set, for that you need to consult the Prototype documentation. All you need to know about AJAX with Prototype is fantastically demonstrated at 24ways.org, in an article written by Drew McLennan. Is that easy or what?

An example – the ODE application

A while ago I wrote a little PHP/JavaScript application called ODE – Online Development Environment. It does just what it says on the tin, allowing you to browse a folder structure on a web server, load multiple text files, edit and save them. It has quite a few nice features such as showing an error if you’re about to close a file that you’ve edited without saving, and runs completely from one HTML (well, PHP) file with no page refreshes.