zargony.com

// Struggling through Ruby on Rails, iOS and Linux

Google Charts on your site, the unobtrusive way

For a recent project, I needed to visualize some simple backend database statistics to admin users. Nothing exciting, just some simple numbers like count of subscriptions and purchases per day and such. When I started to work on some simple stats calculations, I already had in mind that I want to display the result in nice charts rather than in boring tables with numbers. And I wanted nice, interactive HTML 5 charts that display with almost no load time and fetch their data to display with Ajax.

There are several libraries that offer you to display charts in various ways like generating images to display or embedding Flash objects (yieks) into your page. Nowadays you surely want to use a library that displays interactive charts using Javascript and HTML5 though. In Railscast #223, there’s a nice tutorial how to use a few libraries.

However, I ended up using Google’s free chart service Google Charts, paired with unobtrusive Javascript using jQuery. Here’s how I did it:

Read more...

Rails I18N core translation updater and CSS naked plugin as gems

It has been quite a while that I created these two Rails plugins, but they still serve their purpose without problems even in newer applications. Since Rails plugins as a gem are much easier to maintain, I took some time to move these two plugins to gems. This makes them even more easy to use and especially more maintainable.

I’m talking about rails-i18n-updater, a plugin that merges and manages Rails core translations in your application — a helper that I don’t want to miss in any i18n-enabled application anymore. And css_naked, a simple plugin that disables all stylesheets during the CSS naked day event once a year.

Both plugins are ready for Rails 3 and work well with Ruby 1.9, btw.

Rails I18n updater

The rails-i18n-updater plugin does two things to an application. First, it adds a rake task called i18n:update to your applications. This task can be called to download the most current translation files for the Rails core. Second, it prepends these translation files to the I18n load path at runtime.

This means, that you don’t have to fiddle with Rails core translations anymore in your application. Things like date formats, weekday names, month names, time distances in words and ActiveRecord validation error messages are translated for you — and moreover updating them is as easy as calling rake i18n:update. Because the downloaded translations are prepended to your load path, you’re still free to override them in your own locale files.

This seems simple, but becomes really useful if you don’t want to do every core translation yourself and don’t want to manually merge core translation updates. To use the rails-i18n-updater plugin as a gem, just add gem 'rails-i18n-updater' to your application’s Gemfile (environments.rb for Rails 2).

rails-i18n-updater plugin: RubyGems Github

CSS naked

css_naked is a very simple plugin that just disables the stylesheet_include_tag helper during the CSS Naked Day event each year. Installing and using it is now as easy as adding gem 'css_naked' to an application’s Gemfile (environments.rb for Rails 2).

css_naked plugin: RubyGems Github

A Rails plugin to use core translations

If you’re writing an i18n-enabled Rails application, you have to deal with the translation of your own application as well as with the translation of several Rails core strings (like validation error messages, date formats, and so on). You usually don’t need to translate the Rails core strings yourself, since there’s a big repository of user-contributed core translations you can pull into your application. However keeping this translations up to date in your application can quickly become cumbersome.

For this reason, I refactored the rails-i18n(*) repository a while ago and made it a Rails plugin. You could install the plugin to your application and it provided Rails core translations for you. Unfortunately it became annoying to keep the fork up to date with the latest translation changes since every rebase or merge was a pain because of the moved file locations.

So my latest solution is another small plugin called rails-i18n-updater, which does not contain the translations itself but downloads them from the above mentioned repository of core translations.

Read more...

Ruby 1.9 and file encodings

Just out of curiosity, I took two of my recent Rails applications today and tried them with Ruby 1.9. It was surprisingly easy to make all tests pass without any warnings or errors. Rails 2.3 already has quite good support for Ruby 1.9. The main gotcha however was about file encodings. If you have source files which contain non-ASCII characters, Ruby 1.9 now needs to know which encoding the file was saved with. If you don’t specify the encoding for a file with non-ASCII characters, you’ll get an invalid multibyte char (US-ASCII) error message.

Read more...

Routing parameters with a dot

Last week I received an interesting bug report for an application I’m working on at the office. It has a controller with an index action that displays a list of items which can be filtered by tags. A tester reported that every time he chooses to filter the list by a tag that contains a dot, the site returns an error. First this seems strange since tags with a dot worked perfectly fine in tests.

But after digging deeper, I found a surprising reason for this strange error: To make URLs look nicer, I defined an extra route like this:

map.things 'things/:tag', :controller => 'things', :action => 'index',
  :tag => nil

The intention was, to have /things/foo instead of /things&tag=foo as the URL. This actually worked fine – except for cases when the tag contained a dot.

Read more...

Testing Cookies in Rails 2.3

While moving some applications to Rails 2.3 recently, I stumbled across some problems with testing cookies. E.g. this blog uses cookies to remember your name, email address and web url if you leave a comment. This way, you don’t need to re-enter these information the next time you leave a comment. These cookies are set by the controller action that creates new comments (in CommentsController#create):

cookies['blog_visitor_name'] = { :value => @comment.name, :expires => 1.year.from_now }

This is the extended form of setting a cookie (a hash is used to not only set the cookies value but also the expiration time). There are several more hash options available which are described in the ActionController#cookies documentation. The basic form (which only sets a simple session cookie that is valid until the visitor closes the browser) uses a simple string:

Read more...

CSS Naked Day 2009: a Rails plugin

On April 9th 2009, the fourth CSS Naked Day event will take place. The idea behind this event is to promote web standards (like proper semantic markup and a good hierarchy structure). On April 9th, participants are encouraged to completely remove all stylesheets from their site, stripping it entirely of its design. If your site has proper semantic markup, it’ll stay well usable and understandable even without styles. If not, you better hide and don’t take part in this event :)

To make it as easy as possible, I created a little Rails plugin that, once installed to an app, simply disables the stylesheet_link_tag helper for the duration of the event. It’s as easy as install and forget (assuming that you used stylesheet_link_tag in your layouts and didn’t add inline styles or stylesheet links manually).

So let’s see how many sites will join this funny but yet expressive event this year. It’s time to show off your <body> ;-)

Let browsers cache static files to greatly speed up your site

There are many factors that determine how long a page takes to show up in a browser. When a page is requested by a browser, the server needs some time to compute the page contents (controller, model/database, view) and returns HTML to the browser. Besides network latency and throughput (which can be optimized by choosing a good hosting provider), there are several ways to speed up the page generation itself (like memoization, action/fragment/query-caching, using memcached, and so on).

But even after the HTML page itself has been transferred to the browser, the page is not necessarily ready to display yet. A page usually references more resources like stylesheets, javascripts and images that need to be requested and transferred. These are mostly static files (located in the public folder of a Rails application) and are directly served by the webserver without invoking the Rails application. So these files takes very little computation time on the server, but they still need some time and bandwith to transfer, which can be optimized.

Read more...

Selecting the locale for a request

Rails I18N gives you a way to translate your views and easily switch between different languages. However, you still need to set the locale for each request, i.e. you have to choose a method to select the right locale for a request. This can be done in various ways, depending on how you perfer it to behave. Here are some examples.

  1. by browser-setting
  2. by toplevel domain
  3. by subdomain
  4. by manual selection

Read more...

Email address scrambling methods compared

A while ago, I wrote about different methods in JavaScript to prevent spam harvesters from recognizing an email address. These methods work by placing a scrambled version of the email address into the page source so that a spam harvester cannot recognize it as an email address. Using JavaScript, the scrambled text is unscrambled and displayed as usual to human visitors. Usually, the “scrambling” is based on replacing characters of the email address with its hex-entities (Rails’ mail_to helper does so if using :encode => :hex or :encode => :javascript). My theory was/is, that using hex-entities is not sufficient anymore nowadays, since they can be easily reversed with simple search-and-replace operations.

So I came up with the idea to use a scrambling method that cannot be easily reversed. I assumed that spam harvesters probably can decode hex-entities, but still aren’t able to execute JavaScript. However since this was just an assumption, I started a simple test over the last 6 months to find out how good or bad the different scrambling methods perform.

Read more...