The rage

13 May, 2009 (23:11)

Another common usability mistake most make, is the step after a user signs into a web page. Most web pages will redirect a user to the front page or his profile page, which is fine if he is signing in from the front page. But most commonly a user will sign in when he is forced to do so, when he tries to leave a comment for instance:

loginThe text translates as “Sign in, if you want to comment, rate or add the game to your favorites”. Upon clicking the link, a user would then be presented with sign in page. So far so good. The problem arises (on most web pages) when a user successfully signs in. Instead of redirecting him back to the page where he was, when he clicked on the sign in link, he is instead taken to the front page. Now the user must navigate his way back to where he was, loosing his interest in leaving the comment along the way …
I’m stating the obvious now, but the correct way is to redirect the user back to the page, where he can do whatever he was unable while not signed in.

And implementing this is really easy, that is why it’s even more strange that there are so many web pages without this “feature”. All you have to do is append the current URL to the sign in page (signin.php?ReturnTo=current_url for instance) and then do a simple HTTP redirect after the sign in.

The image above is taken from our web page igre123.com, where we don’t annoy our users :)

Generate sitemap(s) with PHP

9 May, 2009 (14:45)

Sitemaps are XML files that help web crawlers (google, yahoo, …) get to know your web page better. The sitemap file contains information about when a web page or sub page was last modified, how often it is updated, etc.
It also includes a “priority” information which tells the crawler how important is one page in comparison with other web pages on the same domain. I won’t go into any details here as you can read all about sitemaps here.

Since I don’t want to edit the sitemap files by hand I’ve written a simple PHP5 class that generates the sitemap(s) on my behalf. On videoarhiv.com, for example, I generate the sitemaps when a crawler that fetches new videos is run.
Now since most of the web pages I work on have many sub pages, my class splits the entries into multiple sitemap files (there is a limit of 50000 entries per sitemap file, and it can’t exceed the 10MB file size) and then generates a sitemap index file that contains the URLs to site maps.
This class was constructed with my demands in mind, so you may have to tweak it to suit your needs. For instance, I only store 40000 (which is hard coded) entries per sitemaps as to respect the 10MB file size limit.
You may have to change this, depending on the type of URLs you have (if you have very short URLs, you can increase this number for instance).

Source code of the class can be found here.

And here is a short example of how to use it:

Include ( '/path/to/SiteMap.class.php' );
// change to SiteMap::WRITE_GZIP to compress the sitemaps
$sm = new SiteMap ( '/path/to/sitemaps/', 'http://www.yourdomain.com/sitemaps/', SiteMap::WRITE_PLAIN );

$data= Array ();
$data[] = new SiteMapItem ( 'http://www.yourdomain.com/', Date ( 'c' ), SiteMap::CHANGE_HOURLY, '0.9' );
$data[] = new SiteMapItem ( 'http://www.yourdomain.com/about', Date ( 'c' ), SiteMap::CHANGE_MONTHLY, '1.0' );
// add all your sub pages like above

// this will generate your sitemap(s) and store them on the location you specified in the SiteMap constructor
$sm->Generate ( $data);

Another One Bites the Dust

8 May, 2009 (17:15)

I like talking about usability, so today I’ll talk about another easy way to improve your web page. There are many web pages which use AJAX to post the contents of a form back to the server. The problem is that most of them don’t act as regular forms, where you can hit enter on your keyboard and submit the form.
The problem is that most developers use a type=”button” instead of the type=”submit” button in their AJAX forms, so you have to click on the button to submit the form. The problem with using a type=”submit” button in AJAX forms is that the browser will submit the form the regular way.

And this, off course, can be easily fixed. You already have a JavaScript function that your type=”button” button calls when clicked. All you have to do is change the type=”button” to type=”submit”, return false from the function that does the AJAX request and then you define a “onsubmit” event for your form.

Example:


your form elements

And that’s it. Off course you should attach the “onsubmit” event via JavaScript not in-line like in the example.

Lazy Days

7 May, 2009 (16:21)

Most developers just go “the usa what now?” when you mention usability. And it shows if you browse the internet a little. And it’s really sad that this is the case, as there are so many quick and easy ways to improve the usability of your web page.

I’ll talk about labels today. They are a very useful but often neglected tags. Take this web site for example (there are many other):

blogorola

Notice the check boxes in the red box (I added that), you define what you want to search for with the search bar above. Great. Only that it isn’t.
If you want to select the “V imeniku” option you have to click the radio button and clicking on the text “V imeniku” has no effect. That’s annoying because you have to pixel-hunt that small radio box.

So how do you improve this? Enter label tag. You put the text that is associated with a certain option inside a label tag, and you set the “for” attribute of the label to the ID of the radio box (or any other form element) you wish to trigger.
Now the user can either click the radio button or the text and the result is the same.

A short example:

<input type=”checkbox” id=”cbContent” name=”cbSearchType” value=”content” /> <label for=”cbContent”>Po vsebini</label>

I would like to state here that all the web pages I’m responsible for are using labels, but they are not. Mostly they are my old projects I don’t have control over anymore. But there are still some active projects that don’t have labels on every form. But I “convert” them as soon as I work on that page on some new feature. Please, do the same!

And, if you haven’t already, read trough this web page (useit.com: Jakob Nielsen on Usability and Web Design).

Harvester Of Sorrow

6 May, 2009 (21:32)

Contrary to popular belief, on various developer forums, I’m, in fact, not a two headed monster crushing hopes and dreams of new comers.

Every now and then a new user registers who’d like to be a programmer. All is good up until the moment he click’s on the submit button of the new thread form. What usually happens then is a thread in which the new user is asking for complete source code for his problem/answer to something way out of his league/homework solution/…

Then I come along (or some other similarly minded colleague) and try to explain that nobody will work for free/he should start with basics/he should do the homework by himself/…

And then the new comer says isn’t a forum supposed to be a place where people help each other/but I want to do this, and I want it now/but I really need this tomorrow/…

In the past I’d try to explain to this new user how things work, throw in some analogies with being a pilot, car designer, etc. and I’d, off course, fail miserably. I really don’t know what’s so hard about understanding, that you have to learn to walk first before you can run, and that programming is no exception.

I’ve simply stopped doing this as it a complete and utter waste of my time. I just let the newbie learn the hard way. But I’m still trying to come up with a great response to this type of questions that would send the new user in the right direction. I do want to help; I always do, if question is really a question.

No educational content in this post, I know, but I just needed to rant a little :)

It's so easy

29 April, 2009 (21:44)

Time has proven that the best ideas are dead simple. Think YouTube, Flickr, Hotmail, Twitter, etc.
And once again somebody beat me to the punch and made a something that was under my nose the whole time, I just didn’t see it.

Anyways, the other day my father asked if there was any way for him to edit the web page of his singing choir. They have a simple HTML only page with some sub pages. So a full blown CMS would be an overkill, as my father would have to learn how to use that and he doesn’t need all the features. Well luck had it that I was browsing the daily WTF and they ware running an ad for something called CushyCMS. The name hit home with me (I mean it just so likable) and I clicked on the link.

It is a CMS … just that it isn’t. The video on the front page will give you a better picture of the whole thing so just go and watch it. But in a nutshell it’s a piece of software that you don’t have to install, you just register, enter your web page’s FTP information, add pages to the CMS and you can edit the content. It’s just magic.

The interface is idiot-proof so anyone can use it. The editor (you can define multiple editors and grant them access to selected pages only) only sees a simple rich text editor, where he can format the text, insert images, etc.
And the best part is, like I said, no installation required on your server. All you have to do is add class=”cushycms” to the element you wish to make editable and CushyCMS will generate a input field (RTE, regular input, image upload, etc) on your behalf. It even stores history of the changes you made, so you can rollback to any previous version if you wish. And, of course, you can still edit the pages by hand directly on the server.

CushyCMS

The only draw back I found so far is the lack of any dynamic content generation. For instance; if you have a page with news, you have to edit the whole page, and add a new news item and edit it by hand so that it matches the design of other news. And you can’t make new pages (you have to create them by hand on the server and then add them to CushyCMS).

It’s, like I said, a very simple idea that I wish would think of. Oh and it’s free, unless you wish to brand it, in that case there’s a small monthly subscription fee.

Have a cake and eat it too

28 April, 2009 (19:01)

Using jQuery (or prototype or whatever) is a standard tool in my tool belt nowadays. It’s so useful I can’t think how I’d do without. You can make some pretty nifty user interfaces with it. And not just pretty ones, but useful ones to.
Take our latest project for example, on the front page (and sub pages also) there is a list of TV stations and it’s current program (2 or 3 items per station). And some of those programs have extra description:

spored.tv

Now the old fashion way would be to click on a program which would then take you to another page where you could read the description. The jQuery way is to show the description immediately and with some style! So after clicking on the first program, for example, the description would slide down beneath it, thous saving user the time of a new request and the time it would take him to get back to the schedule:

spored.tv

Off course this is useless for web crawlers (google, yahoo, …) so you still have to provide the old fashioned way (if you wan’t for your content to be found). It’s really simple to achieve this. You construct the link (which opens the description) like a regular HTTP link which points to a page where you can read the same description (in my case: http://www.spored.tv/program/unicevalca-mitov/1009118). Web crawler (or any user who has JavaScript disabled) will now see this link and will be able to read the content.
Now you use jQuery to dynamically add a onClick event handler, to every link, which slides the description and returns false, so that the browser doesn’t follow the link. Feel free to view the source code of spored.tv to see how I’ve done this.

Class_Exists, __autoload & third-party code

26 April, 2009 (18:35)

I had some problems with my new PHP framework. I was trying (for the first time in this framework) to use a third-party library in my code (SimplePie). And that turned out to be a problem.
See, my framework uses __autoload to dynamically load classes that aren’t yet included. And SimplePie (like many other libraries) uses the Class_Exists function to check if some component is present or not (which is great).

Now the problem is, that Class_Exists, for reasons I can’t comprehend, calls the __autoload function you define. Yes there is a second parameter that disables this behaviour, but are you expecting me to dig trough ten’s of thousands lines of SimplePie (or any other) code to change the second parameter to false? Madness. And that’s not even the point. The function Class_Exists (as name suggests) checks if a given class is loaded and can be used. Why on earth would you go on and try to load the class if it isn’t?

Now you might say: “you should check if the file you are trying to include in your __autoload function actually exists”. “But why?”, I ask? Why should I? If something vital as a file with a class your code is trying to use doesn’t exists, then something is wrong and the application should crash, there is no point in sugar-coting the error.

I hope they fix this in the future so we don’t have to use ugly hack’s in our code to make our code compatibale with third-party code

Handling layout breaking text #2

31 January, 2009 (18:13)

This is a follow-up post to the previous one. I have made some modifications so that you can have HTML tags in your text and my code will still work. I’ve packed the whole thing in a PHP5 class which you can get here. I wanted to put a demo up, but apparently I don’t have PHP5 support here, and Mb_* functions seem to be a mystery to GoDaddy also, so no demo…

So how did I solve the problem with HTML tags? Well before I process the content I replace all HTML tags (including < and >) with some (hopefully) unique characters ($%&) followed by a number, and I save the HTML tag to array (the number is the index of the tag being replaced). Then after the “wbr” insertion I replace the unique characters with the tags I stored.

A quick demonstration on how to use the class (use freely, no guaranties):

$o = new WbrInserter ();
echo $o->InsertHtmlWbr ( 'text with HTML tags' ); // use this method if you have HTML tags in your content
echo $o->InsertPlainWbr ( 'text without HTML tags' ); // use this method if your content doesn’t include HTML tags

Handling layout breaking text

30 January, 2009 (18:56)

Displaying user entered content on a web page can be a pain in the ass. The biggest problem I was always having was long words (usually something like this: “hahahahahahahahah” spanning 100 characters etc) and how to prevent them breaking the layout of the web page. I tried various techniques but none worked as I would like.

So today when I was working on a new web page I decided to find a solution once and for all. So after some googling I found that there is a tag called “wbr” (I don’t really know how I didn’t come across it sooner). I did a little bit of testing and indeed this was the answer to all of my wrapping problems. This is basically an invisible tag that tells the browser that it can split a word on the position of the “wbr” tag if necessary.

So all I needed was a way to insert this tag into the text. So I wrote this PHP function that splits the text by spaces, loops trough all the words, and if it finds a word that is longer than 10 characters it inserts the “wbr” tag after every 5th character of that word. Now this may look like a redundant way of doing it, you might think that I am not aware of the Chunk_Split function that does exactly what I do in the inner loop, but unfortunately Chunk_Split does not support UTF-8 strings so I had to roll my own solution. Why the 10 character limit? I don’t know, but after some testing I discovered that the results are most optimal with this limit.

You will notice that I don’t pass the $encoding setting into any of the Mb_* functions. This is because I have set the encoding via Mb_Internal_Encoding at the beginning of my script.
One final note: thw “wbr” tag is not supported in Opera so you have to use some CSS. Details can be found here, I used the code in the last comment.

function MakeDisplayFriendly ( $Text )
{
	$splited = Explode ( ' ', $Text );
	foreach ( $splited as $key => $value )
	{
		$valueLength = Mb_StrLen ( $value );
		if ( $valueLength > 10 )
		{
			$newValue = '';

			for ( $i = 5; $i < $valueLength; $i = $i + 5 )
			{
				$newValue .= Mb_SubStr ( $value, $i - 5, 5 ) . '';

				if ( $i + 5 >= $valueLength )
				{
					$newValue .= Mb_SubStr ( $value, $i );
					break; // save some time by breaking from the loop, as we already know the next condition check will fail
				}
			}

			$splited[$key] = $newValue;
		}
	}

	return Implode ( ' ', $splited );
}

update: Note that this only works with plain text. It will most likely brake HTML tags in the text, as the function will insert the “wbr” tag in the middle of them. I’ll try to come up with a solution when I find some time. Read this post if you have HTML tags in your content and you wish to use this code.