jlaine.net

Mikontalolights

What would a bunch of geeks do while their dorm highrise is under renovation? Build the world’s biggest LED screen, of course.

Photo by StaneStane

One of the most infamous student dorm houses in my hometown and whole Finland, Mikontalo, is finally put under hammer and renovated to meet the standards of the third millennium. While the construction work is underway, a bunch of TUT geeks decided to get something more out of the works:

The object of MIKONTALOLIGHTS is to create the world’s physically largest colored graphics platform by using the windows of Mikontalo’s D-staircase as light pixels. The platform is used to play Tetris and other games and present demos created by the students of Tampere University of Technology.

Here’s a video of the grand opening, including rounds of Space Invaders and Tetris (controlled with a mobile phone, of course). Times Square, beware!

Leopard Terminal Doesn’t Like ProFont

My clear favorite among monospaced fonts has so far been ProFont, 9pt with no antialiasing. I don’t think antialiasing works well for small type and I have yet to see as clear and crisp a font as ProFont. However… this is what a terminal window looks like after I updated to Leopard:

Leopard Terminal fucks royally up strings with slashes with ProFont

Not cool. Here’s exactly the same window after switching the font to Bitstream Vera Sans Mono:

In Vera Sans Mono everything's fine

Also not cool because of the ugliness but at least all the characters are shown. Anyone got an idea what’s happening with ProFont? Everything worked just pristine in Terminal in Tiger, and still does if I run iTerm.

[UPDATE, Dec 3 2007]

I played around with the different ProFont distributions a bit, and the only one that doesn’t break as above is the bitmap ATM version of the font. However, as you can see it’s just plain ugly with small text size (notice the pixelated k, : and ~).

Letting the Users Choose

My friend Martin just posted a case study on Working With Rails about how Oakley has been migrating their web presence onto Rails. I’m a big fan of Oakley products. They’re a company that puts an enormous effort to make seemingly simple products better and better. In orienteering, where you really need some shield for your eyes (unlike in, say, pole vault), glasses with replaceable lenses with different colors for different weather conditions are a must. I’ve been using the M Frames for a couple of seasons, and refill my lens stock pretty much every time I visit US.

Martin’s interview with Ken Loh – the guy running the web group at Oakley – reveals an interesting point. The guys who actually build their apps got to choose the platform themselves. This is not too surprising for an innovative company such as Oakley, but it does show a clear contrast to the big E word, something Khoi Vinh and Jason Fried have lately talked about:

The people who buy enterprise software aren’t the people who use enterprise software. That’s where the disconnect begins. And it pulls and pulls and pulls until the user experience is split from the buying experience so severely that the software vendors are building for the buyers, not the users. The experience takes a back seat to the feature list, future promises, and buzz words.

(Jason Fried: Why Enterprise Software Sucks)

Gartner Wisdom

In a Computerworld article telling about Steve Jobs and Apple fighting iPhone unlocking (emphasis mine):

Carolina Milanesi, a Gartner Inc. analyst who was at the London presentation, said she wondered if it matters much in the long run whether Apple stays a step ahead of hackers, as Jobs said it must do. “At the moment, as a consumer, you need to be very careful about unlocking the iPhone, and know how you want to use it,” she said. “If you unlock it, you are not going to have a flat rate, and you will not have access to the 7,500 hot spots.”

Huh? A 384Kbps (much more than iPhone can handle) flat rate plan runs around €10/month in Finland. And you have access to each and every wifi hotspot in the world with iPhone.

“If you unlock and then use the Internet and e-mail, you may be surprised€r first bill,” she added, referring to the pay-as-you-go data rates charged by most carriers in the country and elsewhere in Europe.

What the fsck does that have to do with iPhone? You pay what and how you pay regardless of the phone. You probably know what your existing contract charges for data if you’re contemplating buying and unlocking an iPhone.

iPhone vs. Nokia E90 Communicator

(photos by Blackhorn and DanieVDM)

The arrival to the second installment of RailsConf Europe – this time in Berlin – meant even more for me than hanging around with friends from all over the world. It also meant the first time I was able to hold an iPhone in my own hands.

See, about the same time people in US got their hands on the first iPhones, I also got a new phone, a Nokia E90 Communicator. The situation in Finland with the Communicators was almost the same as the one in US with iPhones, it was almost impossible to get one. I was lucky enough to get one in about a week, as a part of a 24-month contract. Here’s the first-quarter report about my experiences.

First things first. E90 is a pretty impressive device. With full keyboard, Wifi, 3.5G, GPS and dual screens (of which the larger one is really good) there’s hardly anything more you could hope. But that’s just on paper. Much more important to me is how useful the phone is in day-to-day use.

The browser (which uses webkit) is fairly good, certainly one of the best in the mobile world. However, the lack of a “real” mouse makes some things really hard, one of the most annoying being the fact that you can’t scroll an iframe or a div with overflow: scroll. There is no notion of dragging.

One of the most disappointing aspects is the general coherence of Symbian, which unfortunately came as no surprise. Used to OS X, I just don’t find Symbian stable or slick enough. One example of that is the selection of a Wifi network. In theory, you click the web button, select a Wifi or 3G network and continue to the browser. In practice, about half the time you just end up back to the desktop after selecting the network.

A thing that I was really disappointed by was the GPS. I’m not quite sure if it’s just my device or if it’s a “feature”, but it just takes too long for the device to find itself on the map and there’s no real feedback on what’s happening. All the UI says is that there’s no GPS available, even though in reality it’s negotiating with the satellites all the time. If you’re moving at the same time, the phone won’t ever be able to locate itself. Therefore, the GPS function has so far been totally useless for me.

Now that I got to use an iPhone in real life, I can say the two UI’s are like from different planets. It’s nice to hear that Nokia and others are coming out with touch screen phones, but I wonder if they ever get it when it comes to usability. Symbian in E90 doesn’t really reassure me in that regard.

Would I swap my omnipotent Nokia for a device using years-old phone technology? In a heartbeat. While the E90 is really nice and all, it’s an epitome of feature list competition where the more buzzwords your feature list contains, the better your phone is. And while getting 3.5G speeds is really cool, the coverage is still so bad around Finland that just having Edge for a while (until the 3G iPhone comes out) wouldn’t be too bad.

It kind of hurts me to say this as a Finn, but at the moment it seems that a newcomer in the mobile phone market has beaten the current leader pretty badly. For the customer and the market in general, that’s all but certainly a good thing.

Making Globalize Play Nice With Specs

We’re using Globalize for our latest Rails project and I just ran against a problem when running specs with rake.

We specify the base language and the locales our app supports in environment.rb:

include Globalize
Locale.set_base_language('en-US')
SupportedLocales.define(['fi-FI', 'sv-SE', 'en-US'], 'en-US')

However, SupportedLocales.define expects that the language and country data exists in the database, otherwise it will die miserably. Of course, when you run specs with rake, it will wipe the database as its first action so you’re pretty much out of luck:

.../vendor/plugins/globalize/lib/globalize/localization/supported_locales.rb:282:in `setup': Globalize base language undefined! (RuntimeError)

I fixed this by copying the db:test:clone rake task from [RAILS]/railties/lib/tasks/databases.rake to its own file in lib/tasks and modifying it so that it will load some language and country fixtures automatically:

require(File.join(RAILS_ROOT, 'vendor', 'rails', 'activerecord', 'lib', 'active_record', 'fixtures'))

namespace :db do
  namespace :test do
    desc "Recreate the test database from the current environment's database schema"
    task :clone => %w(db:schema:dump db:test:purge) do
      ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
      ActiveRecord::Schema.verbose = false
      Rake::Task["db:schema:load"].invoke
      Fixtures.create_fixtures("#{RAILS_ROOT}/spec/fixtures", [:globalize_countries, :globalize_languages])
    end
  end
end

The only thing differing from the original task is the last line creating the fixtures. For some reasons I also need to explicitly require the fixtures file on the top of the file. Aside from this, I needed to change Rakefile in the root of our Rails app to require config/environment.rb instead of config/boot.rb for everything to work.

Of course your fixture files need to include all the languages and countries you’re specifying in your SupportedLocales.define call.

After these modifications, rake runs through fine again.

Langaton Tampere

It seems that my wee hometown is getting a citizen wireless network (only in Finnish, unfortunately), based on sharing your own wifi and getting free access to the network using other people’s access points in exchange. Pretty cool, especially since it’s opening already this month and I didn’t even know about it.

(via Kalamuki)

From Rails Ajax Helpers to Low Pro, Part 2

See also: Part 3

In the first part of this series, we had a look at how we have evolved from using the standard Rails Javascript helpers to first use the UJS for Rails plugin and then to use Low Pro on its own.

However, there’s not much documentation about Low Pro yet. In this article, we’ll introduce Low Pro to you by taking a heavily Ajax-driven, fairly inaccessible Rails page and transforming it to an accessible, unobtrusive one.

We start with a simple todo list application that uses the traditional Rails Javascript helpers. You can download the original application from here.

Todo list app

The index page of the items controller is very simple:

<% form_for :item, :url => items_path do |f| %>

<h3>
  Not done:
</h3>

<ul id="undone">
  <%= render :partial => "item", :collection => @not_done %>
</ul>

<h3>
  Done:
</h3>

<ul id="done">
  <%= render :partial => "item", :collection => @done %>
</ul>

<% end %>

<p>
  <%= link_to_function "Add new item", "$('add_form').toggle()" %>
</p>

<% remote_form_for :item, @new_item, :url => items_path,
   :html => {:id => "add_form", :style => "display: none;"} do |f| %>
  New item:
  <%= f.text_field :description %>
  <input type="submit" value="Add item">
<% end %>

We’ll take a closer look at the partials later, but let’s begin with the lower part of the page. There are two kinds of Rails JS helpers used. First, the link_to_function to implement toggling the visibility of the form for adding new items, and second, the remote_form_for for the actual form.

This is how the source looks to a browser:

<p>
  <a href="#" onclick="$('add_form').toggle(); return false;">Add new item</a>
</p>

<form action="/items" id="add_form" method="post" onsubmit="new
  Ajax.Request('/items', {asynchronous:true, evalScripts:true,
  parameters:Form.serialize(this)}); return false;" style="display: none;">
  New item:
  <input id="item_description" name="item[description]" size="30" type="text" />

  <input type="submit" value="Add item">
</form>

Above, the anchor tag is both inaccessible and obtrusive. Without Javascript support, nothing happens when you click the resulting link. The Javascript behaviour is also placed right into the tag.

The form tag has a normal action attribute, so it’s perfectly accessible, as long as the backend supports receiving the form submit without XmlHttpRequest. However, the tag is at least as obtrusive as the link, having the whole Ajax.Request call in the onsubmit event handler.

Let’s now make the parts accessible, starting with the link. First of all, we’ll want to make sure the link works even without Javascript. For that, we’ll modify the helper call to just use the normal link_to.

<%= link_to "Add new item", new_item_path %>

If we now click the link, it will bring us… nowhere. We don’t have a new action in our controller. Let’s create a template (new.rhtml) for it real quick. We don’t even need to add the action to the controller:

<%= render :partial => "form" %>

We already have the form in the index template, so let’s move it to the partial (_form.rhtml) from there…

<% remote_form_for :item, @new_item, :url => items_path, :html => {:id => "add_form", :style => "display: none;"} do |f| %>
  New item:
  <%= f.text_field :description %>
  <input type="submit" value="Add item">
<% end %>

…and replace it in index.rhtml with a similar render call we just added to new.rhtml.

If we now click the link again, we get to the new page and see…still nothing. It’s because the form is invisible. We don’t want that, so let’s remove the style attribute from the form partial. We also don’t want the form to be a remote form by default anymore, it wouldn’t work well within the separate new page:

<% form_for :item, @new_item, :url => items_path, :html => {:id => "add_form"} do |f| %>
  New item:
  <%= f.text_field :description %>
  <input type="submit" value="Add item">
<% end %>

We can try to create a new item now but we’ll get some weird stuff back. Our create action only has an RJS template so far. Let’s change the create action in items_controller.rb a bit so that it redirects in case of normal http request:

respond_to do |wants|
  wants.html do
    redirect_to items_path
  end
  wants.js
end

Now creating new items from the new action should work fine.

Progressive Enhancement

We have now ensured that adding items works without Javascript and can thus start the progressive enhancement phase. For it, we need the Low Pro javascript library.

Check the code out somewhere on your hard drive:

svn co http://svn.danwebb.net/external/lowpro/trunk lowpro

And copy the dist/lowpro.js and the behaviours subfolder to your app folder

cp dist/lowpro.js behaviours/*.js [path to your app]/public/javascripts/

We also need to update prototype to it’s latest version. Download http://prototypejs.org/assets/2007/6/20/prototype.js and replace the prototype.js in your app with it.

Now you need to load all the needed Javascripts in the layout file (app/views/layouts/items.rhtml):

<%= javascript_include_tag :defaults, 'lowpro', 'remote' %>

We also need a way to pass certain javascript includes for specific pages. We can do this by using the content_for mechanism in Rails. Put the following into the head of your layout template:

<%= yield :javascript %>

Then add the following to your index.rhtml template

<% content_for :javascript do %>
  <%= javascript_include_tag "items_index" %>
<% end %>

This makes the index action to load the Javascript file that is particular to it:

<script src="/javascripts/items_index.js" type="text/javascript"></script>

Now create the items_index.js file in your app’s public/javascripts folder and we’re ready to roll!

We’re using the excellent Event.addBehaviour method in Low Pro to attach behaviours to elements on our page. First of all, we want the form to be hidden when the page loads (remember we removed the css attribute from the element a few lines ago). This makes sure that users who have CSS working but Javascript not can still see the form.

Event.addBehavior({
  '#add_form' : function() {
    this.hide();
  }
});

Here, we target the form element by its id and then attach a function to it hiding the form. Note that addBehaviour always passes the actual element to the function as this, so it’s easy to call methods for that element directly.

Next, we want to make clicking the “Add new item” link to show the form. We need to first add an id to the link and then attach a behaviour to its click event.

<%= link_to "Add new item", new_item_path, :id => "add_new_link" %>
Event.addBehavior({
  '#add_form' : function() {
    this.hide();
  },
  '#add_new_link:click' : function() {
    $('add_form').toggle();
    return false;
  }
});

Note how the actual event is separated by a colon from the element id reference. The same way works for all Javascript events, such as submit, focus and blur.

We must remember to make the attached function return false in the end, otherwise browsers will follow through the link (just like would happen if the code was inside an onclick inline event handler).

Ok, our link is now both accessible and unobtrusive. For Javascipt-handicapped it works as a normal link, and for the majority of the users it shows the form inline on the current page.

Next thing to do is to make the form Ajax’ed again by Hijacking it, in Jeremy Keith’s terms.

Event.addBehavior({
  '#add_form' : function() {
    this.hide();
  },
  '#add_new_link:click' : function() {
    $('add_form').toggle();
    return false;
  },
  '#add_form' : Remote.Form
});

Hold it! What’s that? We’re not attaching a function to the element anymore. Remote.Form is a Low Pro behaviour class, a fairly recent addition in the library. Behaviour classes can be used to encapsulate common behaviour that you would put into an attached function inside addBehaviour. Remote.Form and Remote.Link are good examples of behaviour that is pretty much the same all the time. They will automatically hijack a form or link respectively, and make them use Ajax. We could specify a bunch of attributes to the calls, but most of the time they just work, getting all the needed info from the actual form and a elements.

However, we now have one problem. Since we’re attaching another behaviour to #add_form already, the latter will override the first one and the form is not hidden on the page. We could overcome this by writing our own behaviour class. However, we will take a short cut here and hide the form when the body is loaded, instead:

Event.addBehavior({
  'body' : function() {
    $('add_form').hide();
  },
  '#add_new_link:click' : function() {
    $('add_form').toggle();
    return false;
  },
  '#add_form' : Remote.Form
});

Ta-da! Our link and form now work just like they did in the beginning. However, now the code works even when JS is turned off. The produced HTML now looks like this:

<p>
  <a href="/items/new" id="add_new_link">Add new item</a>
</p>

<form action="/items" id="add_form" method="post">
New item:
<input id="item_description" name="item[description]" size="30" type="text" />
<input type="submit" value="Add item">
</form>

Isn’t that just beautiful?

This is a good time to have a short break and digest what you’ve learned so far. In the next installment, we’ll tackle the select box lists of todo items and see how you can unobtrusively attach behaviours to multiple elements with very small amount of code.

Now, continue to the next part of the series.

From Rails Ajax Helpers to Low Pro, Part I

[UPDATE] Links to the latter parts of the series:

In a recent Ruby on Rails podcast interview, Dan Webb stated he’d rather see the Javascript and Ajax helpers removed from the Rails core. What was the reason a prominent Rails figure like Dan holds such a radical view on the helpers?

When Rails was young and only gaining popularity, its ability to help in quickly building Ajax-equipped web applications was one of the biggest selling points for the framework. In this, helpers such as link_to_remote and remote_form_tag played a big role. However, there are two problems looming with the Rails helpers. While the helpers did manage to make writing Ajax applications as easy as not to, they also made it very easy to fall into the two major culprits of Javascript development: writing inaccessible web applications and obtrusive JS code.

Accessibility

Accessibility in the scope of Javascript can be capped with a single sentence: Can users use the web page if Javascript is not working in their browser? For the longest amount of time, Javascript was considered synonymous to inaccessible web sites. It took a lot of evangelizing (including a book by Jeremy Keith) to convince people that peppering your pages with Javascript doesn’t inherently mean they’re inaccessible.

The technique to create sites that worked both with and without Javascript was originally called graceful degradation. The page would degrade gracefully to a less advanced one if Javascript wasn’t enabled in the browser. However, people weren’t happy with the success of graceful degradation in the larger web design circles. Therefore the strategy was basically reversed and the newcomer was labeled Progressive enhancement. The idea behind progressive enhancement is that you first build the basic functionality of the page that is available to all users, and only after that build more advanced features on that foundation.

Code produced by Rails Javascript helpers isn’t necessarily inaccessible. remote_form_tag sets the action of the form tag to the same url as the target of the Ajax call, so even if the browser doesn’t support Javascript, the form should work fine:

<form action="/items" id="add_form" method="post" 
onsubmit="new Ajax.Request('/items', {asynchronous:true, 
  evalScripts:true, parameters:Form.serialize(this)}); 
  return false;" 
style="display: none;">

Even link_to_remote and link_to_function give you the option to specify the href attribute manually and thus make the link accessible:

<%= link_to_function "Add new item", 
    "$('add_form').toggle()", :href => "/foo" %>

➥

<a href="/foo" 
   onclick="$('add_form').toggle(); return false;">
  Add new item
</a>

However, the problem is that by default the href attribute is set to “#” (which leads nowhere), which provides an easy way to the developer to cut corners and leave the Javascript-disabled out in the cold:

<%= link_to_function "Add new item", 
    "$('add_form').toggle()" %>

➥

<a href="#" onclick="$('add_form').toggle(); return false;">
  Add new item
</a>

Not surprisingly, many if not most Rails developers take the easy way out and just go with the default.

Obtrusiveness

Web evangelists have for long touted the wonders of separating the structure and presentation of web pages by using semantic HTML for structure and CSS stylesheets for styling the presentation. There is, however, a third part belonging to that separation equation, the behaviour. Behaviour is what Javascript is taking care of in web sites.

The separation of concerns is nothing new in the software world, and is fairly far even in the case of CSS. However, many still cobble their HTML views up with smaller or (more often) larger chunks of Javascript. This kind of Javascript usage is called obtrusive.

In unobtrusive Javascript, the HTML view should be left clean of Javascript. Instead, the elements are given id and class attributes that can then be used in separate Javascript files to attach behaviour to the elements. Consider the following bit of code:

<a href="/foo" 
   onclick="$('add_form').toggle(); return false;">
  Add new item
</a>

Using Low Pro, this could easily be made unobtrusive:

HTML file

<a href="/foo" id="add_item_link">
  Add new item
</a>

Javascript file

Event.addBehavior({
  '#add_new_link:click' : function() {
    $('add_form').toggle();
    return false;
  }
});

This not only makes the code cleaner and puts the behaviour code where it should be, it also makes it a lot more natural to begin by making the pure-HTML version work before starting to attach behaviours to it.

The path to enlightenment

Ever since the beginning of Ajax support in Rails, people wanted a way to make their apps more accessible (read the comments in my post Using Rails AJAX helpers to create safe state-changing links for discussion about making the href attribute default to the url given to link_to_remote) and unobtrusive.

In 2006 Dan Webb and Luke Redpath came out with the Unobtrusive Javascript for Rails plugin. The plugin did a bunch of things:

  • It modified the Rails Ajax helpers so that they won’t just add inline event handlers to the HTML code but instead add a dom id to the element (if one didn’t already exist) and attach an event to the element in an external Javascript file that is created and cached on the fly.
  • It added a helper called apply_behaviour that you could use to attach behaviour to elements by hand, using either pure Javascript or the domain-specific Ruby language familiar from the RJS templates. The helper used a CSS3 selector-like syntax (also familiar from the $$ prototype method and assert_select Rails test assertion) to select to which elements certain behaviours should be attached.
<% apply_behaviour "#add_item_link:click", "alert('Foo clicked!')" %>
  
<% apply_behaviour "#another_link:click" do |page|
    page.alert "Ah, you clicked me again"
  end %>
  • It added a couple of helpers to be used with apply_behaviour to call the most common prototype and script.aculo.us effects:
<% apply_behaviour "#sort_list", make_sortable %>

<% apply_behaviour ".ajax_link", make_remote_link %>

Under the hood of the plugin was Dan’s Low Pro Javascript library, a light set of Javascript that makes it easier to produce accessible and unobtrusive Javascript using prototype and script.aculo.us. Low Pro introduced a few additions to the prototype element accessor methods (many of which have later been brought into prototype itself), a DOM builder, and, most important, event handling code that include declarative behaviours:

Event.addBehavior({
  'a.todo:click' : Link.Remote,
  'div.feature:mouseover' : function(e) {
    this.hide();
  }
});

As you can see, the first part of the elements in the array is the same kind of selector used in apply_behaviour — actually apply_behaviour builds this kind of Javascript calls from the Ruby code it receives. After the colon you specify either a function to be called upon the event or a behaviour class to be used (we will talk more about them in part 2). With addBehaviour, you “hijack” the basic functionality of the page and spice it with more advanced behaviour that wouldn’t be possible without Javascript.

While UJS was (and still is) a great step forward in making Javascript in Rails apps more unobtrusive – we still use it heavily on dotherightthing.com – it also has it problems. My biggest gripe with it is that while the produced HTML is clean of any Javascript, the apply_behaviour calls were still in the view code, polluting the RHTML views I was looking at days in days out. In June Dan posted a blog article titled The State (And Future) Of The UJS Plugin. In the article he writes that he’s lately not used the plugin at all and that he’s found it much better to just use Low Pro on its own without the Ruby scaffolding:

Essentially, the status is that, of late, I personally have not used UJS at all and have found a much better process by using Low Pro on its own without all the Ruby scaffolding of the UJS plugin. Secondarily, after talking to lots of developers at RailsConf it seems that the UJS plugin has failed to truly achieve it’s main goal which is to get Rails developers to write JavaScript using progressive enhancement. Many people seem to mainly use the plugin to get their JavaScript in to a separate file which is actually not even essential to progressive enhancement and I think this is a failing in the design of UJS itself. To achieve progressive enhancement you really need to think of JavaScript as a separate layer on top of a working HTML application but UJS lets you get away with keeping behavior in your views and hence leads many developers to think in the same way as they did before but think they are unobtrusive because they don’t see any JavaScript in their HTML – which is obviously not what we wanted to achieve. While many people can and do successfully use UJS for progressive enhancement even more seem not to – UJS has not been the ‘angel on your shoulder’ that I originally wanted it to be.

That single paragraph pretty much sums up my thoughts as well. And as many other people noted in the comments of the article that they, too, were mostly using just plain Low Pro instead of the plugin, I decided to give it a serious go as well. So for a recent project (a heavily Ajax-driven system) I just started writing everything without Javascript at first and then using Low Pro to progressively enhance the user experience with Ajax and other Javascript behaviours. Guess what – it’s worked wonderfully. I’m inclined to say I will never use a Rails Javascript or Ajax helper anymore. It was always more work to make them accessible than to just start with the barebones functionality and add the Javascript with Low Pro afterwards.

One initial fear I had was about dynamic serverside data that I could use with the UJS plugin. But that turned out not to be a problem at all. The cool thing about the Low Pro behaviours is that they have access to all the data on the page (even after updated by Ajax). That means you can use element id and class attribute values and the actual dynamic element content to your heart’s content. And if you really need to pass something special to the JS script alone, you can always set response headers that are then read by the Javascript code.

That’s it for part 1. Next week, in part 2, we’ll dissect an Ajax-driven, fairly inaccesible Rails page, and see how we can easily make it both accessible and unobtrusive with a few simple steps. Stay tuned!

Dubbing of the Simpsons Movie

Guan brings up an interesting point about The Simpsons Movie. Just like in Denmark, it’s distributed here both as original and a dubbed Finnish version. It’s been common to dub films here that are clearly targeted at small children. However, dubbing Simpsons is interesting for two reasons:

  1. Just like in Denmark, Simpsons the series has never been dubbed in the Finnish TV. People, even the children, are used to the certain American voices the characters have.
  2. From what I’ve heard (I’ve yet to see the film) Simpsons the Movie is not really a children’s movie at all, just like the series has never been aimed at children that can’t yet read.