Monday, May 18, 2009

Maribor 2009 Desktop Olympic Games

I'm currently working as a part of a committee tasked with the design, development and organization of Desktop Olympics that will be held in Maribor on 20th May 2009.

The whole project is a product of Brain Working 2009 workshop which is held as an introduction to the annual Magdalena festival.

For more information on the Desktop Olympics be sure to check out the official Desktop Olympics page, to follow @desktopolympics on Twitter and become a fan on Facebook.

If this event is gonna be as fun as is its organization, you won't regret your coming.

Reblog this post [with Zemanta]

Monday, May 11, 2009

jQuery worst practices... really?

Following Elijah Manor (@elijahmanor) on Twitter I came across a blog post suggesting three worst practices in jQuery. So I decided to rant. I almost don't remember when I did that.

If you already opened the article and are familiar with jQuery, its ideology, best practices and have been using it for at least a bit, you know that something is wrong there. Something? Oh, come on, even the advice about commenting is not completely right.

Well, let me begin a dissection of the article:

jQuery and Regular Expressions have a lot in common: They are both amazingly powerful and they are both as ugly as a knife fight between two obese street-whores in a garbage-strewn alley.

When I was reading the article for the first time I skipped this sentence and went straight to the "worst" practices. Had I read it, I would have closed the article and went on with my life and this post would never come to be. Even so, this comment is a matter of taste so there's nothing valuable I can say about it (except: use a different framework, but it sounds too fanboyish).

Worst Practice #1: Hooking up event handlers dynamically when there is no need.

And the author goes on to explain how hist first worst practice is that sometimes there is no need to assign handlers dynamically. Well, surprise: the main reason jQuery is so popular is because it allows us, developers, to include JavaScript in an unobtrusive manner. That means exactly what it sounds like — his Worst Practice #1 is almost one of the reasons why we have jQuery in the first place. And if you care about usability and accessibility at all, you know that unobtrusive is a way to go. If you don't, then, please, don't do web development anymore.

Worst Practice #2: Chaining the results.

I love jQuery because you can chain the results. And using the "unreadable code" argument to support this statement is all but silly. In JS, just as in C++, Java and many similar languages, whitespace is (mostly) ignored by an interpreter. Feel free to put it in any way you like it.

Let's rewrite example from the blog:

$("div.highlight").css({
  color: "yellow",
  backgroundColor: "black",
  width: 50
});

Well, I cheated a but and combined style rules into one function call so there is no chaining here. However it does demonstrate that jQuery is as readable as any other CSS file. Hopefully a web developer has edited one? To demonstrate how to make chainability more readable, let's write a new example:

$("div.highlight")
  .css({
    color: "yellow",
    backgroundColor: "black",
    width: 50
  })
  .slideDown('fast')
  .text('Hey, this is higlighted')
;

I understand that we all have different criteria, tastes and consider different styles "unreadable", but there is no sense writing a blog post in which you will say that the things a framework is best known for are the worst practices for programming with that framework.

I'm not saying that those practices jQuery promotes are the best ones in the world, but they are the best for jQuery. If this was just a rant against jQuery, I wouldn't be even bothered to read it, but in this case, I just can't understand why anyone would be using such an "ugly" framework when there are such beauties as Prototype, MooTools, Dojo...

The third "worst practice" doesn't have anything to do with jQuery, but (I actually hate to say it) the author's example actually is a bad practice. You don't comment what piece of code does, you document its intention. Hence a comment like "get all the Divs with the highlight class and format them and set their width" is totally superfluous and increases the maintenance needed. Anyone who can read is able to read jQuery documentation and CSS specification (or at least a guide on w3schools.com) if he is about to write any code related to web development. If you want to add valuable comment, then you write "style divs that should be highlighted." Even this comment is mostly superfluous, but at least you don't need to update it any time you change the code.

Happy programming.

P.S.: the convention is to name JS variables in camelCase, not PascalCase. Just an intersting thing to note.

Reblog this post [with Zemanta]

Tuesday, January 13, 2009

Solving LoadError problem on Mac OS X

Ruby's LoadError exception occurs when a file specified as a parameter to the load method cannot be loaded. This usually means that the file specified cannot be found in search path. To check if it really exists you should take a look your search path by opening the irb console and examining contents of $: array. Don't forget that gem method changes the contents of the array.

But what if file exists and you still got the problem? Check the privileges! When I installed textmate gem from Github, the textmate file (the one in /Library/Ruby/Gems/1.8/gems/wycats-textmate-0.9.2/bin/) had very weird set of privileges: -rwx-wx-wx. When I chmod-ed the file to 0755 (-rwxr-xr-x), which seems more logical anyways, everything worked as expected.

So, check your load paths and your privileges.

Tuesday, January 15, 2008

Dynamic Calendar Helper - changing months

Lately I’ve started playing with Ruby on Rails and boy, am I excited. When I started, I’ve installed rails with apt-get on Ubuntu, which installed rails 1.2.5 for me. Only later (but not before I finished few sample apps) I learned that there is something called RoR 2 :) Nevertheless, I already convereted one of my sample apps to rails 2.0.2 and I’m getting hang of it.

In this app, I used DynamicCalendarHelper plugin to display data in a calendar. Although it does exactly what I needed, I found that configuration of next/previous month buttons is not a trivial task, so I decided to share my implementation (maybe someone can tell me if there is an easier approach).

My solution was to change routes.rb and add the following line for my “entries” controller:

map.connect 'entries/:year/:month',
  :controller => 'entries',
  :action => 'index'

Now when I enter url like ‘entries/2008/1’, I expect the calendar for January 2008 to be shown. I also expect that url ‘entries/1’ still has same effect (displaying entry with id with ‘show’ action). To implement this functionality, I had to add the following code to the controller (in index mehtod):

y = params.include?(:year) ? params[:year].to_i :
  Date.today.year
m = params.include?(:month) ? params[:month].to_i :
  Date.today.month
@display_date = Date.new(y, m, 1)

It creates a Date object whose year and month are either read from the parameters or (if they are not set) initialized from current year and month. In any case we use first day in month. Finally we can add a method in entries helper class which will return options hash for the calendar we want to display.

def calendar_options                                        
  prevd = @display_date - 1
  nextd = @display_date + 31
  {       
    :year => @display_date.year,
    :month => @display_date.month,
    :previous_month_text =>
      link_to("<< Prev",
        :year => prevd.year, :month = > prevd.month),                                               
    :next_month_text =>                                     
      link_to("Next >>",
        :year => nextd.year, :month = > nextd.month),
  }                                                         
end

Now it is easy to crate a calendar in the view itself:

<%=
calendar(calendar_options) do |d|
  # block
end
%>

Monday, March 05, 2007

S5 - XHTML-based PowerPoint alternative

I never hated PowerPoint (nor Impress, speaking of the matter), but today I saw S5 in action.

I recommend watching the slides to everyone interested in web standards, and S5 to everyone who wants to create presentation for which PowerPoint or Impress would be an overkill. Take a look - you'll like it.

Thursday, March 01, 2007

Valid disabled links in ASP.NET

When we published Bunny-Chicken Evil Plots ten days ago I've tried to make it XHTML 1.0 compliant. However I did not succeed at that moment. Control I've created for comic navigation rendered invalid disabled='disabled' attribute for an anchor tag. Not only it is not valid by standards (hence rejected by validator), but has special "dimmed" rendering in IE which cannot be overridden by CSS. At that moment I let it be, thinking it must be me who messed up something, because ASP.NET should be mostly XHTML-compliant.

Last night I decided to make control render valid XHTML and went to look what's wrong. Turns out the source of the problem lies in WebControl and its Enabled property. WebControl is base class for many ASP.NET web controls and should be inherited by custom web controls. One of its main responsibilities is encapsulated in method protected virtual void AddAttributesToRender (HtmlTextWriter writer) which writes "standard" (X)HTML attributes basing on set control properties.

One of that "standard" attributes rendered is 'disabled'. It is rendered if Enabled is set to false (makes sense :)). After some contemplation I've came with the following solution:

protected override void AddAttributesToRender(
    HtmlTextWriter writer)
{
    bool enabled = Enabled;
    Enabled = true;

    base.AddAttributesToRender(writer);

    Enabled = enabled;
    // [ some more code here... ]
}

Idea is to override AddAttributesToRender and before calling method from base class (which you should do if you inherit from WebControl), you enable control. This way disabled attribute won't be set and you are free to customize disabled control as much as you like it. Of course we restore previous value from local variable.

This code is part of AccessibleLinkButton initially created for Web.Comic. Nice thing about the control is that it can post back if JavaScript is enabled, or go to specified URL if JavaScript is disabled or link is middle-clicked (to open in a new tab). Check out how it works at Bunny-Chicken Evil Plots.

Thursday, February 22, 2007

Feature I wish I'd known about before

This morning I woke up (after two hours long sleep), dressed, went to work and suddenly an idea enlightened me. The idea I supposed would change the world from its roots. Well, at least my world.

You see - I love keyboard. Because it's fast. Faster than mouse. Actually it's an ideal input device for me. No way I'd ever have enough time and nerves to explain to the computer what I want to do with voice commands. Mind control may be useful, but for some reason it scares me just to think about it...

That's why I fell in love with Launchy. It's so simple and yet 42 times as much useful. When you press assigned shortcut (ALT+space is default, but I changed it ALT+Esc) launchy displays a simple text box. Just type part of the name of an application/document/bookmark (you choose) which you want to run/open, press enter and Launchy launches it for you. Simple, yet ingenious if you ask me.

Back to the idea, now. I wanted similar feature for Firefox. I wanted an extension in which you could define shortcuts for URLs. After you type shortcut in, say, location bar, you'd be directed to the mapped URL. For example, instead of typing "https://www.google.com/analytics/home/" one could type only "gan" and get to Google Analytics homepage. Would change world from deepest roots, don't you think?

Just moments before I started preparing all the tools I need for building an extension I googled a bit and found that Firefox supports that feature. By default. It's called - keywords.

Right click on any of your bookmarks and type a keyword. After that you can just focus location bar (CTRL+L, of course) and type the keyword. Works like a charm :D

Moral to the story: start googling before you write the code. Speaking of morals check today's joke of the day.