Hello there. I am Terry and I am a full-time undergraduate based in Singapore. I take photos, write a blog and design websites.

And no, I'm not a teddy bear.

Money is the root of all evil… thoughts

So it turns out that I might not be going for an exchange program next January afterall.

It took me awhile to acknowledge the fact, but I felt that it is terribly unfair for me to unload the entire financial burden onto my parent’s shoulder when studying in my university (NTU) during that period is just as good as going to Sweden instead.

Sweden is good, sans the whole Julian Assange rape smearing case which Sterling succinctly pointed out to me on Twitter earlier today. The weather there is nice. The people there are very hospitable, welcoming and eco-friendly. Their meatballs are awesome. If all these don’t cut it, at least I know that it is where my favourite furniture chain IKEA was conceived. Okay, but I still hated IKEA for using Verdana.

I just returned from a one-day trip to and from Singapore to attend this talk about the exchange program and how we should navigate ourselves around those miles and miles of crazy bureaucracy red tape. I’m not going to moan, whine, whimper, cry baby about this wasted trip – I did get lots of information about the lovely country from a senior who had just returned from the very country I’ve been yearning to travel, live and study in, and learning more about the exchange program isn’t exactly something half bad.

The gist of the problem lies with the money. I don’t live in a upper-middle class, or a high class family. We don’t rake in money by the five or more figures monthly. My dad works as a project manager cum architect in a small medium enterprise, while my mom spends most of her days cooping in the tuition class handling kids that are so wild I thought nobody could ever get hold of them. Well, at least my mom did.

The entire exchange program will set me back by around S$10,000 to S$12,000, which is a lot. Probably a few times of our household income. My brother still has one more year to see before he finishes college, and God knows what he’ll do after that. S$10,000 might not sound a lot to you (it converts to around US$7,350), but it does mean a lot to a small family like mine.

Because of my academic achievements, I’ve been studying in Singapore, a country 400km south of my hometown, for the past 8.5 (and counting) years, relying solely on scholarships. The first 6 years I was on a government scholarship since graduating from elementary school, and for the next 2.5 I’m on a university-sponsored scholarship that pays for the rest of my tuition fees.

For a very tiny instant moment I felt that all these should count in my advantage because I’ve been saving tons of money for my parents – instead of channeling that money into funding my education, they have stashed them in all forms of investments, bank accounts (probably not a good idea), fixed deposits and anything that has to do with money without actually spending them.

Immediately my conscience came riding on this moral high horse and giving me a mental lecture about how dare I conjunture such a thought – saving my parents that much money doesn’t mean I’m entitled to spend them right now, even if that S$10,000 is going to be just a fraction of it. Who do I think I am, for being so selfish, to think that I should make my parents pay for my exchange program that is so incredibly expensive?

An instant sense of shame overcame myself. I couldn’t possibly think what my parents have been through after I told them that I have set my eyes on Sweden for the exchange programs. Their jaws were left somewhat agape when I broke the news about the overall costs, and I hate myself even the more now for allowing such a lapse of judgement to take place.

So I make sure that I got it clear today – I told them that they shouldn’t care about what I would think. Even if I would feel disappointed and probably be all sad panda when I couldn’t go to Sweden, I know that the lump sum of money could be better spent elsewhere. I’ll give them the choice to choose – and I very well know that it doesn’t lie with me.

I’ll still be matching my courses for the exchange program, but that doesn’t meant that I’m getting my hopes high for parental approval. I’m not bitter about this, and in fact I feel a little embarrassed that I have been engaged in this endless soliloquy with myself throughout the entire day.

Wise up, Terry.

p/s: For once, I’m ecstatic about me being so honest with myself.

Better Form Usability with jQuery

The <label> tag is a rather commonly omitted element in HTML forms. Although the tag does not render text in it differently from those outside the tag, it provides a usability improvement for mouse users by duplicating common GUI features. More importantly, it couples an input element with a label for users of speech browsers.

The <label> tag can be used as is, but it has an extremely useful attribute – the for attribute. This attribute allows one to associate a form control with the element, when its value matches the ID of the form control. Here’s a sample of a usable, but not the best, form, without the use of the <label> tag:

<form id="form-1">
	<p>
		<span>Name</span>
		<input type="text" name="author" tabindex="1" />
	</p>
	<p>
		<span>Email</span>
		<input type="text" name="email" tabindex="2" />
	</p>
	<p>
		<span>URL</span>
		<input type="text" name="url" tabindex="3" />
	</p>
	<p>
		<span>Comment</span>
		<textarea name="comment" tabindex="4" />
	</p>
	<p>
		<input type="submit" name="submit" tabindex="5" value="Submit" />
	</p>
</form>

When we add the the for attribute to the <label> element and assign it a value that is identical to the id attribute of the form control, we will improve the usability of the form. For visually-impaired users, the speech browsers are able to draw a link between a form control and it’s label, which will provide important information and even instructions in filling up the form. For those using visual browsers are, in turn, able to focus on a specific form control when its associated label is clicked on.

Here is the improved form:

<form id="form-1">
	<p>
		<label for="author">Name</label>
		<input type="text" name="author" tabindex="1" id="author" />
	</p>
	<p>
		<label for="email">Email</label>
		<input type="text" name="email" tabindex="2" id="email" />
	</p>
	<p>
		<label for="url">URL</label>
		<input type="text" name="url" tabindex="3" id="url" />
	</p>
	<p>
		<label for="comment">Comment</label>
		<textarea name="comment" tabindex="4" id="comment" />
	</p>
	<p>
		<input type="submit" name="submit" tabindex="5" value="Submit" />
	</p>
</form>

What does jQuery have to do with this?

You must be puzzled – afterall, what you need to do so far is to manually inject the for and id attributes into the <label> and <input> elements respectively. In fact, I was actually doing these manual changes to my theme files and other web-based projects because it will only take me at most a few minutes’ worth of time.

However, I recently faced a problem that I felt using jQuery as a workaround wasn’t a bad idea afterall. Many people would advice against using JavaScript in cases like this for two reasons: some users, albeit a minority, don’t allow JavaScript to run on their browser; and on a related note, with the possibility that JavaScript being disabled in mind, we shouldn’t use it to implement essential features.

The problem was that I was working with some WP plugins that generates HTML forms dynamically and on the fly. Although some would dive into the realm of PHP and make the necessary changes such that the generated forms are more user-friendly, I would prefer using the jQuery way, which is easier and does not require muddling with the source code of the plugin files.

There are a few steps that we have to do:

  1. Retrieve the value of the name attribute of the <input> element.
  2. Assign a unique ID to the <input> element.
  3. Assign the same value (the unique ID) to the for attribute of <label>.

For those copy-happy folks, here’s the code:

jQuery(function ($) {
 	$("#form-1 > p").each(function(count) {
		var input_id = $(this).children("input").attr("name") + (count + 1);
		$(this).children("input").attr("id", input_id);
		$(this).children("label").attr("for", input_id);
	});
});

Dissecting the code

$("#form-1 > p").each(function(count) {

This line searches the document for the paragraphy element, <p> that is a direct descendant of an element with an ID of #form-1. The .each() function makes sure that we look the subsequent function across all elements that satisfy the selection criteria. The count variable is declared and it will be used in each iteration.

var input_id = $(this).children("input").attr("name") + (count + 1);

This line defines the variable input_id, and assigns it the value of that is the that of the name attribute of the <input> element combined with a unique number. The number is increased by a value of 1 after each iteration of the loop so that we will generate unique IDs, even in face of an unprobably scenario that two input fields on the same page share the same value of the name attribute.

$(this).children("input").attr("id", input_id);
$(this).children("label").attr("for", input_id);

These two lines do the same thing – the finds the <input> and <label> elements in the same parent element, and assigns the generated value to the id of the former and for attribute of the latter.

Note

Note that this technique only works if each <label> and <input> pair is located in the same parent element, and each parent element has only one pair of label and input field in it. Of course, there is a solution for those forms that do not wrap each pair in a parent element, but I will not dwell into it.

Inception and Gotham

Gotham, a typeface used in the film, Inception

Gotham, a typeface used in the film, Inception

I have watched Inception last weekend and I have to say it’s a really mind-blowing film. People are saying that Chris Nolan invaded everyone’s dream and planted the idea that the film is great *laughs* but that’s not the main point.

What really caught my attention was the choice of typeface used. It is immediately obvious that they did not use Trajan for their movie posters, something I applaud. Trajan is an overused typeface – and here’s a non-exhaustive list of popular films in the past that have used Trajan in their posters (in fact, there are 153 and counting posters):

  • The Final Destination (2009)
  • One Missed Call (2008)
  • Sex and the City (2008)
  • Bridge to Terabithia (2007)
  • I Am Legend (2007)
  • Star Dust (2007)
  • Final Destination 3 (2006)
  • Requiem (2006)
  • The Core (2003)
  • A Beautiful Mind (2001)
  • The Mummy Returns (2001)
  • The Perfect Storm (2000)
  • The Mummy (1999)
  • City of Angels (1998)
  • Deep Rising (1998)
  • Titanic (1997)
Gotham Typeface

Gotham Typeface

They chose Gotham instead. It is a geometric typeface designed by Tobias Frere-Jones and Jesse Ragan. Familiar typeface, isn’t it? That’s because Gotham has appeared in:

  • Obama’s presidential campaign posters
  • Movie posters of Moon (by the way I recommend you watch this film)
  • Branding for Discovery Channel, USA Network, Astro and more.
  • Chicago’s 2016 Summer Olympics bid.

Launching two new sites

After the past few weeks, I was busy with the work I’m getting from my internship position with a local design firm, but I still managed to dedicate enough free time to two sites I was launching. They’re not really community-powered sites, so there’s nothing hyper about it *laughs*

Tweet Archive (link)

Tweet Archive

Tweet Archive

In light of the recent instability of Twitter, especially over the one-month span of the World Cup, I have decided that backing up my tweets on a remote server will be a wise choice. Not only does the remote server helps to archive all the tweets that I have been posting since then, it also creates a searchable tweet archive. Don’t you find it frustrating that even you yourself can’t comb through your own tweets on Twitter web interface?

However, I was only able to retrieve down to the last 3,200 tweets (dating back to August 2009). The 3,200 cap was placed on Twitter API to prevent it from being overloaded with requests… which means I’ve lost around 5000+ of my older tweets, but it’s okay.

I got the idea after Jeff (@perishable) wrote about backing up his tweets during Twitter’s wobbly period. And he has got his tweets backed up already, too.

Jeff's tweet about archiving his tweets

Jeff's tweet about archiving his tweets

What I did wasn’t exactly quite rocket science (maybe except for the regex part):

  1. Upgrade my site to WP3.0, and activate the WP multisite feature. If you’re done with this step, everything will be a lot easier. Note: Please check with your host if they support wildcard DNS, i.e. *.domain.tld. If such a feature is not offered, it’s not all kaboom. Simply create a new WP installation in the subdomain’s root directory.
  2. Install a new child blog pointing to http://tweets.teddy-o-ted.com
  3. Download your Twitter archive – I recommend TweetBackup. Export the latest 3,200 tweets (or less) as an RSS feed and download it. Try to refrain from tweeting between downloading your Twitter archive and the completion of the set up – you wouldn’t want any tweets to fall through.
  4. Import your Twitter archive to your WP installation. If your server is slow, the import script might exceed the 30-second execution time limit and you will encounter a timeout error. Don’t panic. Go to your WP installation and check the earliest tweet that was successfully imported. Return to your RSS file, and remove all entries prior to that, which should shave a sizeable chunk of bytes off the original RSS file. Reimport the file.
  5. Install Alex King’s TwitterTools WP plugin. The plugin has quite a lot of function, but I configured it such that it only imports my tweets and post them. The plugin can also create a tweet from your WP post, but enabling this feature might cause a non-ending loop (although it is claimed that the plugin is designed to avoid such fireball of death, you should be smart enough to avoid it).
  6. Get a theme. Doug has an excellent one, go get it. Alternatively, you can modify any WP themes you want. The theme I am using for my tweet archive is a modification of Sandbox, modeled after Doug’s theme as well.
  7. Regex. If you’re quick, you’ll notice that all imported tweets lack outbound links for @replies and #hashtags. I wrote a short php function to do this. Insert the following lines into your theme’s functions.php file:
    // Makes URLs, @usernames and #hastags in tweets clickable
    function tweet_replies_url_filter($content) {
    	// Prevent premature texturizing
    	remove_filter('the_content', 'wptexturize');
     
    	// Replaces username with clickable link
    	$pattern_username = '/\@(\w+)/';
    	$replace_username = '@<a href="http://twitter.com/'.strtolower('\1').'">\1</a>';
    	$content = preg_replace($pattern_username,$replace_username,$content);
     
    	// Replaces hashtag with clickable link
    	$pattern_hashtag = '/\#([a-z][A-Z])(\w+)/';
    	$replace_hashtag = '#<a title="Search Twitter for \2" href="http://search.twitter.com/search?q=\2">\2</a>';
    	$content = preg_replace($pattern_hashtag,$replace_hashtag,$content);
     
    	/* Uses internal WP command make_clickable to replace URLs with clickable link */
    	$content = make_clickable($content);
    	add_filter('the_content', 'wptexturize');
    	return $content;
    }
    add_filter('the_content', 'tweet_replies_url_filter');

For more information, you can read it up here. Doug has done a great writeup on establishing your own Tweet Archive.

tdy.co (link)

tdy.co - A personal URL shortener

tdy.co - A personal URL shortener

When the .co domain was opened to the general public on the 21st of July, I wasn’t very sure what domain name do I want. The first thing that actually went through my mind was to purchase tmun.co because tmun.com was already parked (and I have no idea why). When searching for available domain names on GoDaddy I decided to try my luck and started jamming the searchform with 3 letter acronyms of my site, my nickname or my other pseudonyms.

Try.co, taken. Tsd.co, taken. Ted.co, taken. Tdy.co, still available. What?!

I jumped. Immediately I billed $26 to my credit card and snagged the domain name before anyone else does. I had no idea what I wanted to do with it until I saw Dean’s tweet about converting his new domain, djr.co, into a personal URL shortener and I thought, hell, why not?

I downloaded a fork of Shaun Inman’s Lessn, developed by Alan Hoogan, called Lessnmore. Lessn is a great simple tool and is a lot lighter than Yourls, but it doesn’t support custom slugs unless I modify the database entry. I dug around and arrived at Lessnmore. It’s an extension of Lessn, and has a little more functionality with the same API hooks as Lessn.

tdy.co/1 points to this site :)

The tdy.co main page is a little plain. However, it is a significant example because it is my first HTML5 page. I’ve never really got into using HTML5 in my current projects because of my unfamiliarity with it, so I’m more than elated that it worked out just fine on tdy.co.

Hello, World!

I’m back after an absurdly long hiatus. Tumblr has got my attention most of the day because of a seemingly infinite amount of posts appear on my dashboard whenever I relief my bladder, get a drink, talk to my brother or catch my 40 winks. In comparison my blog is rather static since the past few weeks and most of the traffic are actually coming from search engines, resulting in a very high bounce rate of around 80%. Pretty crazy!

Here’s a rough update of what happened in the past month:

This layout – teddy-risation Theta

teddy-risation Theta

teddy-risation Theta

I have less to love about the current layout, finally. I’m actually very excited because this WP theme has been up for the longest period of time – compared to the short-lived teddy-risation Epsilon who managed to provoke my ultimate wraith in less than three days online – but then it is getting very clumsy, heavy, bloated and complicated. This theme was developed before the days I knew more about hacking functions.php and I actually loaded multiple Javascript libraries (jQuery, Prototype and Scriptaculous) on the same page. Bad. Very bad.

Regardless of how flawed the current theme is, it actually found its way into Theme Hybrid’s showcase :D rate my theme if you feel like it, thanks!

teddy-risation turned six!

A week ago this site has finally turned six :) It’s another big milestone – since it’s fifth birthday, this site has turned into more like a place where I dump my design inspirations, coding tutorials and some photography works. There is less and less writing about my life, and I’m very much aware of it. Most of the personal stuff has been migrated to Tumblr.

Speaking of which, I have recently migrated my Tumblelog, too. It was a silly mistake that I made, to make my Tumblr as connected to my other online identities as this site was. It was a foolish decision, because I ended up having too many prying eyes and nosey folks stalking my Tumblr entries. A week ago I made the decision to replace my original Tumblr site with a dummy page, while its actual contents were clandestinely moved to a new location – and you’ll have to ask me if you have not been given access to the new Tumblr.

Upgraded to WP3.0 Multisite

Over the week I have also upgraded this WP installation to the latest version, which has integrated WPMU in it, too. After some tinkering with wp-config.php and the .htaccess files, I have managed to activate the multisite feature and now I’m actually running an additional WP site on the server.

I’ll keep you guys posted about what the new site is about. But basically it’s a WP blog that serves the sole purpose of backing up all my tweets ;)

If you need any help with implementing WP3.0′s multisite feature, feel free to contact me. I’ll help you as much as I could.

Personal

If you read my Tumblr you’ll probably knew what happened, but to others I could only say that something major happened around me life lately – I wouldn’t say that its unpleasant or something worth to be celebrated of. It’s neither of both. It is more like a process of discovery, learning, embracing and accepting.

My life was, for a moment, up in smokes for a few days a week ago, which explains pretty much what happened – not only I was not in the mood to celebrate this site’s 6th birthday, I also had to migrate my Tumblr because of me writing some really private stuff in there. Since then, things have pretty much stabilized and my life has returned to normal (hopefully so).

And to all those who sent my emails and left comments on my Tumblr, lending me support and dishing out really helpful advice, thank you. You know who you are ;)

I guess that’s all for this update! I’ll keep you guys posted, watch out this space.

Page 4 of 194« First...23456102030...Last »

Hello Easter Egg hunter! You've discovered the magic of the Konami Code!

Yea. You probably know what the Konami code is before getting to this page. So now what? Here is a randomised YouTube video on my favourites list... which includes Rickroll, if you're luck enough to get it.

You are currently watching How long can you hold your breath. Loving it? You can even watch the video in its full screen glory :)

The Konami Code:
Konami Code sequence