About half a year ago I wrote a snippet of code to make the GetText package for the Ruby programming language to work with ActiveScaffold, a highly configurable dynamic editing facility for Ruby On Rails applications.
I published this as a contribution on ActiveScaffold's project wiki. Since then there had been at least one supplement by another user. One day the wiki was not availabe, and the link structure changed afterwards and the wiki became read-only. I guess this was the final brake against comment spam, being a plague everywhere on the net by turning community features into an annoying mess of crap.
Today I decided to duplicate my former article here for backup reasons
and for getting back the opportunity to have changes added by myself or
others, paying the price of redundancy:
(begin of original article)
Update 06-27-07 (added missing varargs handling)
Update 06-28-07 (enforced signature conformance in #[N]_())
Update 09-12-07 (changed to use the Action
Controller textdomainname and removed setting single locale:
NOTE YOU MUST NOW REQUIRE
localize_active_scaffold.rb in the body of your application
controller)
Integrating the Active Scaffold Localization Plugin sources, I had consulted for a clue.
The core of the solution is the following module to be placed in your app’s lib subdirectory:
# localize_active_scaffold.rb
# Created by ofi on 2007-06-24.
# Published under MIT license (like RoR).
#
module LocalizeActiveScaffold
include GetText
# [09-12-07] changed to use the ActionController textdomainname
# and removed setting single locale
bindtextdomain(ActionController::Base.textdomainname, :path =>
File.join(RAILS_ROOT, "locale"))
GT_LOG = Logger.new("#{RAILS_ROOT}/log/gettext.log")
GT_LOG.level = Logger::WARN
GT_LOG.error "**** Started log at #{Time.new.to_s}"
# [06-27-07] no varargs parameter anymore
# [07-12-07]:(anonymous) use GetText.s_ when column name is specified
def self.translate(string_to_localize)
if string_to_localize.include?('|')
res = s_(string_to_localize)
GT_LOG.debug "translate() called for: #{string_to_localize} => #{res}"
if GT_LOG.warn? and (res == string_to_localize.split(/\|/).pop)
GT_LOG.warn "No translation for <#{string_to_localize}>!"
end
else
res = _(string_to_localize)
GT_LOG.debug "translate() called for: #{string_to_localize} => #{res}"
if GT_LOG.warn? and (res == string_to_localize)
GT_LOG.warn "No translation for <#{string_to_localize}>!"
end
end
return res
end
# [06-27-07] no varargs parameter anymore
def self.dont_translate(string_to_localize)
N_(string_to_localize)
end
private
# The following strings contained in the ActiveScaffold plugin in various
# files serve as a proxy for rgettext (driven by the rake task updatepo)
# for making them appear in the po files.
def dummy
N_('Open')
N_('Close')
N_('close')
N_('Edit')
N_('Delete')
N_('Show')
N_('Search')
N_('Search Terms')
N_('No Entries')
N_('Found')
N_('Create New')
N_('Are you sure?')
N_('Cancel')
end
end
# The following methods delegate ActiveScaffold's call to as_() as well as
# gettext's calls to _() to the above translate() method:
class Object
# [06-28-07]: enforce single argument signature
def _(*args)
LocalizeActiveScaffold.translate(args[0].to_s)
end
# [06-28-07]: enforce single argument signature
def N_(*args)
LocalizeActiveScaffold.dont_translate(args[0].to_s)
end
# coupling ActiveScaffold to gettext by declaring this
# method, which will be called by AS:
# [06-27-07]: now calling the insertion operator on the
# varargs parameters (if any). CAVEAT: Too few parameters
# will deliver nil as the method's result!
# [06-28-07]: less is more: removed redundant cond. expr.
def as_(loc_string, *args)
LocalizeActiveScaffold.translate(loc_string) % args
end
end
# following method replaces column labels into 'ClassName|Attribute name' forms.
# gettext returns column name as that's form.
# [07-12-07]:(anonymous)
module ActiveScaffold::DataStructures
class Column
def initialize_with_gettext(name, active_record_class)
initialize_without_gettext(name, active_record_class)
self.label = active_record_class.name.demodulize + '|' + self.label.humanize
end
alias_method_chain :initialize, :gettext
end
end
What it does:
- The enhancements to Object take care for the appropriate calls at runtime. I first tried without N_(), but saw in the log, that all strings in a “dclarative” context like in arrays or the AS config blocks triggered at least two calls, meaning that translation may happen too early, and in a real multi-language application with possible locale switches between requests, the user will be presented with the wrong translation.
- The private dummy method only flags terms for rgettext which appear in the AS sources in various files.
- The logger GT_LOG in the tranlsate() method when set to WARN will note down phrases not translated into log/gettect.log, so you can add these terms to dummy(), do the “rake updatepo; edit <...>; rake makemo” dance (see the Ruby Gettext pages for details), et voilà.
To use the module You will need to “require” it in your application.rb file after init_gettext like:
...
class ApplicationController < ActionController::Base
init_gettext 'your_app'
require "localize_active_scaffold"
...
Of course I won’t win a programming-elegance award with this, but as long as it can save someone some time I wish I had spent with something else, this is all I’d like to achieve.
(end of original article)
Go Top