January 2007


While working on stylesheets in an Ajax application, it is often neccessary to reload the page and perform a lot of clicks to check whether your changes had the right effect. Especially filling the same forms the whole day becomes very annoying.

Mr. Clay provides a cross-browser-solution to reload your css with a bookmarklet every 2 seconds. This was a bit to hectic for me, especially since you could not stop it. That is why, I removed the interval and made it a one shot bookmarklet.

I had a tough fight with the wordpress editor, but I lost. Unfortunately I am unable to paste the correct code here. But get the bookmarklet from Mr. Clay and remove the setInterval at the beginning and ,2000 at the end. Additionally the last to )) should become )()). That’ll be it.

Feel free to leave a comment, if you have any problems with this tiny script. There are known issues listed on Steve’s site.

For the communication between client and server in an AJAX environment JSON became a very important part. It is easy to use, to understand and supported from the most important programming languages (if not native like in Javascript, at least there is a framefork provided). Usually one would use the default encoders to translate the objects provided on the one side to data represented using JSON and then again decode to extract the objects.

But in some cases using the usual encoders would not be enough. For these cases Rails provides a very easy framework to plug you own encoders for you own class. The process to achieve that is simple and again easy to understand, but the procedure can leave some obstacles on the road that need to be survived.

The following sample will explain, what can happen and will show a solution to avoid the most problematic JSON CircularReferenceError.

class MyArray < Array
  attr_accessor :providers
end

The above noted class provides a new type of Arrays containing a new attribute to better identify the providers of the array. Using this array in Ruby is now problem, since the runtime will always identify this object correctly. But what about serialization? Here the problem starts. The serialization will not uses the attribute and simply ignore it. So the next step would be to write an own encoder to provied a specific JSON encoding.

module ActiveSupport
  module JSON
    module Encoders
      define_encoder MyArray do | fra |
        myfra = fra.compact
        returning( result = '{' ) do
          i = -1
          result << '"providers": ' << myfra.providers.to_json << ', '
          result << '"length": ' << "#{myfra.size}" << ', '
     
            result << myfra.map do | val |
              [ i += 1, val ].map { |value| value.to_json } * ': '
            end * ', '

          result << '}'
        end

This code provides a simple Encoder for our MyArray class and adds the provider to our data string. Of course on the client side (or the other side), this will not result in an array but more an object that has integers as attributes and the values as values for these attributes. But in Javascript this would feel like an array.

// ...
// data is the variable containing the parsed object fromm our ruby side.
for (var i=0; i < data.length; i++){
  alert(data[i]);
}

for (i=0; i < data.providers.length; i++){
  alert(data.providers[i]);
}

Well, and this is what we wanted to achieve. An user defined array class containing additional attributes to carry additional data. So far, so good. But it is not as simple as it seems. Just imagine the following example that creates an empty instance of MyArray containing an emtpty providers Array. In the beginning everything is fine, but as soon as you want to serialize the instance using our user defined JSON Encoder, we will receive a circular reference error. Before I will explain a solution for our problem let’s have a look on what happens while serializeing. At first for each object a new stack is created, this stack contains all objects that are to be serialized. The reason for this stack is simple: If the object contains an instance of itself, this would result in a circular reference and an endless loop.

But why do we get an circular reference error? We put at first an instance of our MyArray class, and then an instance of an normal Array into the stack list. It looks like there is no circular reference! But there is, or at least for Ruby it looks like there is! To explain, have a look at the following piece of code:

a = MyArray.new
b = Array.new # Or simply []
puts a == b

Actually a == b is what the include? call is doing when recursing the object stack. The result of this piece of code is true. The instance of MyArray has the same == method as Array, they share it. Since Array overwrite the default == method of Object, the result is true. And this is the simple and short reason why we receive a CircularReferenceError message.

To avoid receiving this error, the first and most simple reason would be to define an own == method for MyArray and actually this is the most safe method. Another idea would be to extend the include? method used by the JSON Encoder. Instead of simply calling == for all objects, we could combine this with an instance check.

  # This method is directly taken from Rails json.rb
  def raise_on_circular_reference(value)
          stack = Thread.current[REFERENCE_STACK_VARIABLE] ||= []
          raise CircularReferenceError, 'object references itself' if
            stack.include? value && stack.find {|e| e.instance_of? value.class}
          stack << value
          yield
        ensure
          stack.pop
  end

The include condition is now extended using the stack.find {|e| e.instance_of? value.class} fragment. The circular reference error will only be raised if the referenced stack element is an instance of the current value class.

The second possibility may have side effects of that I am not sure. But I think I will investigate in that direction. If you have any ideas, please tell me!

In the beginning of computer science people or at this time still scientists tried to centralize knowledge, they tried to build systems, that are capable of handling all tasks that will arise in their daily work. Systems like the famous System/360 of IBM where such machines. They began to be really highly complex systems, capable of everything, that we might now from our small PCs under our desk or on our lap today. But these systems had a big disadvantage: their size and handling. Of course they could solve a lot of problems, but nobody really had enough spare room for these big machines, and who could effort the knowledge of administrating such a system? Who ever tried to run a OS/360 even on a virtual machine, knows what I mean. So computers and of course their software evolved. In the already mentioned beginning, we had large monolithic systems. Many users could connect, but still the application logic was bound to one machine or better one system.

The next phase in software development marks the client/server phase. By now developers and system architects tried to separate application logic. Typical UI logic and controls where swapped to external programs. Still the main part of the application logic remained on a single “server” but parts of the workload where put on the client. One of the main advantages by now was, that the clients were strong enough to execute application logic and not only to forward the requests to the server.

But again this client/server principle had a big disadvantage, that software developers and their system architects tried to overcome – Deployment! In the early days only a single machine needed to be maintained, but now may thousands of clients connect to the server and all of them need to follow distinct rules and these rules are defined by the version of the software they are using. The costs for maintaining the installation and monitoring the software now rise extremely fast with the number of clients connecting to the whole system.

Besides the software evolution from monolithic to scattered architectures the network topology changed as well. Not only in big industries, but for almost everyone. The cost for network bandwidth to connect to a service was and is constantly falling. As a result, the cost to transmit more data became cheaper and opened up the way for another architectural principal. Well, let’s say another interpretation of an old one. The Thin Client idea is not really new, but it changed dramatically. Of course the original idea of saving IT costs remained but in a different way for developing Web Clients.

The first overwhelming advantage of web clients is, that by now they can be deployed without any effort on almost every computer worldwide. On every computer some kind of a browser is already installed. The communication protocol exists and tends to be some kind of stable and is widely accepted. The user interface language is specified and accepted as well. So only the back-end and the application logic needs to be developed. Deployment is now almost for free available. And applications cannot only be deployed to internal clients, but using the Internet and maybe secured connections, the dream of a home office can come true.

Ok, this was a nice summary of application development of the past 40 years until the beginning of the magical Web 2.0. Web 2.0 revealed patterns and principles, that seemed to be banned from the world wide web during the Internet revolution in the end of the 20th century. Things like Cookies – do you remember all the advices to not to allow them? Languages like Javascript! Always seemed to be an ugly mistake, but now? Look at it! Do you now a site that does not use Javascript?

But that is not the point the I want to state. Web 2.0 had a revolutionary impact on the software development industry. It made the thin rich client possible!

The what? Yeah, you are right the Thin Rich Client – something that you ever missed! Two of the main advantages of thin clients are the low deployment and IT costs, one of the main drawbacks is the high server load. The money you save using thin clients, you will have to invest into new iron to beat the enemy with! And what do you save in the end? Not enough, isn’t it?

Now let’s have a look at a typical Thin Rich Client application – Google Mail. Almost every one knows it (well from the Geek point of view) and most of the people love the ease of use and smoothness of the application. It feels like a real desktop application but is only a web appliction. But did you ever asked how does it work? It uses lot’s of Javascript to achieve that! Javascript – isn’t that the language to hack my PC down? No! Javascript became a very usable language, a language that makes fast processing of information available to browsers and so to your PC. Using asynchronous HTTP request (the mythical AJAX) we can even reload data without reloading the page!

As a result we can start building rich client applications using Javascript and use automatic deployment mechanisms to deploy them right on your computer using standardized protocols, no more version problems. It just works! We will reduce the server load since, the client is able to process information. Part of the application logic can again be extracted to the clients but still use all the advantages of a web client. We have to change the way we look at Javascript and use the advantages provided by it.

Using Javascript to build Thin Rich Clients can really save money from my point of view. For large companies or large scale web applications thin rich clients can be a serious alternative to new servers. Furthermore thin rich clients allow new UI paradigms, that make web applications feel like desktop applications and so better meet the user expectations.

Examples like GMail, Google Spreadsheet and Flickr are only the beginning of a new type of web applications and we will have to use a new term for it – Thin Rich Clients.

I just read, that the new prototype release is out by now – version 1.5. Since it was very hard to follow the development of prototype for quite a long time, the developer group made a complete rebirth for prototype. By now they provide a complete API documentation, some tutorials and whats left in the world of web 2.0? Of course, a blog.

To hava a closer look on what has changed go for the CHANGELOG.

Since prototype is the JavaScript framework of my choice, the only thing, that I can say is – check it out!

To avoid information overload on a website, information is splitted and scattered. So it becomes really hard to display all information needed on a single place. To help the designer to make information available pop-ups can be used. But nobody really wants windows out of websites. So SiteWindow is the alternative. It allows to display an window within the window. It is highly customizable and easy to extend. One of its biggest advantages is the possibility to react on events triggered within the window directly in your website.

You need the right information, on time and on the spot? Use SiteWindow!

Have a look at this source sample:

var w = new SiteWindow();
w.setTitle("Title");
w.setContent(document.createTextNode("Lorem ipsum milanum com ..."));
Event.observe($("1"), "click", function(e){w.show(); Event.stop(e);});

Want to try? Download now – SiteWindow!

Everybody, who has ever tried, knows how difficult it is to design fluid layouts. Designers and others don’t make it easier. But todays computers do not allow to ignore the screen size and deliver just one fixed layout. The minimum would be to build two or three static sizes:

  1. one for mobile devices: something about 300px in width, but this is just a guess. iPhone might improve this issue.
  2. one for regular screens – 1024 x 768. Works on small (widescreen) notebooks and most other elderly monitors
  3. one for the large ones, that never heard of leaving the full screen. We decided to go for 1280 x 1024

This leads to the problem, that graphics have to scale to certain sizes, margins and paddings should grow and the font-size has to be reviewed. One could argue, that just a redefinion of the font size within the body should be sufficent. But nobody wants to enlarge every tiny bit.

So you have to deliver different stylesheets for every supported size. While there are several possibilties, they all have certain drawbacks.

  1. Separate the different css files completely: While writing the styles, this comes handy, you have all definitions that influence the view at hand. No side effects,you didn’t recognize. But when maintaining the code, adding new UI elements, this becomes dirty. You will inevitably loose changes in the one or the other way and you have to synchronize the styles manually.
  2. Have a default style sheet and redefine the changes in another one: This solves the synchronizing issue, mainly. But the definition of the derived style gets pretty difficult. There is no way to recognize unintended side effects, when editing the default style.
  3. Have a basic style sheet and define the size-related statements in other files: What should that be good for, except bandwidth concerns.
  4. and finally: Define everything in place, use one stylesheet to rule them all. Introduce variables to compute the needed sizes or add control structures to get the correct results.

But wait – there is no such thing like variables or control structures in Cascading Stylesheets. But they are there in Ruby and in Erb, so why shouldn’t we combine them, as we do in HTML?

Rails makes everything handy from now on. Others ( Dirt simple .rcss templates, Dynamic CSS in Ruby on Rails) have already described, how to add rcss to your Rails environment. There is even a Gem at Rubyforge, which may be included easily. We have made our own contribution, specific to our needs.

Building rcss templates in Rails

Add the following to your config/routes.rb

map.connect 'rcss/:rcss', :controller => 'rcss', :action => 'dispatch'

In Rails 1.2.1 which has been released recently, the configuration of Routes as been changed significantly. It is said to be more powerful and faster. For our configuration we need only small changes. Add the following line if you are using the lastest Rails:

map.connect 'rcss/:rcss.:format', :controller => 'rcss', :action => 'dispatch'

Generate a controller to handle your generated stylesheets.

script/generate controller rcss

And fill it with contents.

class RcssController < ApplicationController
  layout nil
  session :off

  def dispatch
    if rcss = params[:rcss] and
       action_name = rcss.gsub(/\.r?css$/i, '').to_sym and
       respond_to?( action_name )
        file_path = send( action_name )
        render :file => file_path, :content_type => "text/css"
    else
      render(:nothing => true, :status => 404)
    end
  end

For every style sheet you would like to use with your HTML add a method named after it. So style.css or style.rcss if you like would become

  def style
    @custom_variable = true # May be used within the style sheet
    "#{RAILS_ROOT}/app/views/rcss/style.rcss"
  end

with the corresponding rcss template

<% if @custom_variable %>
   body * { background-color: green; } 
<% else %>
   body * { background-color: yellow; } 
<% end %>

Now you are able to keep all the definitions in one place. You may recognize all dependencies and react correctly.

Further topics:

  1. What does that mean for caching?
  2. How do we activate the different styles on the client side to adopt to different screen resolutions?