Getting Started with Ruby on Rails and TML

In this post we will create a simple web site using Ruby on Rails and translate it to a few languages using Translation Markup Language and Translation Exchange service.

In this demo, we will create a simple one page site, called “Welp”. On the site we will have a few restaurant reviews and a search form.


Once you follow this guide, you will see how you can use Translation Exchange tools to quickly and easily translate the app to any number of languages.


You can activate translation mode by clicking on “Help Us Translate” link.


All of the source code for this post can be found at:

Let’s create a RoR application by executing the following commands:

$ rails new welp
$ cd welp

Let’s create our main controller called “home” with a “index” action:

$ bundle exec rails g controller home index

We need to make sure our home controller and action are available in the routes. Edit config/routes.rb file and add the following:

[ruby title=”config/routes.rb” class=”lang:ruby”]
Rails.application.routes.draw do
get ‘home/index’
root ‘home#index’

Let’s start our server and make sure the index view can be loaded:

$ bundle exec rails s
$ open “http://localhost:3000”

Now let’s add the TML gem to our Gemfile. We will be using tml-rails gem that comes with extensions for Rails applications. We will also add a Dalli gem so we can use Memcache as our cache adapter:

[shell title=”Gemfile” class=”lang:bash”]
gem ‘tml-rails’
gem ‘dalli’

Install the gem by running:

$ bundle

To properly instantiate our library, we need to add an initializer file. All our settings and configurations will be kept there. Create a new file called config/initializers/tml.rb and add the following information:

[ruby title=”config/initializers/tml.rb” class=”lang:ruby”]
Tml.configure do |config|
config.application = {

config.cache = {
enabled: true,
adapter: ‘memcache’,
namespace: ‘translations’,
host: ‘localhost:11211’

config.logger = {
enabled: true,
path: “#{Rails.root}/log/tml.log”,
level: ‘debug’

We will cache all our translations using Memcache server and log debug information in log/tml.log file. There are many other options for caching translations data. For instance to cache translations using Redis, use:

[ruby title=”config/initializers/tml.rb” class=”lang:ruby”]
config.cache = {
enabled: true,
adapter: ‘redis’,
namespace: ‘translations’,
host: ‘localhost:6379’

If you prefer keeping all translations in memory of each process and load them from file system, you can use the release snapshot and point your cache to local files:

[ruby title=”config/initializers/tml.rb” class=”lang:ruby”]
config.cache = {
enabled: true,
adapter: ‘file’,
path: ‘config/tml’,
version: ‘current’

We will come back to file caching and releases in a separate post.

Keep in mind, if you disable cache, translations will be loaded directly from the API. This approach works great while you are in development or translation modes, but you should always cache translations in your production environment.

Our next step is to create our layout. Let’s update the application layout with the following:

[ruby title=”app/views/layouts/application.html.erb” class=”lang:ruby” mark=”2,14″]



<%= stylesheet_link_tag “application”, media: “all”, “data-turbolinks-track” => true %>
<%= javascript_include_tag “application”, “data-turbolinks-track” => true %>

<%= csrf_meta_tags %>

<%= tml_scripts_tag %>
<%= render ‘/layouts/navigation’ %>

<%= yield %>


Notice that on line 2 we use tml_html_attributes_tag which automatically adds lang and directional attributes to the HTML tag. On line 14 we add tml scripts that offer in-context translations and globalization metrics.

Let’s add the navigation include file.

[ruby title=”app/views/layouts/_navigation.html.erb” class=”lang:ruby” mark=”1,42″]
<%= tml_source(‘navigation’) do %>

<% end %>

On lines 1 and 42 we open and close a source block. All translation keys within the block will automatically be grouped and cached as a single source. If you have multiple pages using the same navigation include – it will automatically be used from the cache and used across all pages. We then use tr method to mark all content we want to translate.

Now we can update our main view.

[ruby title=”app/views/home/index.html.erb” class=”lang:ruby”]

<%= link_to(tr(‘More Cities’), ‘#’) %>

<%= tr(‘Welp {city}’, city: tr(‘Los Angeles’)) %>

<%= tr(‘The best way to find local businesses’) %>

<%= tr(“Search for everything from the city’s tastiest burger to the most renowned cardiologist.”) %>
<%= tr(‘What will you uncover in your neighborhood?’) %>

<%= link_to(tr(‘Create your free account’), “#”, class: “btn btn-primary”) %>

<%= tr(‘Best of Welp: {city}’, city: tr(‘Los Angeles’)) %>

<%=link_to(tr(‘See More’), ‘#’) %>

<%= tr(‘Restaurants’) %>

<% @restaurants.each_with_index do |restaurant, index| %>


<%= index + 1 %>.
<%= link_to(restaurant[:name], ‘#’) %>
<%= image_tag(“#{restaurant[:rating]}-stars.png”, title: trl(‘{num} out of {count|| star}’, num: restaurant[:rating], count: 5) ) %>
<%= tr(‘{count || Review}’, count: restaurant[:review_count]) %>


<%= tr(restaurant[:last_comment]) %>

<% end %>

<%= form_tag do %>



<% end %>

<%= tr(“Review of the day”) %>


<%= tr(‘[link: {user}] reviewed [link: {business_name}]’, { link: {:href => “”},
user: {:value => “Jane Smith”, :gender => “female”},
business_name: “Ricky’s Fish Tacos”
}) %>
<%= image_tag(“5-stars.png”, :title => trl(‘{num} out of {count || star}’, num: 5, count: 5)) %>

<%= tr(‘{count || Review}’, count: 234) %>

<%= tr(“You can’t beat flavorful crunchy tacos, free chips and delicious salsa, yummy burritos and enchiladas.”) %>
<%= link_to(tr(‘Read More’), “#”) %>

<%= tr(‘Welp on the go’) %>

<%= tr(“Get the Welp app on your mobile phone. It’s free and helps you find great, local businesses on the go!”) %>



You can see the source code for this post here:

You can also see various versions of Rails and different cache adapters used with this app here:

Now that the SDK is integrated into the application, let’s translate it. To put the application into translation mode, press Ctrl+Shift+I. When translation mode is activated, the application will send all your strings to our platform, register them and will start looking for translations from our UTM. The mode also allows you to review suggested translations, vote on them and let your translator team provide new suggestions. Proofreaders can review suggested translations and lock them into your application’s translation memory.

To deactivate translation, press Ctrl+Shift+I again.

To learn more about TML, visit the following url:

Get Started Today!

Create an account to get started now! No credit card required.

Get Started