The WebTranslateIt Blog · Page 13

i18n news and Product Updates about WebTranslateIt · Page 13

New in WebTranslateIt: Better Attributions

By Edouard on July 23, 2017

We made an update about how translation changes are attributed to people on WebTranslateIt.

Before this update, any translation change made was getting attributed to the name of the person making that change. While this is correct most of the time, it wasn’t right to say that a person translated a segment if the only thing that person did was flagging a translation as “to verify”.

From now on, instead of only tracking the person who made the last change, WebTranslateIt now tracks the name of the last translator and the name of the last proofreader and displays this information when you update a translation.

This change also now makes it possible to filter segments by last translator and last proofreader, which is useful if you want to check on the work translated by a specific translator. You will find these new filters in the filters section at the top of the translation interface.

We hope you will find these improvements useful. Thank you for using WebTranslateIt.

Want more? Follow us on Facebook and Twitter

Why Translating your application

By Edouard on July 5, 2017

Why should you translate your application?

Because it will open your app to new markets. You will get new customers/visitors

Only 26% of the world’s Internet population understands English. By localizing your application to their languages you will therefore gain customers.

Localization only is an accelerant, though. An application currently having a poor market fit in its current market probably won’t magically work in foreign markets too. You need to already have traction in order to get more revenue. Localizing an app which has troubles finding its market niche is likely to cost you more money than you will earn.

Let’s say your software’s annual revenues are $10,000 per year. You estimate that translating your app in Chinese will open you to the Chinese market and will make your revenue grow 10% a year thanks to that.

10% of $10,000 is $1,000. Given that translating your app into Chinese cost you $1000 it might be worth spending that money into development work or marketing in order to increase revenue before thinking about localizing your application.

Now, if your software annual revenue is $100,000 a year, this is a whole different story. 10% revenue growth represents $10,000 more per year. Growing your company worldwide can be a great way to increase your revenue, at the cost of an increased complexity.

Localizing increases complexity

By making your application available into more languages you will increase complexity. If you regularly update your application with new feature, your development team could deploy new features whenever they were ready.

Now the development team will deploy the new feature whenever the new feature is translated and the translations tested.

If your team has more than a few developers it is likely you will need to set up a strict workflow so new features are only deployed after they are translated and so that translators can work on a stable environment where no new segments to translate creep in while they are currently working. This typically slows down a new feature release by about a week. We’ll write an article about workflows for internationalization in the future.

It’s not only complexity due to translations

A few week in after having defined a proper workflow having a internationalized application will feel easier. After all with a good process in place and outsourcing the work to good companies things aren’t too difficult. But growing your organization worldwide is not only about translation work.

If you handle tech support for your app you will have to handle it in the supported languages too. It might mean hiring and training customer representatives in these new supported languages.

It might also mean to adapt your application to the local laws, secure local domain names, …

https://jedmahonisgroup.com/blog/localization-the-best-way-to-increase-international-sales-of-your-app

http://developingperspective.com/2014/01/22/171/

Get Started translating your application (part 1)

By Edouard on July 5, 2017

1.2 The fun part: extracting strings

In any case, internationalizing your application is a manual process where you extract all the translatable text out of file, and place it in a linguistic file, which compiles all the translatable text of your application.

Then, a mechanism to retrieve the translated text is setup, which lets the application display the translated text from a linguistic file, depending on the requested language.

Will that slow down my application? Usually no. Templates are usually cached into memory. In the rare case it’s not the linguistic file content is likely to be loaded in memory, and the lookup to find the translation is negligible on today’s hardware.

1.3 Best practices to write code and copy for i18n

Translators are not programmers. Writing good copy for i18n is not always easy for developers. Here are a few rules to write better copy for your internationalization.

1.3.1 Extract simple, complete sentences

Try to extract complete sentences that will make sense to a translator.

Original text: “Hello, good to see you.”

GOOD: Hello, good to see you # Perfect, the sentence makes sense
BAD: Hello,
good to see you # It can be hard for a translator to understand the context of one or the other string.

1.3.2 Include variables if your internationalization framework supports interpolations

Most internationalization frameworks let you interpolate variables. Choose your variable names appropriately, so translators can understand the segment in context.

Original text: Hello #{user.name}, Good to see you.

GOOD: Hello %{user_name}, good to see you # Perfect, the sentence makes sense
BAD: Hello
good to see you # Context can be difficult to understand.
# You don’t necessarily greet people “Hello username” in this order in other languages.
SO-SO: Hello %{var}, good to see you # Context is a bit difficult to understand.
# Give the variable a better name.

1.3.3 Don’t include untranslatable content

If something is not translatable, don’t include it in a linguistic file.

{$starttime|displaydatenotz:'hour'}

1.3.4 Avoid including code in text

Original text: <a href="urlblah" title="Hello!" onClick="$('thingy').toggle(); style="color: pink; font-size: 12px">Hello there!</a>

GOOD: Hello!
Hello there! # Perfect, the sentence makes sense, no code.
BAD: <a href="urlblah" title="Hello!" onClick="$('thingy').toggle(); style="color: pink; font-size: 12px">Hello there!</a> # Too much code! Translators will make mistakes in the code,
# which will break the feature.

Sometimes you have to, though:

Original text: Hello <strong>#{user.name}</strong>!

GOOD: Hello <strong>%{user_name}</strong> # Perfect, the sentence makes sense.
# There are some code but this is acceptable.
BAD: Hello # Context can be difficult to understand.
# You don’t necessarily greet people “Hello username” in this order
# in other languages.
BAD: Hello <strong>%{user_name} # As a rule of thumb, if you include some code in the translatable text,
# include it all the way.

1.3.5 Do repeat yourself

Remember, translators are not programmers! Translatable text is not the place to write clever code. In my experience, it’s better to repeat yourself than to write a clever sentence translators will have troubles translating.

Example:

Hi {if $to}{$to->getLinkText()}
{else}there{/if},
{if $user}{$user->name} {else}{$fromname} ({$fromemail})
was on our awesome website and {/if}{if $attending}thinks you should come along to
{if !$eventname}see{/if}{else}thinks you might be interested in
{if !$eventname}seeing{else}going to{/if}{/if}
{if $eventname}{$eventname}{else}{$headliner->getLinkText()}{/if} at
{$venue->getLinkText()} on {$startdate|displaydate:'shortdmy'}.

This kind of code needs a complete rewrite. It’s best to write conditionals, each containing one full sentence.

1.3.6 Use pluralization (if your framework supports it)

Pluralization is a way to change the spelling of a noun depending of the plurality of a variable.

Let’s consider this example: Less than #{@count} minutes.

It displays:

  • Less than 0 minutes if @count equals 0, which is correct.
  • Less than 3 minutes if @count equals 3, which is correct too.
  • Less than 1 minutes If @count equals 1, which is incorrect English.

Developers usually get around this by writing conditional around this sentence, creating two strings for the translators:

if @count equals 1
  then display “Less than 1 minute”
else
  then display “Less than %{@count} minutes”

The problem is that pluralization differs from one language to another. In French for instance, it’s spelled:

  • Moins de 0 minute if @count == 0
  • Moins de 1 minute if @count == 1
  • Moins de 3 minutes if @count == 3

So, the conditional works in English, but doesn’t work in French.

Even worse: languages such as Polish or Arabic have 4 and 6 plural rules, and languages such as Chinese or Japanese have no plural rules at all!

Thankfully Unicode publishes and maintains CLDR, a database listing the plural rules of most languages. Also, good internationalization frameworks take care of this complexity for you, so you will have to use it.

In your application, you will extract the text like so:

t(“less_than_x_minutes”, :count => @dogs.count)

And in your linguistic in English will look like so:

less_than_x_minutes:
  one: “less than %{count} minute”
  other: “less than %{count} minutes”

Which will translate in French:

less_than_x_minutes:
  one: “moins de %{count} minute”
  other: “moins de %{count} minutes”

In Russian:

less_than_x_minutes:
  one: "меньше %{count} минут"
  few: "меньше %{count} минут"
  many: "меньше %{count} минуты"
  other: "меньше %{count} минуты"

In Chinese:

less_than_x_minutes:
  other: "不到 %{count} 分钟"

1.4 Internationalizing database content

Internationalize database content is tricky. Handling the translation of this content depends on the nature of the content itself.

Is you database content static? For instance, is it a list of countries or a list of languages, then I would recommend using a unique identifier (such as a country code or language code), and translate this content in a linguistic file.

On my web application for instance I have a database containing all the languages in the world. Each language is identified by a ISO language code. I then use the language code to get the name of the country from a linguistic file.

Linguistic file:

languages:
  en: English
  fr: French
  es: Spanish
  da: Danish

The advantages are multiple. First, the kind of content is standard. It comes, once again from Unicode’s CLDR, which means it’s likely to be correct and won’t offend anyone. Second, this data was already translated on the CLDR repository, so I won’t have to translate this content by myself (This repository contains translated languages, scripts and territories in a YAML format). Lastly, we’re dealing with the real world, and this content is subject to changes: new counties appear, some disappear or get renamed. If that’s the case, it’s just a matter of updating this linguistic file from the source.

If you database content is fairly “dynamic”, for instance it is a list of products in a shop, then save the translations in database.

If you only need to translate one table, add one new column per language in your table to handle the translations. If you need to translate several tables, then create a dedicated table containing the translations of all tables.

[TODO: Develop]

1.5 Internationalizing Javascript

If you develop a web application containing Javascript, then you’re probably wondering how to internationalize the text contained in the Javascript code.

The good news is that there are several plugins for Javascript to help you with this task. For instance i18n-js i18n-node or i18next. They all work by extracting the translatable text into a separate file containing a JSON hash.

If you don’t have much text to translate, a leaner solution is to extract the translatable text to a file compatible with your server i18n framework, and make your server dump these translations as a JSON hash inside your HTML body like so.

window.I18n = {"translations":{"key1":"text1.","key2":"text2."}}

You can then recover your translations in Javascript by calling window.I18n[“translations”][“key1”].