Skip to content

Better translations for time_ago_in_words #2255

@gravitystorm

Description

@gravitystorm

(Moving https://trac.openstreetmap.org/ticket/4968 here for better visibility.)

In rails there is a time_ago_in_words helper (aka distance_of_time_in_words_to_now) that we use extensively. The strings it returns are actually just the same as the distance_of_time_in_words helper, e.g. "3 years" or "about 1 hour"; that is, they doesn't come with 'ago' attached.

The logic behind the helper is fairly complex. The default translations come from the rails-i18n gem, we don't control them ourselves.

We then use these "distance_in_words" strings to create what I'll refer to as "distance_in_words_ago" strings. In English this is very easy, since every possible output of the helper can just have "ago" tacked on the end. For example

  • English: "3 years" -> "3 years ago"

However, this is not the case in other languages, where to be gramatically correct, in certain cases the original "distance_in_words" needs tweaking. For example:

  • Hungarian: "2 óra" -> "2 órája"
  • German: "2 Tage" -> "vor 2 Tagen"

Other people identified the problem many years ago, and so since rails 3.2 the time_ago_in_words helper accepts a :scope, which allows you to pick a different i18n scope for the localisation. For example, instead of using the default en.datetime.distance_in_words from the rails-i18n gem, we could define our own distance_in_words_ago hierarchy:

en:
  datetime:
    distance_in_words_ago:
      about_x_hours:
        one: about 1 hour ago
        other: about %{count} hours ago
      about_x_months:
        one: about 1 month ago
        ...

We would then update our views, so instead of using the output from the helper in a '.ago' translation, we would set the i18n scope in the helper, and use the output directly. For example:

       <% end %>
-      ... <%= t ".ago", :time_in_words_ago => time_ago_in_words(trace.timestamp) %></span>
+      ... <%= time_ago_in_words(trace.timestamp, :scope => :'datetime.distance_in_words_ago') %></span>
       <%= link_to_if trace.inserted?, t(".map"), { :controller => "site", :action => "index", :mlat => trace.latitude, :mlon => trace.longitude, :anchor => "map=14/#{trace.latitude}/#{trace.longitude}" }, { :title => t(".view_map") } %> /

This means that our translators could translate all of the 'distance_in_words_ago' strings in a grammatically correct fashion.

Ultimately, this could also be fixed by two upstream changes. The first would be for the rails-i18n gem to include a 'distance_in_words_ago' translation hierarchy itself, which could be used by hundreds of projects beyond ours. And the secondly, the time_ago_in_words ActionView helper could then return 'distance_in_words_ago' style strings by default, which I think would be more helpful than now. But unless there's any strong opinions, I would suggest we fix this locally first.

My proposal it therefore:

  • Add an en.datetime.distance_in_words_ago hierarchy to our own en.yml.
  • Give the translators a few weeks opportunity to translate them.
  • Update our usage of the time_ago_in_words and distance_of_time_in_words_to_now helpers to use the new hierarchy using the scope parameter.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions