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.

Wednesday, February 15, 2006

New project planning

I'm about to start developing heavy client-based web application. It is meant to be some form of CMS for web-comic relying on client-side JavaScript and PHP as data connector.

I didn't decide yet which technologies/protocols/software I'm going to use, but I had following structure in mind at first:

  • User interface: JavaScript using XMLHttpRequest to obtain data from server;
  • Data transfer protocol: pure XML;
  • Data provider: PHP would be used to read data and prepare results in XML for XHRO;
  • Data store: XML files sound like cheap solution. I think it should be easier to prepare XML output if I only select some elements and redirect them to XHRO.

As more time passes I find more flaws in this design. Some points I've read at "Why does XML suck" just cannot be denied.

Now I think I'd use JSON to transfer data between data connector and JavaScript. I still cannot decide upon data store.

MySQL does seem like logical solution. I have used it many times before, version 5 seems like serious RDBMS with features like stored procedures and data dictionary. Problem is that hosting solutions I'm interested in do not support newer versions (MySQL 4.0.x is most recent I saw) and generally, MySQL database has to be seperately paid for.

Hence, I started to think about SQLite. I've never used it before and don't have any idea about how fast/flexible it is, so I will do some testing.

I tried using embedded Firebird on previous project and liked it. Especially because it has support for stored procedures and many 'advanced RDBMS features' ('advanced RDBMS features' is everything not present in MySQL < 4.1 :D). Unfortunately it would require rebuild of PHP or additional dlls. I doubt I'd get that with shared hosting :(

Maybe I should look for more hosting solutions :)

Tuesday, February 14, 2006

Hello World!

And may the KIMV protect you!