Pretty textbox jQuery plugin

26 September, 2009 (11:00)

Some time ago I made a pretty search box for our latest project (not yet released) and I thought I’d make it into a jQuery plugin and share it with you. The goal was to have a text input with some default text (search this, or search that) and a pretty magnifying glass image in the right. And when you click (or give focus to) into the input the default text and the image would disappear. This is just an effect we ware going for, you could make something completely different using only CSS and this plugin for the default text disappearing/appearing. The nifty part is that if the user doesn’t enter any text and leaves the input box the default text pops-up again. Best describe this with a image:

pretty text box

Plugin code and demo can be found here. I also played with CSS3 border-radious and box-shadow to make the inputs even more prettier.

update: just realized that the middle label on the image should be “with focus” not “with input”

Conditional CSS

22 September, 2009 (23:14)

CSS is a lovely thing, but it can get out of your hands very quickly (especially if you are programmer first and HTML code-monkey second). I often find myself having some element that appears on various sub-pages of a page, comments for example. HTML is stored in a template file and included where needed and styles, that make the comments pretty, are usually in the main CSS file. No problem with this approach if comments are exactly the same on whichever sub-page they resist. But what happens when they have to be 200px wide on the user’s profile page and 300px somewhere else? You make another CSS file where you override the width and include it on the page.
The problem with this is that you often end up with several CSS files containing a few lines, which increases the number of requests and page load time. But the biggest problem with this is maintainability. All of a sudden you have styles for the same thing in several different files and guess how long that takes to get out of sync.

So I was thinking how one would go about solving this, and I came up with this: what if you ware able to define a certain style only if some condition would be true. CSS if statements! I’m not proposing a juggernaut here, just something along this lines (haven’t really thought about the syntax):

#CommentsContainer {
width: 100px;
background-color: silver;
}
[URL=/some/path/(.*)/([0-9]+)]
#CommentsContainer {
width: 200px;
}
[/URL]
[URL=/some/other/path/([0-9]+)]
#CommentsContainer {
width: 300px;
}
[/URL]

So depending on the URL some of the styles would be defined and some would be not (you could have URL!= for instance and some basic Boolean operators such as AND and OR). You would define the URL with regular expressions (as you have probably guessed).
With this approach you could have all the styles for some page element (comments are just an example I’m struggling with at the moment) defined in one place, which greatly improves maintainability, and you would reduce page load time, which matters the most at the end of the day.

Conditional CSS

I just thought of this and haven’t asked google if somebody has already written about this, so don’t hold it against me if I say that this is my idea.

Be progressive and do community a favor at the same time

24 July, 2009 (19:07)

Currently there are around 5% of internet users that have JavaScript disabled or their browser doesn’t support it. I’m all for progressive enhancement and degrading gracefully,whether you do it or not, depends on you.
I, for one, look forward to the day when this percentage will be zero, and we can all forget about this. Until then I will do my best to keep my web pages friendly to users without JavaScript (I am a prefectionist after all :). If nothing else, search engine’s crawlers are users you simply can’t ignore, and JavaScript doesn’t exist for them.

Sometimes there is a feature that just can’t be done without JavaScript or is to complicated and time consuming that it wouldn’t make sense spending the time to accommodate for that 5% of users. I’ve developed a new strategy for our newest project: if there is a link that triggers some JavaScript code I construct it like so:

<a href=”http://www.our-domain.com/enable-javascript.html” id=”FancyStuffLink”>do some fancy stuff</a>

This is a perfectly valid link that anyone can click. The trick here is that I attach a “onClick” event with JavaScript and remove (or rather replace) the “href” attribute. The end result is that users with JavaScript won’t see the “enable-javascript.html” URL if they hover over the link, and if they click on it the desired functionality executes.
Whereas users with JavaScript disabled are (upon clicking on the link) taken to a page describing the benefits of enabling JavaScript and some simple instructions on how to do it (tailored to the browser they are using, off course).

Unfortunately our project is not yet finished so I can’t show you a live example, but I’ve made this demo page where you can see this. Just view the source to see the code.

ps: you’ll see my first jQuery plugin on this demo page, so any comments regarding that are highly welcomed. Off course, you can use the code if you happen to find it useful.

@ operator is slow

21 June, 2009 (09:44)

The @ “operator” in PHP is used to silence any warnings or errors that would otherwise be shown (in the browser or the log). It’s really useful, because sometimes you know you can safely ignore a warning or error, when checking if a GET variable is set for instance. Until today I though that, if used properly and with caution, the @ operator can be freely used. Then I read this article. I really had no idea that PHP is doing so much work behind the scenes to make @ work.
When PHP comes to a statement, that contains the @ operator, it changes error reporting to none and then back, which translates to a trip to the php.ini file.
So after I stopped scratching my head and thinking “why the bloody hell would one do that like so?”, I opened my PHP editor and wrote this simple test to see just how much of a difference this makes. It’s the most common scenario where you check if a GET variable has any content.
First the version with @:

for ( $i = 0; $i < 1000000; $i++ ) {
	if ( @$_GET['var'] != '' )
		echo 'foo';
}

And the version without @:

for ( $i = 0; $i < 1000000; $i++ ) {
	if ( IsSet ( $_GET['var'] ) && $_GET['var'] != '' )
		echo 'foo';
}

I timed the execution of both snippets and here are the results:

  @ version IsSet version
1 1.52496409416 0.196986913681
2 1.48627185822 0.204479932785
3 1.52267694473 0.206820964813
4 1.51263594627 0.207319021225
5 1.49150109291 0.199639081955
6 1.48829102516 0.174983978271
7 1.54369091988 0.206038951874
8 1.52254199982 0.204971075058
9 1.50641703606 0.190815925598
10 1.51343107224 0.203064918518
sum: 15.11242198945 1.995120763778
avg: 1.511242198945 0.1995120763778

The IsSet version is about 7.5 times faster, really amazing. I don't use @ as often as I used to, but I will now try to reduce it to zero. You should do the same.

Aliiike recommendation engine

16 June, 2009 (19:21)

We updated igre123.com today and one of the main new features is the recommended games you see on the right of the game you are playing:

recommended games

You may not see this if you go see for yourself. Either you are viewing a game that hasn’t got enough data collected to show the recommendations or you are one of the “lucky” 20% of users who don’t see the recommendations (we are comparing how well this new feature influences bounce rate, time on page, …).

We are using the Aliiike recommender system which is a breeze to use and gives fantastic results. We simply couldn’t offer better recommendations based on search because games rarely have title or description that would overlap (we have yet to test this on mojvideo.com where this isn’t such a big problem). And if you look at the above picture, showing a bejeweled like game, you can see that recommended games are really related (most of the games are of the same type or are puzzle games).

When you install Aliiike you are simply putting a simple JavaScript tracking code (kinda like google’s analytics) into your product page (product being anything you want, aliiike doesn’t care what it is tracking) which logs how your users move from one product to another (it does that by logging the URL of the product). And then you wait a week or two for the data to collect (you get better and faster results on high traffic web pages as there is more clicks to analyze).

After Aliiike has enough data you can start showing recommendations. There are various ways how you can do that, but all is explained on this page, so I won’t go into any details.

We grab a fresh file with analyzed data every day and store the recommendations into the database, but you could opt for a simpler approach with AJAX for instance.

Anonymous paradise

11 June, 2009 (15:57)

Google’s gmail is great; I can’t imagine working with email without it. Unfortunately, as with everything, there are some issues with it.

Did you know that the following email addresses all “translate” to the same account: not.a.real.email@gmail.com,notarealemail@gmail.com, not.arealemail@gmail.com, n.o.t.a.r.e.a.l.e.m.a.i.il@gmailcom, … ?

This is great, because who could remember where the dots are when somebody tells you his email? But this also means that a user can register on your site using one email multiple times (how many times depends on the length of his email), because he can just randomly rearrange the dots and voila a valid unused email.

So this is really anonymous paradise as he can register countless times (if you ban him for instance) without going trough the hassle of setting up a new email account. I don’t know if other mainstream email providers also have this “feature”.

So the obvious solution would be to remove all the dots when a user registers/signs in using a gmail email, but that could cause some problems later on. What if Google suddenly drops this “feature”? You would wind up with a whole bunch of problems.

I think that a better solution is to store the dot less email into some table when you ban a user. And then at registration you check the email, the user is wishing to register with, against this table (stripping dots off course). This way annoying anonymous users get to use his email only once.

php konferenca 2009

6 June, 2009 (18:15)

This year’s Slovenian PHP conference just finished. This was the second installment of the only PHP event here in Slovenia. It’s a shame I wasn’t there last year so I can’t compare. Overall I was really impressed with everything, all but two talks ware magnificent. Guys from videolectures.net have recorded the whole thing so you will be able to see the conference if you weren’t able to make it.

PHP konferenca 2009

Below are my opinions on the lectures:

Delavnica: OpenID, OAuth in Najdi.si Prijava (Workshop: OpenID, OAuth and najdi.si login):
This workshop showed me that OpenID isn’t that hard to implement (few API calls and you are done). The user experience bugs me (Facebook Connect wins here) and I don’t se mass adoption anytime soon, especially because, apparently, many OpenID enabled web pages are making a white list of OpenID providers that they accept logins from. Najdi.si made their own OpenID provider but they are not really helping with educating users what OpenID with their own custom name.

Delavnica: Varnost in PHP (Workshop: Security in PHP):
Really great workshop, Gašper Kozak walked us trough all the major security issues we, developers, should take care of. Most of the stuff he sowed was known to me and I’ve got them covered in my code, but there were still some things I just stared with my mouth opened. I will address those issues first thing on Monday. Gašper was also kind enough to point some security flaws in my code (he still has to give me details).

Predavanje: PHP brez brskalnika (Lecture: PHP without the browser):
This lecture was about PHP CLI and it showed me some new tricks to use. It also showed me how to do multi-threading properly (something I’m struggling with for quite some time now). Great lecture!

Delavnica: Izdelava Facebook aplikacij in uporaba Facebook Connecta (Workshop: creating Facebook apps with Facebook Connect):
Here we learned how to build Facebook applications and I learned that this really isn’t all that difficult. You build the application just like you are used to, the difference is only that you ask the Facebook API, instead of db for example, for users data. Great!

Predavanje: 10 koščkov kode, ki so mi olajšali življenje (Lecture: 10 code snippets that made my life easier):
Unfortunately I overslept (this lecture was the first of the second day) so I missed half of this lecture. But judging from what I saw it was pretty much useless. Marko Štamcar was showing us some code that would be acceptable for a rookie programmer or would have it’s place 10 years ago.

Predavanje: Keširanje dinamičnih vsebin (Lecture: caching of dynamic content):
One of my favorite lectures, Miha Hribar of 3fs (who was the main sponsor btw) talked about memcache. It was really interesting as we plan on implementing it in the near future and I learned quite allot about how to do this. Very handy!

Predavanje: PHP+Flash=RIA (Lecture: PHP+FLASH=RIA):
Anže Žnidaršič (organizer of the conference) was this lectures speaker. Although I’m not planning on using this anytime soon the talk was interesting as it showed us that there are alternatives to writing PHP applications the “regular” way. Basically the development is very much like ASP.NET if you use flash.

Predavanje: Real-time web (Comet) (Lecture: real time web with Comet):
We are planning on doing a something that will require us to use Comet so this lecture was really helpful. I learned all the missing pieces so I can now dive in and implement the feature (can’t say what it is just yet). There are allot of problems with using Comet (which is just a bunch of technologies wrapped in a common name, just like AJAX) on the client side, but fortunately there are libraries that deal with those problems. The best part is that it works in all mainstream browsers including IE6!

Predavanje: Spletne aplikacije na namizju (Lecture: web applications on the desktop):
Anže already scratched the surface in his lecture but Swizec gave us a in-depth look at Adobe AIR and how to use it. It looks like a nice platform. I only wish he would compare it to Silverlight to give more perspective on the technology.

Predavanje: CodeIgniter PHP Framework (Lecture: CodeIgniter PHP framework):
I hate to say this, but this was the worst lecture of the conference. Tomaž Muraus talked about CodeIgniter but instead of showing us how to do a real web page in it, he basically walked us trough the manual which I can do by myself.

Like I said I’m very pleased with the conference and I’m looking forward to the next one. Maybe I’ll even man up and prepare a lecture/workshop of my own.
I’ve also meat a lot of my fellow php-si.com users and it’s always nice to put a face to a nickname. Really great getting to know you all!

IE6 is dead … over the weekend

4 June, 2009 (21:28)

Every time I’m writing new HTML&CSS I check google analytics to see what browsers our users are using. I do this so I can determine what browsers must be supported and if Internet Explorer 6 is, by any chance, dead yet. This is, annoyingly, still not the case (I shall be very drunk when that day comes). IE6 still has, on one of our web pages, 47.30% share between different IE versions (IE7 trails it closely with 47,06%). Overall IE holds a 48.54% share, Firefox is second with 47,09% and Chrome is third with 1,90%.
So no surprises here, except maybe for Chrome which beats Opera and Safari. The power of Google brand is amazing.

What I did find interesting is how IE6&7 share changes during the week. On weekends IE7 has a bigger share then IE6, whereas during the week IE6 leads. And here lies the main problem why IE6 is still hanging around. You see, most of IE6 users come from various government agencies and departments (ministries, schools, town halls, …) and big companies. They usually don’t upgrade because they use custom web applications that refuse to work on anything else other than IE6. The other main reason is that system administrators (in companies mostly) can’t justify the upgrade to the bosses or are just plain ignorant and don’t bother. So that is why IE7 gains, although slightly, over IE6 during the weekend, because users who surf the internet during work with IE6 go home and use something more modern.

This disturbs me greatly, because I don’t know how this will change anytime soon and we, webmasters, will have to support IE6 (if we don’t want to loose customers that is) for a long time.
Off course there are other reasons for this mess we are in. Most users are regular Joe’s who haven’t got a clue about computers and they usually don’t even know they are using a browser, they just “surf the web”, so we can’t expect them to upgrade anytime soon. How could they? They don’t even know that there is something wrong with what they are using. And Microsoft is to blame here. They ware simply not aggressive enough when they released IE7, they should have pushed IE7 as a critical update that would install automatically without user intervention (they could exclude companies from this so that sys admins could confirm the install) and they should have launched a broader media campaign, like they are doing now with IE8.

Stop IE6

Facebook like rounded images

31 May, 2009 (09:30)

We are currently renewing Igre123 with a wider design to accommodate the new standard web resolution. Somewhere along the way, we decided that it would be nifty if user’s avatars would be rounded like on Facebook:

I thought the task would be difficult at first, but after I tossed some CSS around, I found out that this is not the case.
In a nutshell: you have a regular rectangular image and then you make another (overlay) image that you put on-top of the first image. The overlay image is mostly transparent and only has white corners that make the curved border (those hide the corners of the first image).
I’ve made this demo page where you can see how one can accomplish this (I used ugly images just for the sake of demonstration). You’ll notice that there are two examples. The first one uses one overlay image which has corners both on top and on the bottom. Use this if you know the dimensions of the image being rounded (as the overlay must match it’s dimensions).
The second example uses two overlay images, one for the top and one for the bottom. I use this one, as our user’s avatars have a variable height (but fixed width). The only problem here was IE6, that’s why there is a height property on the container span. Without that IE6 puts the bottom overlay at the bottom of the page and not at the bottom of the image.

The Invisible Man

20 May, 2009 (20:59)

If you have a web page such as YouTube or Mojvideo, where the sole reason for a pages success is user generated content and the quantity (and quality off course) of it, it’s easy to forget about the users who don’t contribute to the content of the page. We (at Popcom) spent most of the time developing and improving features for registered users, which isn’t bad per se, but unregistered users (who account for the majority of visitors) usually don’t gain anything from that. Mostly because you have to be signed in to see the new feature. The problem is that usually there is no easy or unobtrusive way to advertise that feature to unregistered users.

So, the goal of any page maintainer should be to evenly spread his time between developing features for registered and unregistered users. The real trick is, off course, making some feature for unregistered users which will convert them into registered users.