Thursday, June 28, 2012

Internationalization

Facebook is currently available in over 70 languages, thanks to a framework that allows our user community to translate the text on Facebook. By integrating with Facebook, you can take advantage of our Translations framework immediately, so you can enjoy the benefits that translation can bring to your Platform application or website. If you are interested in Open Graph localization, please refer to Open Graph Internationalization.


Understanding Locales

The locales that Facebook supports are available in an XML file.
Facebook locales follow ISO language and country codes respectively, concatenated by an underscore.
The basic format is ''ll_CC'', where ''ll'' is a two-letter language code, and ''CC'' is a two-letter country code. For instance, 'en_US' represents US English.
There are two exceptions that do not follow the ISO standard: ar_AR and es_LA. We use these to denote umbrella locales for Arabic and Spanish, despite in the latter case having a few more specialized localizations of Spanish.
You can determine this information about a user by examining the locale field of the User Graph API object.

Support Locales in Social Plugins and the JavaScript SDK

If you're rendering a social plugin in an IFrame, Facebook automatically translates the text because it's based on the viewing user's locale.
If you're using XFBML, you need to load the JavaScript SDK in the appropriate locale for your site. For example, if your site is in Spanish, reference this script:
//connect.facebook.net/es_LA/all.js

Internationalizing your Application

The following steps assume you have created an application and have an application ID.

Preparing Your Application for Translation

In order to opt into the Facebook Translations framework, you need to set the native language for your application, then you need to decide into which languages you want your application translated.

Selecting Your Native Language

  1. Go to the My Applications page in the App Dashboard, where you initially configured your application.
  2. Select the application you want translated, then click Edit Settings.
  3. On the Advanced tab, under Contact Info select the Language in which your application is currently written, then save your selection. This selection determines the native language from which translations will occur. If your application is using "English (US)" as the native language you will not see the option and will not be able to change it, as the Open Graph translations need English as the native app language. See this blog post for details.

Choosing Languages for Translation

Once you configure your application's native language, you need to specify into which languages you want your application translated.
  1. Visit the Translations admin panel for your application. Select which application you want to translate from the dropdown menu in the upper right corner.
  2. Enable a language for translation. To enable translation of your application into a particular locale, select the row for the appropriate Language, then check the On check box for that locale. After checking it, users can see any strings that you mark as translatable, and can provide translations for them.
    Note: If this check box is NOT checked, the only people who can translate your application into this language are the application's developers (listed in the App Dashboard) and those designated as the language managers for this language in the Language Managers column.
Once you initiate the translation process, you'll return to the Translations dashboard when you need to do more administration. For now, these steps are the ones necessary to get started.

Registering the Text You Want Translated

Text can come from a lot of places, and it's important that if your application is available in a language that everything is translatable. The following is an exhaustive list of all places that you may find content you need to prepare for the translation process.

Text that gets rendered within your application or website.

Use FBML (for FBML applications) or XFBML (for Facebook websites or IFrame applications) markup tags for this text.

Text entered on facebook.com.

There is a list of static text about your application that you may enter on facebook.com which you may want to have translated. Each of these fields, when submitted or updated on Facebook, will automatically be registered on the Translations application on behalf of your application.
  • Application Name
  • Application Description
  • Tab Name
  • Attachment Text
  • Description (from the Application Profile)
  • About the Developers (from the Application Profile)
  • Text related to the Open Graph action types and aggregations
Once a translation is ready for any of these fields from the Translations application, it will automatically get used on Facebook without any further effort on the part of the developer.

Text sent through Facebook communication channels (like stream attachments).

Wrap the text using the FBML internationalization markup tags. Then, use intl.uploadNativeStrings if you want to register the text to be translatable by users before actually sending it.

Text contained within your databases.

You may have content that isn't rendered directly. For instance, if your application is an online store, you might store a list of item names of your inventory. In order for this text to be registered for translation, use intl.uploadNativeStrings to register all variations of the text that include each item from your database.
Note: This technique should not apply to strings that change frequently, or are user-generated. Each application has a static limit for the number of strings that may be registered at any given time, so it's important to avoid submitting dynamic content for translation.

Text contained within images or other non-text-based representations.

This content cannot be translated directly using Facebook Translations. If you want to serve internationalized images, you need to generate an image for each language you wish to support, and determine the user's locale (for example, via users.getInfo) to decide which image to serve them.

Marking Up Text for Translation

In order for you to submit structured text for use with Facebook Translations, there are a number of FBML and XFBML tags that have been added to accomplish this.
  • fb:intl -- The principal tag for making a string of text translatable.
  • fb:intl-token -- Replaces a token contained within fb:intl with its content.
  • fb:tag -- Renders an HTML tag. Only useful in conjunction with fb:tag-attribute.
  • fb:tag-attribute -- Contains the value of an HTML attribute specified by fb:tag that needs to be translatable.
  • fb:tag-body -- Contains the contents of an HTML tag specified by fb:tag. Only useful when fb:tag-attribute is needed.
  • fb:date -- Renders a date, adjusting the format correctly depending on the locale settings of the viewing user.
  • fb:fbml-attribute -- Similar to fb:tag-attribute, this contains the value of an attribute of an FBML tag, allowing the value to be translated. (FBML only)
  • fb:window-title -- Including this allows the window title of the current IFrame to be translatable. Note that this tag is only useful for Facebook Connect websites. (XFBML only)

Example Code

Let's say you have the following FBML in your application (or XFBML on your site):
Give <fb:name uid="4800348" useyou="false" firstnameonly=true/> 
a copy of "Catcher In the Rye"?
When Facebook renders the FBML, this would yield the proper English sentence 'Give James a copy of "Catcher In the Rye"?'. However, in order to render it in a way that is translatable, this line must be converted to the following:
<fb:intl desc="Asking whether user wants to give a book to someone">
  Give <fb:name uid="4800348" useyou="false"/> a copy of "{book-title}"?
  <fb:intl-token name="book-title">
      Catcher In the Rye
  </fb:intl-token>
</fb:intl>
Some things to note about this code:
  • The variable text (the book title) is a token formatted in curly brackets, since you don't want the actual book title to be part of the translatable text. This string, including the token, is what translators will need to be able to translate, using only the description as context. Wrapping the text in fb:intl-token places the variable text into the string at render time. The name attribute must be the string in the token(s) it is meant to replace. While these components generally can be ordered in any way, you should do something similar to the above, for the sake of readability and to prevent forgetting tokens.
  • The translatable message still contains the fb:name tag. This tag gets displayed as a token when the string is presented to translators, but the token is inserted by Facebook's translation system. You do not need to put it inside curly braces manually. The translator will be presented with the string, "Give {name} a copy of "{book-title}"?" in this case.
Once your FBML text uses these tags, it will be uploaded to the Translations application on the first canvas page load containing this FBML. After that initial page load, it will be translatable both in the Translations application as well as inline by Facebook users. Once the text is translated in, say, Spanish, it will appear to users browsing in the Spanish locale.

Best Practices

Much of this may become clearer after reading the best practices for advice on how to best prepare your applications. We strongly encourage you to do so.

Getting Your Application Translated

Now that you prepared your application or site for translation and registered all the text you want translated, you can start getting the text translated. Any Facebook user can translate your application, but it's much easier for people who have already authorized your application.
Users can translate text in two ways:
  • Inline while using your application.
  • Translating in bulk from the Translations application itself, which is an easy way to translate many strings of text at once.

Inline Translations

Users can translate strings inline if they've enabled this mode of translation. The screenshot below shows what inline translation mode looks like to a user. Underlined strings are available for translation (and voting) simply by right-clicking on the underlined text.

Users can enable inline translating by clicking the link in the Translations dialog on the status bar.

Bulk Translation

The Translations application has a user interface that allows translators to quickly and efficiently translate many strings. To direct a user to translate your application's strings in bulk, link them to https://www.facebook.com/translations/index.php?translate?app=<YOUR_APP_ID>, specifying your application ID.

Learn More

The best way to learn how your application can be translated is to actually try it out. The Facebook Translations application has a help guide for getting started with translating. This may help you better understand the process.

Managing the Translation Process

Use the Translations admin panel to manage the translation process for your applications.
  1. Visit the Translations admin panel for your application. If the default selection is not the application you wish to translate, select the right one from the dropdown in the upper right corner.

  2. Enable it for translation: To enable translation of your application into a particular locale, select the row for the appropriate Language, then check the On check box for that locale. After checking it, users can see any strings that you mark as translatable, and can provide translations for them.
    Note: If this check box is NOT checked, the only people who can translate your application into this language are the application's developers (listed in the App Dashboard) and those designated as the language managers for this language (see the Language Managers column).
  3. Review translated strings: Click the link for the language in the Language column. You are taken to the Browse Phrases tab for text in this language.
  4. Check the progress of the translation effort: The progress bar in the Translation/Approval Progress column gives you a high level idea of what percentage of your text is translated and/or been approved.
  5. Specify language managers: In the Language Managers column, specify which Facebook users can administer translations in the given language. These individuals may view, add, and remove translations regardless whether the application is open to all translators.
  6. Publish in that language: When you decide that the existing translations are sufficient, click the blue Publish link. It turns green and changes to ''Published'', which indicates that all users that view your text while viewing Facebook in this locale will see the translations.

Accessing Your Translations

Facebook Translations has multiple ways for you to view and access the text you've registered for translation, as well as the translations provided by Facebook users. The translation data retrieved from these methods may be used or stored however you choose.
You can always view and edit your text and translations from the Translations admin console. However, you can't export translations from the console currently. You can get the translations programmatically.
There are two programmatic ways for accessing translation data:
  • Calling the intl.getTranslations API method. Call this method to easily query all of your translations for a particular language.
  • Querying the translation FQL table. Query this table for a very select set of translation data.

Best Practices

We may make many assumptions when working with text in code, which may not always hold true in other languages. To help you prepare your application for most languages and quirks, we offer these best practices and lessons learned by the Facebook internationalization team. Unless otherwise indicated, these examples apply to both FBML and XFBML markup.

Be Descriptive

In general, text under 20 characters should have a description (use the desc attribute). A word like "Poke" can vary if it is used as a noun or a verb. Facebook Translations works by creating a hash value from the text and description of the phrase. That means that even a slight change to the original text or description will cause your string to be counted as a completely new one. So err on the side of starting off with a complete description you won't have to clarify later. For example, do this:
<fb:intl desc="Label for name of photo album">Name:</fb:intl>
In some languages, the word for "name" is different depending on whether it's the name of a person, a place, or an object. A description here allows a translator to choose the correct word for this label.
Descriptions should usually indicate context as well as meaning. This is especially important for things like link text that are presented as part of a larger grammatical structure like a sentence.
So do this:
<fb:intl desc="In, 'X's photos are ready to view.'">{name}'s photos</fb:intl>
In languages where nouns change depending on whether they're used as the subject or object of a sentence, this description will allow translators to use the correct form.

Don't Translate Markup

Don't include HTML markup in a translatable string; split the text into multiple translatable strings. Otherwise, translators will be able to modify your markup. Never put tags with behavior such as <a> inside a translatable string, since a translator would be able to make changes to the tag's contents. This is a better way to render an anchor:
<fb:intl>Click {=here} to continue.
  <fb:intl-token name="=here">
<a href="xyzzy">
  <fb:intl desc="In 'Click here to continue'">here</fb:intl>
</a>
  </fb:intl-token>
</fb:intl>

Use CSS instead of Markup

Use CSS rather than markup to confine text to particular parts of the page or to style your text. For example, if you have the text "Next Page" and you want each word on a separate line, put it in a <div> with a maximum width rather than putting a <br> tag in between the two words. Don't split the text into separately translatable units since it will prevent translators from changing word order if needed.
Don't do either of these:
<fb:intl>Next<br/>Page</fb:intl>

<fb:intl>Next</fb:intl><br/><fb:intl>Page</fb:intl>
If a language needs the word for "Page" to come before the word for "Next", it is impossible to translate correctly.
Rather, do this:
<div class="limited-width-box"><fb:intl>Next Page</fb:intl></div>
With appropriate CSS, the browser will word wrap the string appropriately.

Translating Attributes of HTML Tags

There are some HTML tags that have attributes that can take on text values, like the "value" attribute of an <input> tag or the "alt" text of an image. To make situations like these translatable, use fb:tag-attribute. You would format markup for a form like this:
<input type="submit"> 
  <fb:tag-attribute name="value"> 
    <fb:intl desc="Button action: Submit a form">Click here</fb:intl> 
  </fb:tag-attribute> 
</input>

Avoid Layouts Relying on Precise Sizing

Try not to use layouts that depend on the precise onscreen sizes of pieces of text in the original language. For any piece of text, in some languages it is likely to be shorter and in some it will be longer (sometimes significantly so in either direction.) If you have sized your user interface elements such that your text just barely fits, your application will probably not work well in a language with longer words.

Assume Word Order Will Change

Assume that a translator will have to change the word order of every sentence. In particular, don't try to assemble sentences from smaller separately-translatable fragments, because even if you provide excellent descriptions, it's likely you will make it impossible for a translator to come up with a grammatically correct translation. Instead, expand all the possible cases out into separate translatable sentences and choose a complete sentence in your code.
Here's a simple example to avoid:
<fb:intl>You are eating</fb:intl> <fb:intl>at home.</fb:intl>
<fb:intl>You are eating</fb:intl> <fb:intl>at a restaurant.</fb:intl>
Here the code is printing the beginning of the sentence, which doesn't change in English, then choosing one of two possible endings. This is impossible to translate correctly to Chinese, where the phrases for "at home" and "at a restaurant" need to come before the word for "eating".
In this case, use separate phrases:
<fb:intl>You are eating at home.</fb:intl>
<fb:intl>You are eating at a restaurant.</fb:intl>
Here the code chooses one of two complete sentences. The translator can adjust the word order of both sentences as needed, and these can be correctly translated into every language.
Or, say you have a phrase like "You have {number} photos." where you use the word "photo" when the number is 1, expand this out into separate complete sentences line, "You have one photo." and "You have {number} photos.", like this:
<fb:intl>You have one photo.</fb:intl>

<fb:intl>You have {number} photos.
    <fb:intl-token name="number">5</fb:intl-token>
</fb:intl>

Don't Hardcode Punctuation

Different languages use different punctuation symbols; for example, Chinese has two different comma characters that are used in different contexts. And Japanese uses its own end-of-sentence character, which is not an English-style period. In general if you allow translators to translate complete sentences (including periods and commas) this won't be as big an issue for you. So you should include punctuation within the fb:intl tags:
<fb:intl>You have mail.</fb:intl>

<fb:intl>Favorite color:</fb:intl> &lt;input ...>
Including the colon as part of the translatable string means translators can substitute another punctuation mark if applicable, or can insert whitespace between the text and the colon (as is done in French, for example.)

Messing with Your <head> (XFBML Only)

Generally speaking, XFBML will work anywhere in the <body> tag of your page. However, this doesn't account for the title of the window. You can set a window title using the fb:window-title tag, placing it anywhere in your document where normal XFBML can be parsed. It will take the rendered contents of the tag as your document's title. You could now enable a translated window title with the following:
<fb:window-title> 
  <fb:intl desc="Title of a Web page">Welcome!</fb:intl> 
</fb:window-title>

No comments:

Post a Comment