Golden Gate Bridge Syndrome & TML

Golden Gate Bridge Syndrome” is a term we coined when my team was trying to implemented i18n framework at Geni.com, a Rails-based web application.

The Golden Gate Bridge Syndrome was based on the idea that by the time the painting crew finishes painting one side of the bridge, they must start painting it again, since other parts of the bridge have already become rusty. Painting the Bridge is an ongoing task and the primary maintenance job.

So how does it relate to Internationalization and Localization?

At Geni.com, localizing the website became a priority after it had already up and running for months, with many features and functions. Our goal was to find a way to localize the site with minimal distractions to our ongoing development. This became challenging, since we had to work in a separate SCM branch and water down the branch with constantly changing content.

By the time we were finally able to extract majority of the strings from our rapidly changing site into YAML resources (we had over 5,000 phrases at that time) we learned that a significant number of the strings were either changed or moved to other section (breaking our file organization). We realized that managing strings in resource files was not a scalable solution for us and we had to come up with a different approach. Realizing this early enough saved us a lot of money on translating string that were no longer used.  We learned that as long as you innovate, you will never be 100% translated. Translation is like painting the bridge – an ongoing process, that will never stop as long as you add/change text in your application. Making strings/labels/descriptions/alt tags/values into “keys” and putting them into resource bundles creates an enormous overhead, slows down development, irritates engineers and complicates the code.

At that time our strings used custom keys for the resource ids:
[ruby];[/ruby]

Without looking at the actual resources, it was impossible to guess the content of the message.  We decided to abandon this approach and start using strings themselves as the keys and the values for the default language.
[ruby][/ruby]

At this point we decided to completely abandon the resource files and create a custom backend for i18n. And this is how tr8n framework has started.

As our strings became more and more complicated, we had to come up with a more sophisticated syntax that could accommodate such strings.

Contextualization Based On Description

Every once in a while we had a situation where same strings had different meanings based on their context. We solved this problem by introducing string description. The string together with the description created a unique string identifier for the translation key:

[ruby]


[/ruby]

Even though the label of the above keys is identical, two distinct keys are registered by the library. The description served two purposes: it created a unique identifier for the translation key and it also used as a context for the translator who may not have access to the user interface.

Numeric Rules

Many strings in our system contained numbers and had to be translated according to the rules of the viewer’s language. We wanted to come up with a flexible syntax that would allow us to encode the strings according to the English rules and allow us to translate them accurately to any other language. We also wanted to allow any number of context tokens in a single string, without breaking it into pieces.

[ruby]




[/ruby]

Gender Rules

All users in our system provided genders during registration. We wanted to come up with syntax that could help us provide accurate translations based on genders.

[ruby]

[/ruby]

Sometimes tokens were implied, so we had to come up with a way to indicate such cases:

[ruby]

[/ruby]

Every string in our system had a way to refer to the viewing user.

[ruby]

[/ruby]

Multiple translations can be provided based on the implied viewing user context.

List Rules

Often enough we had to talk about multiple users in a single sentence. Normally we would list such users by name.

[ruby]


[/ruby]

Date Rules

Sometimes we wanted to condense translation syntax based on dates. Instead of creating nested If statements, we could simply provide it in one line:

[ruby]

[/ruby]

Decorations

All of the above example usually had some kind of decorations involved. We want to have the ability to change the decorations without affecting the strings:

[ruby]
#{text}“}
}) %>

{$0}”
}) %>

{$0}”
}) %>
[/ruby]

Some data tokens and decoration tokens were repeated often enough that we configured them on the application level and could abandon them altogether.

[ruby]

[/ruby]

Language Cases

We wanted to have ability to properly change the ending of the data token values based on the rules of the languages they are translated to.

[ruby]

{$0}”
}) %>

# in Russian would be:

[/ruby]

And this is how Translation Markup Language (TML) was born. The markup language is very flexible, new tokens types and rules are being added to further enhance its capabilities.

The language is supported on all major platform – both server-side and client-side.

To learn more about TML, please visit:
http://welcome.translationexchange.com/docs/tml/basics

Get Started Today!

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

Get Started