Guide to Locales - Best Practices

Introduction

The locale system's functionality relies heavily on localization best practices. The system cannot translate phrases as code runs, and instead relies on pre-translated phrases in a lexicon. This document lists best practices and recommendations to ensure that you use easily-translated phrases. If you pay translators to localize your custom strings, these practices can significantly lower translation costs.

Important:

Whenever you localize a phrase, make certain to check whether a similar phrase already exists in the lexicon. If one does, use it. Reuse of phrases significantly lowers translation costs.

Notes:

  • This document's examples use various languages to better illustrate likely use scenarios. For example, you are likely to localize error messages in a Perl script, while titles or headings will generally appear in a Template Toolkit file. 
  • Most of the examples in this document use advanced bracket notation methods to illustrate likely use scenarios. For more information, read CPAN's Locale::Maketext::Utils documentation.

Make certain that phrases are complete sentences.

Do not use partial phrases, or pass another phrase into the middle of a single phrase.

Two exceptions exist for this rule:

  • Labels or titles that use title case should not be complete sentences.
  • Partial phrases during a specific process may use an ellipsis character () to convey their context.

    Notes:

    • Do not confuse the ellipsis character () with three consecutive periods (...).
    • We strongly recommend that you include a single space on each side of the ellipsis character, unless the ellipsis ends the phrase.
Correct?
Phrase
Explanation

maketext('The system set up your email address “[_1]” on your domain.', $email) This example passes a single phrase that is a complete sentence to the locale system. It uses bracket notation to display the $emailvalue.
maketext('The system set up your email address') . $email . maketext('on your domain.')

This example splits the sentence into two separate phrases:

  • The system set up your email address
  • on your domain.

Because neither of these phrases is a complete sentence, this method presents a translation problem.

maketext('The system set up your “[_1]” “[_2]” on your domain.', 'email address', $email) This example splits the sentence into two separate phrases:
  • The system set up your on your domain.
  • email address 
Because email address is not an untranslated variable, it must remain with the rest of the phrase.
maketext('Starting the update process …')

or

maketext(' … Done!')
This example is correct even though it is not a complete sentence. The ellipsis character conveys the sentence's context to translators.

Do not use bare variables

Do not use bare variables, unless the variable is clearly separated from the text. Whenever possible, we suggest that you surround bracket notation variables in phrases with double curly quotes (“”).

  • You are more likely to notice issues with partial phrases if curly quotes surround all of your variables.
  • Curly quotes help translators understand that a variable will appear in the phrase in a specific location. 
    • For example, The new value is  “”. will make more sense to translators than The new value is .

Correct?

Phrase

Explanation

 

maketext('The system set up your email address “[_1]” on your domain.', $email)

This example correctly uses a bracket notation variable in curly quotes.

 

maketext('The system set up your [_1] [_2] on your domain.', 'email address', $email)

 Because this example includes bare variables, the partial phrase in the first variable is easier to miss:

The system set up your email address user@example.com on your domain.

With curly quotes around the variables, the partial phrase becomes obvious:

The system set up your “email address” “user@example.com” on your domain.

 

 

maketext('The new value is “[_1]”.', $value)

This example correctly uses a bracket notation variable in curly quotes.

 

maketext('The new value is [_1].', $value)

Because this example includes bare variables, it may confuse translators. Phrases that include curly quotes show translators the specific locations in which variables will display.

  • In The new value is “”., the variable location is obvious. 
  • The new value is . appears to be an incomplete sentence.

Remember:

Translators generally do not view code directly, and will only see the locale system's phrases, without their contexts.

 

maketext('The system received the following error message: [_1]', $error)

This bare variable is correct, because the colon (:) clearly separates the variable from the phrase.

Note:

When you use a colon to separate a phrase from a bare variable, make certain to include a single space between the colon and bare variable. 

 

Labels and titles

Labels and titles should use title case.

  • Title case capitalizes the first letter of each word in a label or title. For example: This Is My Label
  • Labels and titles should not include punctuation. 
  • In general, labels and titles will only include a few words.

Correct?

Phrase

Explanation

 

<h3>[% locale.maketext('Reseller Center' ) %]</h3>

or

[% locale.maketext('Your Domain' ) %] <input type= "text"  name= "domain" >

These examples correctly uses title case for a heading and an interface label, respectively.

 

<h3>[% locale.maketext('Reseller center' ) %]</h3>

or

[% locale.maketext('Your domain' ) %] <input  type= "text"  name= "domain" >

 These examples use sentence case. Because this causes the heading or label to appear similar to a partial phrase, it may cause difficulties for translators.

 

[% locale.maketext('Enter The Name Of Your Domain.' ) %]

This example incorrectly uses title case. Because the localized phrase is a complete sentence, you should not treat it as a label or title for localization purposes. Write complete sentences in sentence case, even if the phrase's position in the interface's layout is as a label or title.

 

Localized phrases should not include formatting

Do not include formatting in localized phrases (for example, extra whitespace, tabs, newlines, or other markup).

  • Formatting is almost always specific to a single usage of the phrase. This lessens the phrase's reusability, which often raises translation costs.
  • The locale system may experience errors with some formatting.
  • Formatting markup may confuse translators or other developers.

Note:

Use the output bracket notation method to add specific formatting or characters to localized phrases. For more information, readCPAN's Locale::Maketext::Utils documentation.

Correct?

Phrase

Explanation

 

<h3>[% locale.maketext(' Reseller Center' ) %]</h3>

In this example, formatting tags are correctly outside of the locale.maketextcall.

 

[% locale.maketext('<h3> Reseller Center</h3>' ) %]

Because this example's formatting is included within the translated phrase, it may cause translation problems.

 

Avoid colloquialisms, jargon, and other dialect-specific words or phrasing

Many colloquialisms or "slang" terms do not translate well. Some normal phrases in one language may even be offensive when translated. For this reason, we strongly recommend that you avoid these words and phrases wherever possible. Precision that may seem unnecessary in one language could be vital in another language.

If you plan to add many new phrases to the locale system, an understanding of Global English will help you write easily translated phrases. 

  • For more information, we suggest that you begin with TECHwhirl's Writing for Global Readiness article. Many excellent books, articles, and other resources exist for this topic.
  • If you use a paid translation company, they may have additional resources to help you write easily translated phrases.

Mark unlocalized text

Mark words or phrases that you do not wish to localize with the asis bracket notation. This prevents localization of company names, trademarks, and other important terms.

Correct?

Phrase

Explanation

 

<p>[% locale.maketext('The system installed [asis,Ruby On Rails] on the domain.') %]

In this example, the asis tag ensures that the term Ruby On Railsdoes not change.

 

<p>[% locale.maketext('The system installed Ruby On Rails on the domain.') %]

Your translation service might accidentally translate Ruby On Railsinto something meaningless, such as Gems on Trains.

  

Numeration

You can use the numerate function to properly localize singular and plural text. If you append the .size suffix to the end of a variable, it returns the size of the variable. 

In the following example, the reverse_dns_hostname variable is a list of strings, and may contain multiple values: 

[% locale.maketext('A reverse [output,abbr,DNS,Domain Name Service] lookup on the IP address returned the host[numerate,_1,name,names] [list_and_quoted,_2].', reverse_dns_hostnames.size, reverse_dns_hostnames) %]

In this example, the system determines the size of the reverse_dns_hostnames variable. Then, the system passes it through the _1 identifier to the numerate function, which determines whether to use the singular term name or the plural term names

The system then passes the actual contents of the reverse_dns_hostnames variable through the _2 identifier to the list_and_quotedfunction, which makes a list out of the values and puts them in quotes.

In the interface, this template code could display the following results: 

A reverse DNS lookup on the IP address returned the hostname "hostname.example.com".

Create reusable phrases

The number of individual phrases in a lexicon correlates directly to the cost of translation.

  • For this reason, we strongly recommend that you reuse existing phrases whenever possible. 
  • Whenever you add new phrases, write them to be as reusable as possible.

Correct?

Phrase

Explanation

 

[% locale.maketext(' List [numf,_1] of [numf,_2].',10,12 ) %]

 The numf bracket notation method will add the number (10) to the phrase when the localized text displays.

You can use this method to display the same phrase with many numbers:

  • List 10 of 12.
  • List 25 of 32.
  • List 100 of 400.

However, this method only adds a single phrase to the lexicon to translate:

  • List [numf,_1] of [numf,_2].
 

[% locale.maketext('List 10 records. ' ) %]

This example incorrectly hardcodes the number ( 10 ) into the phrase.

Each of the following similar phrases would require its own entry in the lexicon, and would be translated separately:

  • List 10 records.
  • List 25 records.
  • List 100 records.
 

[% locale.maketext('Save' ) %]

This example uses a simple phrase that you could use in many instances.

 

[% locale.maketext('Save The Spreadsheet Changes ') %]

This example follows all of the requirements for the locale system, but is very specific to a single usage.

Unless there is a good reason for specific labels (for example, in an interface with several different Save options), we recommend that you generalize labels to minimize the number of lexicon strings to translate.

 

  • 8 Users Found This Useful
Was this answer helpful?

Related Articles

The cPanel Interface

For  cPanel  &  WHM  version  58 Overview The cPanel interface is...

User Preferences

For cPanel & WHM version 58 Overview This document outlines how to access your cPanel...

Manage External Authentications

For cPanel & WHM version 58 Overview Manage credentials Additional documentation...

What is cPanelID?

In This Article:  Overview ServicesHow to get a cPanelID cPanelID External...

Guide to cPanel Interface Customization - cPanel Style Development

Introduction You can develop custom styles that modify the appearance of the cPanel interface....