Archive for the 'Rails' Category

Upgrading Ruby on Ubuntu Dapper

November 2nd, 2007 by pyrat

dapper

Ubuntu Dapper will only install ruby as high as 1.8.4 which is not ideal sometimes. To upgrade an existing ruby installation to 1.8.6 do the following.

  sudo apt-get install build-essential
sudo apt-get install libreadline5 libreadline5-dev
wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6.tar.gz
tar -xzf ruby-1.8.6.tar.gz
cd ruby-1.8.6
./configure --prefix=/usr/local --enable-pthread --with-readline-dir=/usr/local
make
sudo make install

Even if you had rubygems you need to install it and all your gems! Again.

   wget http://rubyforge.org/frs/download.php/35283/rubygems-1.1.1.tgz
tar -xzf rubygems-1.1.1.tgz
cd rubygems-1.1.1
sudo ruby setup.rb

Now this is where you need to do a little fix. Openssl will not work out of the box and some application need it so you should just set it up now.

Note: If apt-get libssl-dev complains about a not found run: sudo apt-get update

  sudo apt-get install libopenssl-ruby
sudo apt-get install libssl-dev
 
cd ~/src/ruby-1.8.6/ext/openssl
ruby extconf.rb
make
sudo make install

And thats it!

Logrotate in Rails

September 29th, 2007 by pyrat

Just a wee snippet for logrotate.
Open /etc/logrotate.conf or find it.

Then drop this at the bottom:


/var/www/apps/oentries/current/log/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
copytruncate
}

Example Monit Configuration with Mongrel

September 15th, 2007 by pyrat

Monit is great for keeping your services online. I use them for keeping my collection of slices online when I am asleep.
The example monitrc is a great starting point of listing the services which you should be monitoring.

One thing: monit can have its own little http server which runs internally. This is off in the example config as you have to explicitly enable it.

I hope to release a monit config generator gem in the near future which makes this a lot quicker.

Action Cache Issue Rails

August 30th, 2007 by pyrat

hmm-interesting

Ran into an interesting caching issue today which has been hiding in my web application oentries for quite some time. It all comes down to the locations that you serve your application from.

Previously (up to 10 minutes ago) I would serve it from both www.oentries.com and oentries.com. Recently I have been noticing a weird behaviour of the cached entry lists not getting updated. I have started using oentries.com for this recently. I then checked the equivalent URL on www.oentries.com and all was well.

Essentially, when the expire_action call is made, it uses something similar to url_for which generates the url from the headers to expire. Since all the users use www.oentries.com this cache is cleared out all the time when people enter for orienteering events, and since nobody is using oentries.com this isn’t getting cleared out.

The solution was to change the nginx config to put a global url rewrite to force www on urls. So now oentries.com gets redirected to www.oentries.com

I could have also improved the cache expiry code to expire the cache for both domains but as this is also an issue for SEO when you are serving the same app of different domains I decided that the URL rewrite was both a quicker fix (thanks to the nginx config generator now with SSL support thanks to me) and the right thing to do.

Conditional Validations in Rails

August 28th, 2007 by pyrat

The single table inheritance feature of rails is really useful. Today I needed to turn off validations in the extended model that were implemented in the base class.

I scratched my head for a while then realised its actually very simple.

class Page < ActiveRecord::Base

validates_presence_of :title, :slug,
:description, :if => :is_a_page?

private

def is_a_page?
self.class == ‘Page’
end

end

The above validation only takes place for the base class and not for classes that extend this. The beauty of STI being that the database stays pretty clean.

Install Old Capistrano 1.4.1

August 20th, 2007 by pyrat

sudo gem install -v 1.4.1 capistrano

In case you dont have the time to update your recipe and are setting up a new machine.

File upload plugin for rails

July 13th, 2007 by pyrat

I just found a great tutorial on using the attachment_fu rails plugin for uploading images to your rails app.

If you have every done this before in rails you will agree it takes a while and this makes it easy and powerful. You can even store all your images in amazon s3 with a couple of lines.

I’m going to write a wee rails project using these technologies and will let you know how it goes.

Deploying with Capistrano VPS

July 4th, 2007 by pyrat

It has taken me a while to move from the custom checkout scripts that I use for rails deployment to move to the capistrano way of doing things. I am so excited about it that I have decided to write this blog post.

This is not a definitive guide to rails deployment with capistrano but is the way I do things when deploying to slicehost for an application which we will be releasing in the not too distant future. This should work out for other vps servers and can be modified for shared hosting where you dont have as many permissions such as sudo access. Also I am basically a capistrano beginner so take what I say with a pinch of salt.

Firstly, if you are not familiar with capistrano I recommend purchasing the peepcode episode titled Capistrano Concepts

Your using source control right?


The first step is to make sure that you are using source control. The source control system of choice in the rails world is subversion. Capistrano works with quite a few other scm applications but subversion is by far the most common.

So you need to have your application in a repository somewhere which your deployment box can access. You should also setup the repository to work with the rails app (ignore log files, ignore database.yml, ignore *.pid files etc.) There is a great rake task for setting up subversion on rails

You have installed and setup your vps?


Lets say you have setup your vps and plan to deploy with an nginx / mongrel_cluster rails stack. There is a good guide at usefuljaja for doing this.

You have also setup ssh key authentication to avoid typing in passwords all the time. You are also just deploying to a single server and only have one mongrel process to start with.

For installing and setting up nginx for your deployment its best just to install nginx from source and use the nginx config generator to configure nginx for your deployment. I am also loving the no_www option which redirects requests to www.example.org→example.org. Is it just me or do other people hate www.*

Setting up a deploy user on the VPS is also recommended for cleanliness.

You have setup a database and there is a domain you can run this off?


You need to setup the database in your production environment. A url to deploy to would also be nice, maybe you are still in development and you can use a static dyndns.org free domain to get started.

Install capistrano and railsmachine


sudo gem install railsmachine —include-dependencies

This is a great little collection of capistrano tasks to organise the deployment by convention over configuration.

Setup your rails app and deploy


cd {RAILS_ROOT}
cap—apply-to .

This creates a deploy.rb in your /config directory where you can setup the deployment. My deployment script can be found over at pastie

The tasks defined in the two bottom tasks are defined in a mycaptasks.rb file which I can move around projects. You could also set it up as an svn:external in your project if you want to be more DRY. It is also up on pastie

Now run:
cap setup

This sets up the folder structure that capistrano uses.

Now:
cap cold_deploy

To check everything is working ok.

Now:
cap deploy_with_migrations

This will build up your new database assuming you work withe database migrations.

From now on
cap deploy

To deploy your app.

Its in source control


Because the deploy scripts are contained within the source control it works great in a distributed work environment so other developers can work with your project and deploy in a common way. It brings deployment into a convention rather than custom built and often nasty deployment methods which exist out there.

Cheers for now


This has been a skim at deploying with capistrano and I urge you to check out the other and probably a lot better learning resources out there.

Database Administration on a VPS

June 10th, 2007 by pyrat

Lets say you are setting up a lightweight VPS for hosting a rails stack. You install Nginx a high-performance HTTP server and reverse proxy with a small memory footprint and doesnt leak memory like my scirocco leaked petrol.

You also install mysql and tweak it like a mofo to decrease the memory usage and increase speed. You also install mongrel and mongrel_cluster to make scaling a reality for when your app hits the big time. It hasnt quite yet; so one mongrel process in the cluster will do for now :-)
You also configure a firewall, update ubuntu to the latest version, change ssh ports and make the server pretty lightweight and secure.

Usefuljaja has a pretty good guide on VPS setup.

Also, props to the amazing nginxconfiggenerator which makes setting up this beast from the motherland a sinch.

Now database admin. I like using phpmyadmin for simple database tasks. I have command line skillz but there is something about the visual representation in the browser that appeals to me. Does this mean I need to install php, fastcgi and lighttpd; or the industry heavyweight and Macdonald’s fan Apache2? Nope! Just setup a tasty ssh tunnel to port 3306 on the VPS and use a local install of phpmyadmin! It is pretty fast and works really well for simple tasks.

Also something like wamp or instant rails will give you a phpmyadmin install in a couple of minutes.

There is something about a VPS which gives you a new sense of power and the feeling that your hosting is truly in your hands. Out with the shared, in with the VPS!

Using Gettext to Translate Your Rails Application

April 20th, 2007 by pyrat

The version of this document is optimized for Ruby-GetText 1.9.0 and Rails 1.2.


This is hosted here because the ruby manuals server seems to have died. Central documentation would be nice :-p

Introduction


Stand on the shoulders of Giants


Gettext is a great tool for translating user interfaces of applications into different languages. It has been around for a long time and is very well established for this task. Gettext helps you to open up your application to a much wider user base than you would normaly reach in only one language. Since it is used in many open source projects it has a lot of useful tools you can use to your own advantage. It would be possible to “roll your own� solution, but this would consume a large amount of time. Time you would lose for the development of your app. And this is not something you would want, right?

So in this tutorial I am going to show you how to effectively use Gettext for all your translation needs in your Ruby on Rails application.

What can Gettext do for you?


Here is a quick explanation of Gettext for those of you who haven’t worked with it, yet. Gettext is a set of tools that provide help when translating strings in your software. It gives you (straight from the gettext manual):

  • A set of conventions about how programs should be written to support message catalogs.

  • A directory and file naming organization for the message catalogs themselves.

  • A runtime library supporting the retrieval of translated messages.

  • A few stand-alone programs to massage in various ways the sets of translatable strings, or already translated strings.

The only thing you have to do to your program sources is wrap all translatable strings with a method call: gettext(text) or shorter _(text). Example:

Without gettext:
notice = &#226;&#8364;&#732;Thank you for buying our product.&#226;&#8364;&#8482;
With gettext:
notice = _(&#226;&#8364;&#732;Thank you for buying our product.&#226;&#8364;&#8482;)
If you have wrapped everything between the method call Gettext will provide you with the tools to extract these messages (called a harvester) from your source code and save the results to a portable file format. A runtime library will allow you to display a translated message whenever _() is called. In essence this is what Gettext does. It can do a couple of more things (like update / merge message catalogs, handling plurals, …) but essentially it tries to make it as easy and as unobtrusive as possible to translate the language strings in your source code and then get out of your way.

Preperation is everything—use UTF-8 everywhere

Edit your files with UTF-8 only

The W3C has an awesome page with all you need to know about character sets (choosing, declaring, serving, editing, …) and other important stuff concerning internationalization on their site called W3C I18N Topic Index. There you will find a lot of good help and suggestions on everything you need to know about general internationalization topics. You really want to spend at least a couple of hours reading through the resources they offer or link to. If you happen to use VIM like I do you can put these two lines in your .vimrc and it will from then on treat your files as UTF-8 and convert everything to UTF-8 whenever you save a file:
set encoding=utf8
set fileencoding=utf8
If your editor of choice doesn’t provide support for UTF-8 it is probably time to get a new one ;)

Feed your database with UTF-8

If I need a database I usually go for MySQL. At least most of the time. Since version 4.1.x MySQL has very good support for different character sets. Please read the extensive MySQL Character Set Support article. It will give you a very good idea about the kind of support MySQL has to offer. Here is a table definition I use in a current project:
CREATE TABLE `pages` (
`id` int(10) unsigned NOT NULL auto<em>increment,
`title` varchar(255) default NULL,
`keywords` varchar(255) default NULL,
`description` varchar(255) default NULL,
`block1` text,
`block2` text,
`block3` text,
`block4` text,
`block5` text,
`lang` varchar(10) NOT NULL default &#226;&#8364;&#8482;en</em>EN&#226;&#8364;&#8482;,
`category` varchar(255) default NULL,
`path` varchar(255) default &#226;&#8364;&#732;/&#226;&#8364;&#8482;,
`updated<em>at` datetime default NULL,
`created</em>at` datetime default NULL,
`published<em>at` datetime default NULL,
`layout` varchar(255) default &#226;&#8364;&#732;main.rhtml&#226;&#8364;&#8482;,
`template` varchar(255) default NULL,
`access` tinyint(3) unsigned default &#226;&#8364;&#732;3&#226;&#8364;&#8482;,
`version` int(10) unsigned default &#226;&#8364;&#732;1&#226;&#8364;&#8482;,
`is</em>published` tinyint(3) unsigned default &#226;&#8364;&#732;0&#226;&#8364;&#8482;,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
There is nothing really special about it except the DEFAULT CHARSET=utf8 in the last line. It will make MySQL use UTF-8 for every field that holds text like varchar and text. Add the following line to your database.yml to connect with UTF-8.
encoding: UTF8
If you use another maybe more mature and feature rich database like PostgreSQL UTF-8 support should also be available. Just make sure you configure everything upfront, because it might save you time later on.

If you still think you are going to tack on support for UTF-8 later you might reconsider after reading David’s and Jamis’ experiences: Forty-four grueling hours (or Welcome to 37s!) by David Heinemeier Hansson and On the job by Jamis Buck.

If for any reason you need to use anything other than UTF-8 you might want to know that you can use the Iconv module to convert between different character sets. This module should be installed by default on most distributions. If it is not it is usually easy to get. Just be sure to get it if you need charcter set conversion. On Debian you might need a apt-get install libiconv-ruby to get started. Here is a little example stolen from Pickaxe 2 page 686:

Example: Convert olé from UTF-8 to ISO-8859-1
$ irb&#226;&#8364;&#8220;riconv
>> Iconv.conv(&#226;&#8364;&#732;ISO-8859-1&#226;&#8364;&#8482;, &#226;&#8364;&#732;UTF-8&#226;&#8364;&#8482;, &#226;&#8364;&#339;ol303251&#226;&#8364;?)
=> &#226;&#8364;&#339;ol351&#226;&#8364;?

Installing Ruby-GetText

After everything in your setup will accept UTF-8 we can go ahead and install Gettext support in Ruby. We will use the Ruby-GetText-Package which is a Ruby implementation of the Gettext interface that also has some c-bindings for the Locale. If you have rubygems, you can easily install Ruby-GetText:
$ gem install gettext
Select which gem to install for your platform (&#226;&#8364;&#166;)
1. gettext 1.9.0 (ruby)
2. gettext 1.9.0 (mswin32)
&#226;&#8364;&#166;>
Be sure to choose option 2 if you want Ruby-GetText to work on native Windows (with One-Click Ruby Installer) as you are most likely not able to compile otherwise. For all other platforms use 1.

Alternative: If you need the source you can get it from the author’s site: Ruby-GetText-Package. Besides installation instructions you will find a small HOWTO, API Reference and documentation on how to use provided tools.

Check the sample Rails application that is delivered with Ruby-GetText. If you installed via RubyGems it is most likely here: /usr/lib/ruby/gems/1.8/gems/gettext-1.9.0/samples/rails/, but it could be somewhere else depending on where your Ruby is installed. Later I will call that path $RUBYGETTEXTRAILSSAMPLE. So keep this in mind when you read.

Create the “po� directory structure


Create a po dir right in your $RAILS_ROOT. In it you will create a subdir for every language/dialect combination (actually the second part of this abbreviation stands for “geographic region�, but I will just call it dialect throughout this document). If you don’t know the right code for your language you can seek help at the Language section of the W3C I18N Topic Index.

Ultimately your directory structure is going to look like this:
simplepages@colinux: /home/simplepages/rails/po:
$ d&#226;&#8364;&#8220;T
/home/simplepages/rails/po/:
|-myapp.pot
|-de<em>DE/:
| `-myapp.po
|-en</em>GB/:
| `-myapp.po
|-en<em>US/:
| `-myapp.po
|-fr</em>FR/:
| `-myapp.po
|-fr_CH/:
| `-myapp.po
`-ja/:
`-myapp.po
The myapp.pot file is the original file created by the rgettext script introduced later. The po files will contain the translation messages that your application is going to use depending on the language that is requested.

Convert pofiles to mofiles

After creating pofiles, you need to convert them to mofiles. If you haven’t yet, please read the the GNU Gettext manual with the explanation of what mo and po stands for. Add the code below to Rakefile:
simplepages@colinux: /home/simplepages/rails/Rakefile
require &#226;&#8364;&#732;gettext/utils&#226;&#8364;&#8482;
desc &#226;&#8364;&#339;Create mo-files for L10n&#226;&#8364;?
task :makemo do
GetText.create_mofiles(true, &#226;&#8364;&#339;po&#226;&#8364;?, "locale")
end
Then,
$ rake makemo
It will create locale directories and subdirectroies such as:
simplepages@colinux: /home/simplepages/rails/locale:
$ d&#226;&#8364;&#8220;T
/home/simplepages/rails/locale/:
|-de<em>DE/:
| `-LC</em>MESSAGES/:
| |-myapp.mo
|-en<em>GB/:
| `-LC</em>MESSAGES/:
| |-myapp.mo
|-en<em>US/:
| `-LC</em>MESSAGES/:
| |-myapp.mo
|-fr<em>FR/:
| `-LC</em>MESSAGES/:
| |-myapp.mo
|-fr<em>CH/:
| `-LC</em>MESSAGES/:
| |-myapp.mo
`-ja/:
`-LC_MESSAGES/:
|-myapp.mo
These files are used by Ruby-GetText. You don’t need to touch these files.

Tools of trade

Gettext

You will need to install Gettext. On Debian I would do apt-get install gettext to do that. It contains a couple of tools that will be handy later on, most importantly msgmerge which can merge different po files so updating your message files will be a snap and msginitwhich can set default values to the header of pofile in your locale.

Ruby-GetText and rgettext

After you have installed Ruby-GetText and tools you should able to call rgettext on the command line. rgettext is a replacement for xgettext which comes with the main Gettext application. Beyond xgettext, rgettext supports not only ruby scripts(.rb) but also ERB files (.rhtml), ActiveRecord(.rb) directly.

ActiveRecord support rgettext extracts all the table names and field names within subclasses of ActiveRecord::Base.

Notice: You need to run your database server and configure the config/database.xml correctly before executing rgettext.

poEdit

poEdit is a great tool to manage and edit your translations. It gives you a nice graphical frontend to translate all your messages. It is available for many different platforms. A nice side effect about using an easy to use GUI tool is that you can tell non-programmers to install it, open the po file and just start translating. They might have nothing to do with the coding in your project but will be able to help you translate your software. So if your grandma can translate English to Chinese she can maybe help you with your software project :)

Collecting messages

Add the code below to Rakefile:
simplepages@colinux: /home/simplepages/rails/Rakefile
desc &#226;&#8364;&#339;Update pot/po files to match new version.&#226;&#8364;?
task :updatepo do
MY<em>APP</em>TEXT<em>DOMAIN = &#226;&#8364;&#339;myapp&#226;&#8364;?
MY</em>APP<em>VERSION = &#226;&#8364;&#339;myapp 1.1.0&#226;&#8364;?
GetText.update</em>pofiles(YOUR<em>APP</em>TEXT<em>DOMAIN,
Dir.glob(&#226;&#8364;&#339;/<strong>/</strong>.{rb,rhtml}&#226;&#8364;?),
MY</em>APP_VERSION)
end
Running this task will either create or update your po/myapp.pot and po/<strong>/myapp.po</strong> files in the relevant directories. It will go through all the important directories of your rails app and harvest all the Gettext strings in files ending in .rb, *.rhtml.
$ rake updatepo

Translating and compiling with and without poEdit

After you have successfully harvested your files you should have a myapp.po file in every locale dir. Now you need to translate them. Since the myapp.po files are mere text files you could just use your favourite text editors to translate them. Given that your text editor can edit in UTF-8 mode and you know the escaping rules of Gettext this is all you actually need. Open the file, translate the text and save it. After you have saved the file compile it. Gettext doesn’t work with the text files (myapp.po) directly. It wants a compiled version of it (myapp.mo). Use the rake makemo command to compile:
simplepages@colinux: /home/simplepages/rails/po/de_DE:
$ ls
myapp.posimplepages@colinux: /home/simplepages/rails:
$ rake makemo

	

simplepages@colinux: /home/simplepages/rails/locale/de<em>DE/LC</em>MESSAGES:
$ ls
myapp.mo


However, it is way more comfortable to use an application like poEdit for this. With poEdit you can also easily open up the myapp.po file. It will give you a nice side by side view your original strings and the translated version, telling what is already translated and what is not. You click on a message and start translating it in a special field. Hit the save button and poEdit will automatically compile the myapp.mo file for you (check the preferences if it doesn’t do it by default). That’s it. With a compiled myapp.mo you can start to teach your rails app how to translate your user interface.

See Documents for Translators for more details to translate the po-file.

When creating a po file it is useful to include header information at the top of the po file. This adds useful information such as character set, last translator etc. If you are not using poEdit add something similar to the top of the po file.
msgid &#226;&#8364;&#339;"
msgstr "&#226;&#8364;?
&#226;&#8364;&#339;POT-Creation-Date: 2007-02-19 17:15-0000n&#226;&#8364;?
&#226;&#8364;&#339;PO-Revision-Date: 2003-04-03 10:49--500n&#226;&#8364;?
&#226;&#8364;&#339;Last-Translator: Alastair Brunton n&#226;&#8364;?
&#226;&#8364;&#339;Language-Team: fr_FR n&#226;&#8364;?
&#226;&#8364;&#339;MIME-Version: 1.0n&#226;&#8364;?
&#226;&#8364;&#339;Content-Type: text/plain; charset=UTF-8n&#226;&#8364;?
&#226;&#8364;&#339;Content-Transfer-Encoding: 8bitn&#226;&#8364;?

Implementing Ruby-GetText into your rails app

By now you should have a translated and compiled myapp.mo in your locale dir. For example my German translation of SimplePages is at $RAILS<em>ROOT/locale/de</em>DE/LC_MESSAGES/myapp.mo.

Including Ruby-GetText

Edit application.rb to bind textdomain to your application.
simplepages@colinux: /home/simplepages/rails/app/controllers/application.rb:
require &#226;&#8364;&#732;gettext/rails&#226;&#8364;&#8482;class ApplicationController < ActionController::Base
init<em>gettext &#226;&#8364;&#339;myapp&#226;&#8364;?
	

#init</em>gettext &#226;&#8364;&#339;myapp&#226;&#8364;?, &#226;&#8364;&#339;UTF-8&#226;&#8364;?, &#226;&#8364;&#339;text/html&#226;&#8364;? # <= Also you can set charset and content_type.
end


In this sample, the textdomain name is “myapp�. Replace it as you like to fit your application. Maybe you want to have different textdomains for your site and the admin section.

Selecting the scope of your textdomain


  1. If you call bindtextdomain in ApplicationControler, the textdomain applies to the entire application.

  2. If you call bindtextdomain in any other controller with a different textdomain, this textdomain only applies to this specific controller. For example if you call a different textdomain in myapp<em>controller.rb</em> it will only be used in myappcontroller.rb.

The textdomains are applied to each controller/view/model.

Choosing the right language on every request


Since we are developing a web application we want to be able to choose the current language by request. Additionally we might want to offer the user the possibilty to choose the language from a menu.

Ruby-GetText chooses the current language by following these rules in the given order:

  1. the first value passed to the ‘locale’ parameter of GetText.bindtextdomain method call

  2. ‘lang’ value of QUERY_STRING

  3. ‘lang’ value of the Cookie

  4. the value of HTTP<em>ACCEPT</em>LANGUAGE

  5. or default ‘en’ (English).

The script $RUBYGETTEXT<em>RAILS</em>SAMPLE/vendor/plugins/lang_helper.rb is a sample that selects locale using the cookie value of the user.

It may be useful to implement a simple controller action to change between languages eg.
class CookieController < ApplicationController
def set<em>cookie
code = params[:id]
cookies[:lang] =
{
:value => code,
:expires => Time.now + 1.year,
:path => &#226;&#8364;&#732;/&#226;&#8364;&#8482;
}
redirect</em>to home_url
end
end
So /cookie/set<em>cookie/fr</em>FR would change the language to French.

Using the Locale in your templates

Depending on the selected locale you will want to customize the language and character set in your templates. File: $RAILS_ROOT/app/view/layouts/main.rhtml
&#226;&#8364;&#339;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&#226;&#8364;?>

= Locale.charset %>" />
&#226;&#8364;&#166;

Have your own textdomain for plugin applications

If you are a plugin developer and want to have your own textdomain, you need to separate the Class/Module from ActionView::Base/ApplicationController.
simplepages@colinux: /home/simplepages/rails/vendor/plugins/gettext/lib/gettext_plugin.rb:
require &#226;&#8364;&#732;gettext/rails&#226;&#8364;&#8482;module LangHelper
	
  1. If you need to bind yet another textdomain to your plugin.
  2. Separate the name space from ActionView::Base/ApplicationController.
    class YetanotherTextDomain
    include GetText::Rails

def initialize

  1. You need to call bindtextdomain in an instance of ActionView::Base.
  2. The locale is used a same values which define ApplicationController#init<em>gettext instead of
  3. the textdomain.
    bindtextdomain(”gettext</em>plugin”)
    end

def show<em>language(actionview)
langs = [”en”] + Dir.glob(File.join(RAILS</em>ROOT,&#226;&#8364;&#339;locale/*&#226;&#8364;?)).collect{|item| File.basename(item)}
langs.delete(”CVS”)
langs.uniq!
ret = &#226;&#8364;&#339;
<h4>&#226;&#8364;? + <em>&#226;&#8364;&#339;Select locale&#226;&#8364;?) + &#226;&#8364;&#339;</em></h4>
<em>&#226;&#8364;?
langs.sort.each do |lang|
ret << actionview.link</em>to(&#226;&#8364;&#339;#{lang}]&#226;&#8364;?, :action => &#226;&#8364;&#339;cookie_locale&#226;&#8364;?, :lang => lang)
end
ret
enddef cookie_locale(cookies, flash, params)
cookies[”lang”] = params[”lang”]
flash[:notice] = _(&#226;&#8364;&#732;Cookie “lang” is set: %s&#226;&#8364;&#8482;) % params[”lang”]
end
end

  1. This function shows supported languages with link to set cookie
  2. action (cookie<em>locale).
    def show</em>language
    YetanotherTextDomain.new.show_language(self)
    end
  1. This function is called when the language link is set.
    def cookie<em>locale
    YetanotherTextDomain.new.cookie</em>locale(cookies, flash, params)
    redirect_to :action => &#226;&#8364;&#732;list&#226;&#8364;&#8482;
    end
    end

Simply put gettext_plugin.po into the po directory.

Conclusion


That’s it. If you have your translated message catalogs (myapp.mo) in all the right places your application should show your message strings in your favourite language.

You can now easily start to translate your application into all the different languages you want. I hope this guide helps you to get started. There are certainly many more aspects of internationalization that you will have to learn and apply. Remember that this is only one of many possible ways to do it. If you find any mistakes, shortcomings or have good suggestions on how to improve this guide I would be more than happy to hear from you.

If you want you can download the original Textile document, make modifications and send them back to me. I will be sure to include you in the credits section.

Sascha Ebach
se at digitale-wertschoepfung dot de

Credits


Author

Sascha Ebach is the owner and lead developer of a small web design and development shop Digitale Wertschöpfung in Cologne, Germany. Together with his two partners he develops and designs complete online solutions for small to medium sized businesses. Up until the surfacing of Rails he used to develop everything in PHP although he has already fallen deeply in love with Ruby since version 1.6.2 came out. For him it is very clear that Rails and Ruby will be The Future Way of developing web applications and he already looks forward to the day when he has ported his last line of PHP to Ruby.

Appendix A: Downloads

Used files

Download the archive with files and scripts I use and talk about in this guide. The file includes the complete skeleton of files that you need to get started.
/home/simplepages/using-gettext-with-rails/:
|-app/:
| `-controllers/:
| `-application.rb (the ApplicationController with the .init<em>gettext method)
`-po/: (sample directory structure)
|-de</em>DE/:
|-en<em>GB/:
`-en</em>US/:
Download using-gettext-with-rails.tgz