Thomas Fuchs
Hi, I'm Thomas Fuchs. I'm the author of Zepto.js, of script.aculo.us, and I'm a Ruby on Rails core alumnus. With Amy Hoy I'm building cheerful software, like Noko Time Tracking and Every Time Zone and write books like Retinafy.me.
   Want me to speak at your conference? Contact me!

Localization plugin

October 30th, 2005

I’ve updated my pragmatic i18n/l10n library for Ruby on Rails and released it as a plugin.

With the latest edge rails, a simple script/plugin install localization should get you going.

For more information, see the included README flie!

Slider plugin for Ruby on Rails!

October 29th, 2005

So, have a quick look at it!

Still rough warning, so expect more tomorrow or so.

S5 slides with script.aculo.us effects

October 17th, 2005

Want to give your S5 presentations some impact by adding script.aculo.us effects? Juan Manuel Caicedo created a nice library called ‘Presentacular’ to do that. (Usage info, Demo)

No knowledge of JavaScript required!

4000+ delicious links for script.aculo.us

October 14th, 2005

Now ranking at #6 on populicio.us! 🙂

AJAX Workshop (with me!)

October 13th, 2005

On December 8, I’m doing a one-day workshop in London, UK on AJAX and how to use it properly with Ruby on Rails (and PHP, too). Participants will get a chance to have look at some of the inner workings of the still unannounced application we’ve in the works at wollzelle.

Read more on the Carson Workshops site!

script.aculo.us V1.5_rc3, second release candidate

October 9th, 2005

The final release of script.aculo.us V1.5 should now be just around the corner!

Important changes and fixes from 1.5_rc1 (for a detailed list, see the CHANGELOG file):

  • Make Effect position available to callbacks
  • Droppables.fire: send event to onDrop callback [François Beausoleil], #2389
  • InPlaceEditor: Add disabling the field while loadTextURL loads and add a class while loading, plus fix various bugs with Internet Explorer and InPlaceEditor, [Jon Tirsen] #2302, #2303
  • Made Droppables.remove work again [thx Mindaugas Pelionis], #2409
  • Fixed that IE6 would incorrectly render the “fix-windowed-elements-overlapping” IFRAME on autocompletion [thx tshinnic], #2403
  • Fixed Element.getOpacity throwing an error on Safari in some situations (this caused the autocompleter not to work)
  • Added format option to Sortable.create and Sortable.serialize to allow custom id formats. The format option takes a regular expression where the first grouping that matches is used for building the parameters. The default format is /^[^_]*_(.*)$/ which matches the string_identifier format. If you want to use the full id of the elements, use format: /(.*)/. More examples are available in the sortable unit test file.
  • Started refactorings to use the new Prototype features and general code-cleanup
  • Update lib/prototype.js to Prototype 1.4.0_pre11
  • Fixed a typo breaking the up arrow key for autocompletion [thx tshinnic], #2406
  • Changed the handle option on Draggbles to accept classnames, or ids or elements [thx to Andrew West], #2274
  • Force indicator to be hidden on hiding autocompletion update element, #2342
  • Make Draggables honor external CSS positioning [thx to Mark Shawkey], #2359
  • Make zindex handling for Draggables honor external CSS styles
  • Fix two Sortable.serialize issues, [thx Avi, Gorou], #2339, #2357
  • Make Element.getOpacity work with IE, added unit tests [thx to Greg Hill]
  • Make Element.setOpacity honor non-alpha filters on IE (it now works with filters for alpha PNGs)
  • Fixed that Element.class.remove wrongly deleted spaces between class names, fixes #2311, #2313
  • Fixed Builder for OPTION and OPTGROUP tags on Firefox < 1.5 and Internet Explorer 6, completely fixes #2325
  • Improved Builder implementation to deal with Firefox-specific requirements and innerHTML parsing, partly fixes #2325
  • Attempt to fix crashes in Safari 2.0.1, probably related to the event registering und unregistering in Draggables, possibly fixes #2310

As always, a big thank you to all the contributors and testers!

Ruby on Rails i18n revisited

October 3rd, 2005

Having a requirement for both internationalization and per-instance customizability of translations in our soon to be revealed application, I wanted to go with an as-simple-as-possible pure Ruby solution for translating strings.

While gettext based approaches might have some advantages over this (some tools available, possibly faster speed with C-based variants) I didn’t want to go with a sledgehammerized solution (I’ve very few strings in the app, and I really only need to support a handful of languages), so I’ve come up with this:


# .rb files to define l10ns in (lang/ and lang/custom/)
Localization.define('de_DE') do |l|
  l.store "blah", "blub"
  l.store "testing %d", ["Singular: %d", "Plural: %d"]
end

# Call from anywhere (extension to Object class):
_('blah')
_('testing %d', 5)

# in .rhtml
<%=_ 'testing %d', 1 %>

# current language is a class var in class
# Localization, so set e.g. in application.rb
Localization.lang = 'de_DE'

# in environment.rb (rails 0.13.1)
Localization.load

All you need to include for this is the following localization.rb file, which you stick in your lib directory:


module Localization
  mattr_accessor :lang

  @@l10s = { :default => {} }
  @@lang = :default

  def self._(string_to_localize, *args)
    translated =
      @@l10s[@@lang][string_to_localize] || string_to_localize
    return translated.call(*args).to_s if translated.is_a? Proc
    translated =
      translated[args[0]>1 ? 1 : 0] if translated.is_a?(Array)
    sprintf translated, *args
  end

  def self.define(lang = :default)
    @@l10s[lang] ||= {}
    yield @@l10s[lang]
  end

  def self.load
    Dir.glob("#{RAILS_ROOT}/lang/*.rb"){ |t| require t }
    Dir.glob("#{RAILS_ROOT}/lang/custom/*.rb"){ |t| require t }
  end

end

class Object
  def _(*args); Localization._(*args); end
end

It should be easy to alter or extend that for your own purposes, or just use it as-is.

Update: Changed to module; and here’s a very quick hack to extract a nice pre-generated guesstimation of a l10n file:


# Generates a best-estimate l10n file from all views by
# collecting calls to _() -- note: use the generated file only
# as a start (this method is only guesstimating)
def self.generate_l10n_file
  "Localization.define('en_US') do |l|n" <<
  Dir.glob("#{RAILS_ROOT}/app/views/**/*.rhtml").collect do |f|
    ["# #{f}"] << File.read(f).scan(/<%.*[^w]_s*["'](.*?)["']/)
  end.uniq.flatten.collect do |g|
    g.starts_with?('#') ? "n  #{g}" : "  l.store '#{g}', '#{g}'"
  end.uniq.join("n") << "nend"
end

To use that, call up script/console and do a puts Localization.generate_l10n_file.

Update 2: I’ve added support for using nice lambda blocks of code for those “speciality” translations. The block gets passed the *args given to the _ method, so you can basically do anything:


Localization.define do |l|
   l.store '(time)', lambda { |t| t.strftime('%I:%M%p') }
end

Localization.define('de_DE') do |l|
   l.store '(time)', lambda { |t| t.strftime('%H:%M') }
end

_ '(time)', Time.now =>"10:13PM"
Localization.lang = 'de_DE'
_ '(time)', Time.now => "22:13"

An unveiling

October 2nd, 2005

Our company is moving to brand-new offices in the heart of Vienna really soon, so you might want to take a peek.

wollzelle

This will not be the last of our unveilings, so stay tuned. 🙂

P.S. And yes, among other things, we’re working on the next big thing in web apps (written in Ruby on Rails, of course!). 😉