Ruby-GetText-Package HOWTO maintain po/mo files

ruby-gettext-howto-manage

Why do you need Ruby-GetText-Package ?

For Developing L10n applications, the most important task is to keep to synchronize the catalog-files(such as po/mo files) easily.

Ruby-GetText-Package and GNU GetText family provide useful tools(and utility libraries) for maintainance.

At my first tutorial, I introduced the tools rgettext/rmsgfmt. It's useful on the console. But it may be annoy to type the commands with some options to the console.

On this article, I introduce the second way which uses to call GetText's functions with rake.

It makes maintain your application easier than using rgettex/rmsgfmt on the cosole.

Note

The application's information on this tutorial

  • Appliction name: myapp
  • Textdomain name: myapp
  • Version: 1.0.0

Directory structure

Puts Rakefile at the top of your application directory.

/myapp/Rakefile
       |-lib/...   => target ruby scripts to extract the strings.
       `-bin/myapp => your application which is the one of ruby script.

Add the code below to Rakefile:

desc "Update pot/po files."
task :updatepo do
  require 'gettext/utils'
  GetText.update_pofiles("myapp", Dir.glob("{lib,bin}/**/*.{rb,rhtml}"), "myapp 1.0.0")
end

desc "Create mo-files"
task :makemo do
  require 'gettext/utils'
  GetText.create_mofiles(true)
  # GetText.create_mofiles(true, "po", "locale")  # This is for "Ruby on Rails".
end

You need to require 'gettext/utils' in each tasks. Because it may not work with RDoc tasks.

Create myapp.pot

Run "updatepo" task to create pot-file using updatepo task.

$ rake updatepo

This creates po directory and po/myapp.pot

/myapp/Rakefile
       |-lib/... 
       |-bin/myapp
       `-po/myapp.pot  => Created. 

ActiveRecord support

"updatepo" task extracts all of the table names and field names which the subclass of ActiveRecord::Base has. Before you execute "updatepo" task, you need to run your database server and configure the config/database.xml correctly.

Edit myapp.pot

Edit the header part of po/myapp.pot. It is for the explanation of your application.

# myapp - my sample  application.
#
# Copyright (C) 2005 Masao Mutoh  <= the author of this application.
#
# This file is distributed under the same license as the Ruby. <= Licence information.
#
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.    <= Translator's name (not edit here)
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: myapp 1.0.0\n"
 :
 :
 :

Send myapp.pot to translators

Send your po/myapp.pot to translators.

See Documents for translators to translate myapp.pot.

Collect myapp.po files from translators

You get the translated myapp.po files from translators, you need to put them under po/ properly.

/myapp/Rakefile
       |-lib/... 
       |-bin/myapp
       `-po/myapp.pot
          |-en/myapp.po
          |-de/myapp.po
          |-fr/myapp.po
          |-fr_CH/myapp.po
          |-ja/myapp.po
              :
              :

Convert po-files to mo-files.

Run "makemo" task to convert po-files to mo-files.

$ rake makemo

It makes mo-files under data/locale/ directory.

/myapp/Rakefile
       |-lib/... 
       |-bin/myapp
       |-po/myapp.pot
       |  |-en/myapp.po
       |  |-de/myapp.po
       |  |-fr/myapp.po
       |  |-fr_CH/myapp.po
       |  |-ja/myapp.po
       |      :
       |      :
       `-data/locale/
                  |-en/LC_MESSAGES/myapp.mo
                  |-de/LC_MESSAGES/myapp.mo
                  |-fr/LC_MESSAGES/myapp.mo
                  |-fr_CH/LC_MESSAGES/myapp.mo
                  |-ja/LC_MESSAGES/myapp.mo
                      :
                      :

Note if your application is based on "Ruby on Rails", the mo-files are created under locale/ directory instead of data/locale/.

Test your application

Before installing myapp, you can test it to use GETTEXT_PATH environment variables.

$ export GETTEXT_PATH="data/locale"
$ ruby -Ilib bin/myapp

If something is wrong, execute ruby with -d to output verbose messages.

$ ruby -d -Ilib bin/myapp

Release your application

Using RubyGems

If you use RubyGems, the data/ directory will be install to:

/usr/lib/ruby/gems/1.8/gems/myapp-1.0.0/data/

Ruby-GetText-Package finds this directory automatically.

Add the code below to Rakefile:

desc "Create gem and tar.gz"
spec = Gem::Specification.new do |s|
  s.name = 'myapp'
  s.version = "1.0.0"
  s.summary = 'Sample application'
  s.author = 'Masao Mutoh'
  s.email = 'mutoh@highway.ne.jp'
  s.homepage = 'http://ponx.s5.xrea.com/hiki/ruby-gettext.html'
  # s.rubyforge_project = "myapp"
  s.files = FileList['**/*'].to_a.select{|v| v !~ /pkg|CVS/}
  s.require_path = 'lib'
  s.executables = Dir.entries('bin').delete_if {|item| /^\.|CVS|~$/ =~ item }
  s.bindir = 'bin'
  s.description = <<-EOF
    myapp is the sample application of Ruby-GetText-Package.
  EOF
end

Rake::GemPackageTask.new(spec) do |p|
  p.gem_spec = spec
  p.need_tar_gz = true
  p.need_zip = false
end

Then,

$ rake package

It creates pkg/myapp-1.0.0.gem and pkg/myapp-1.0.0.tar.gz. You'll release them any host where you want.

After installing your application, Run

$ myapp

Now your application works with L10n messages.

If not, try ruby with "-d" option.

$ ruby /usr/bin/myapp

Using setup.rb

If you use setup.rb, data/ diretory will be installed to /usr/share/.

$ ruby setup.rb

So, data/locale directory will be installed to:

/usr/share/locale/...

This is the default locale directory for POSIX system and almost of applications which use GNU GetText use this directory.

Run myapp

$ myapp

it works with L10n messages, too.

Go next stage

You finished the first release, you'll start to develop next version of myapp-1.1.0.

The codes are updated and some messages will be added and changed. So you need to update your pot/po file again.

First, update "updatepo" tasks in Rakefile. Usually you need to update the version information of the GetText.update_pofiles only, though.

desc "Update pot/po files."
task :updatepo do
  require 'gettext/utils'
  GetText.update_pofiles("myapp", Dir.glob("{lib,bin}/**/*.{rb,rhtml}"), "myapp 1.1.0")
end

Run

$ rake updatepo

"updatepo" task updates/merges po/myapp.pot and all of the po/#{lang}/myapp.po files using msgmerge[1].

Then send the po/#{lang}/myapp.po to the translators again.

[1] msgmerge is a tool of GNU GetText. So you need to install GNU GetText first. If "updatepo" task can't find msgmerge, set MSGMERGE_PATH environment variable like as:

(For bash/zsh)
$ export MSGMERGE_PATH="/usr/bin/msgmerge"

(For Windows)
c:\foo> set MSGMERGE_PATH="c:\GTK\bin\msgmerge.exe"