Actions

Difference between revisions of "Embedding translatable strings in the template"

From Joomla! Documentation

(New page: In the template itself translations are handled using the ''JText'' static class. It is referred to as “static” because it does not require instantiation as an object before its method...)
 
m (Changed to Geshi formatting and fixed the table.)
Line 4: Line 4:
 
Most text strings can be translated using the “_” (underscore) method. For example, suppose your template contains the English text “Welcome” which needs to be made translatable.
 
Most text strings can be translated using the “_” (underscore) method. For example, suppose your template contains the English text “Welcome” which needs to be made translatable.
  
<nowiki><?php</nowiki>
+
<source lang="php"><?php
    echo 'Welcome';
+
    echo 'Welcome';
?>
+
?>
 +
</source>
  
 
Then you would replace the static string like this
 
Then you would replace the static string like this
  
<nowiki><?php</nowiki>
+
<source lang="php"><?php
    echo JText::_( 'Welcome' );
+
    echo JText::_( 'Welcome' );
?>
+
?>
 +
</source>
  
 
This would cause the translation system to search the appropriate language file for “''WELCOME''” on the left-hand side of an equals sign. The search is case-insensitive. If this language definition string is encountered
 
This would cause the translation system to search the appropriate language file for “''WELCOME''” on the left-hand side of an equals sign. The search is case-insensitive. If this language definition string is encountered
  
WELCOME=Welcome!
+
<source lang="ini">WELCOME=Welcome!</source>
  
 
then the effect will be to output the string “Welcome!” to the browser. If the user switches to the German language then the German language definition file will be search for “''WELCOME''” and this time might encounter the string
 
then the effect will be to output the string “Welcome!” to the browser. If the user switches to the German language then the German language definition file will be search for “''WELCOME''” and this time might encounter the string
  
WELCOME=Wilkommen
+
<source lang="ini">WELCOME=Wilkommen</source>
  
 
and so “Wilkommen” will be sent to the browser. Importantly, if the user switches to German but there is no German language file present, or the appropriate string does not appear in the German language file, then Joomla will fall back to sending the untranslated string “''Welcome''” to the browser.
 
and so “Wilkommen” will be sent to the browser. Importantly, if the user switches to German but there is no German language file present, or the appropriate string does not appear in the German language file, then Joomla will fall back to sending the untranslated string “''Welcome''” to the browser.
Line 31: Line 33:
 
For example, suppose you have the string “Donations of 12.45 GBP have been received” where the amount comes from a variable, $donations”, say. You could split the string into two like this
 
For example, suppose you have the string “Donations of 12.45 GBP have been received” where the amount comes from a variable, $donations”, say. You could split the string into two like this
  
JText::_( 'Donations of' ) . “ $donations GBP “ . JText::_( 'have been received' )
+
<source lang="php">
 
+
JText::_( 'Donations of' ) . “ $donations GBP “ . JText::_( 'have been received' )
 +
</source>
 
with language definition strings
 
with language definition strings
  
DONATIONS OF=Donations of
+
<source lang="ini">
HAVE BEEN RECEIVED=have been received
+
DONATIONS OF=Donations of
 
+
HAVE BEEN RECEIVED=have been received
 +
</source>
 
but this does not work well in languages where the embedded data is not in a similar place in the translated string. Instead use the ''sprintf'' method like this
 
but this does not work well in languages where the embedded data is not in a similar place in the translated string. Instead use the ''sprintf'' method like this
  
JText::sprintf( 'Donations have been received', $donations )
+
<source lang="php">
 
+
JText::sprintf( 'Donations have been received', $donations )
 +
</source>
 
with language definition string
 
with language definition string
  
DONATIONS HAVE BEEN RECEIVED=Donations of %.2f GBP have been received
+
<source lang="ini">
 
+
DONATIONS HAVE BEEN RECEIVED=Donations of %.2f GBP have been received
 +
</source>
 
You can include more than one format specifier in a translation string. Substitutions are carried out in order so this works as expected
 
You can include more than one format specifier in a translation string. Substitutions are carried out in order so this works as expected
  
JText::sprintf( 'String with numbers in it', $num1, $num2, $num3 )
+
<source lang="php">
 
+
JText::sprintf( 'String with numbers in it', $num1, $num2, $num3 )
 +
</source>
 
with language definition string
 
with language definition string
  
STRING WITH NUMBERS IN IT=First %d, second %d, third %d
+
<source lang="ini">
 +
STRING WITH NUMBERS IN IT=First %d, second %d, third %d
 +
</source>
  
 
==== Syntax of format specifiers ====
 
==== Syntax of format specifiers ====
 
The format specifier consists of a percent sign (''%''), followed by one or more of these elements, in order:  
 
The format specifier consists of a percent sign (''%''), followed by one or more of these elements, in order:  
 
+
{| class="wikitable"
 
+
{| class="prettytable"
+
 
| <center>'''Order'''</center>
 
| <center>'''Order'''</center>
 
| '''Type'''
 
| '''Type'''
Line 99: Line 106:
  
 
|-
 
|-
| <center>6.</center>
+
| rowspan="13" | <center>6.</center>
| Type
+
| rowspan="13" | Type
 
| colspan="2" | Mandatory. The type of the argument data. Possible types are:
 
| colspan="2" | Mandatory. The type of the argument data. Possible types are:
  
Line 157: Line 164:
 
For example, suppose we have the following code
 
For example, suppose we have the following code
  
echo JText::sprintf( 'Balls in the bucket', $number, $location );
+
<source lang="php">
 +
echo JText::sprintf( 'Balls in the bucket', $number, $location );
 +
</source>
  
 
with this language translation string
 
with this language translation string
  
BALLS IN THE BUCKET=There are %d balls in the %s
+
<source lang="ini">
 +
BALLS IN THE BUCKET=There are %d balls in the %s
 +
</source>
  
 
Then if
 
Then if
  
$number = 3
+
<source lang="php">
$location = 'hat'
+
$number = 3
 +
$location = 'hat'
 +
</source>
  
 
this would output “There are 3 balls in the hat”. But consider if you wanted to change the translation to
 
this would output “There are 3 balls in the hat”. But consider if you wanted to change the translation to
  
BALLS IN THE BUCKET=The %s contains %d balls
+
<source lang="ini">
 +
BALLS IN THE BUCKET=The %s contains %d balls
 +
</source>
  
 
This would now output “The 3 contains hat balls” which is clearly nonsense. Rather than change the code, you can indicate in the translation string which argument each of the placeholders refer to. Change the translation to
 
This would now output “The 3 contains hat balls” which is clearly nonsense. Rather than change the code, you can indicate in the translation string which argument each of the placeholders refer to. Change the translation to
  
BALLS IN THE BUCKET=The %2$s contains %1$d balls
+
<source lang="ini">
 +
BALLS IN THE BUCKET=The %2$s contains %1$d balls
 +
</source>
  
 
and the output becomes “The hat contains 3 balls” as expected.
 
and the output becomes “The hat contains 3 balls” as expected.
Line 180: Line 197:
 
An added benefit of being able to number the arguments is that you can repeat the placeholders without adding more arguments in the code. For example, change the translation to
 
An added benefit of being able to number the arguments is that you can repeat the placeholders without adding more arguments in the code. For example, change the translation to
  
BALLS IN THE BUCKET=The %2$s contains %1$d balls, so there are %1$d balls in the %2$s
+
<source lang="ini">
 +
BALLS IN THE BUCKET=The %2$s contains %1$d balls, so there are %1$d balls in the %2$s
 +
</source>
  
 
and this will correctly output “The hat contains 3 balls, so there are 3 balls in the hat”.
 
and this will correctly output “The hat contains 3 balls, so there are 3 balls in the hat”.

Revision as of 05:57, 17 August 2008

In the template itself translations are handled using the JText static class. It is referred to as “static” because it does not require instantiation as an object before its methods may be used.

Contents

Simple text strings

Most text strings can be translated using the “_” (underscore) method. For example, suppose your template contains the English text “Welcome” which needs to be made translatable.

<?php
    echo 'Welcome';
?>

Then you would replace the static string like this

<?php
    echo JText::_( 'Welcome' );
?>

This would cause the translation system to search the appropriate language file for “WELCOME” on the left-hand side of an equals sign. The search is case-insensitive. If this language definition string is encountered

WELCOME=Welcome!

then the effect will be to output the string “Welcome!” to the browser. If the user switches to the German language then the German language definition file will be search for “WELCOME” and this time might encounter the string

WELCOME=Wilkommen

and so “Wilkommen” will be sent to the browser. Importantly, if the user switches to German but there is no German language file present, or the appropriate string does not appear in the German language file, then Joomla will fall back to sending the untranslated string “Welcome” to the browser.

Strings containing formatted fields

Sometimes it is necessary to include specially formatted fields within a string to be translated. This usually happens where numbers are involved but can occur for dates and times or when precise formatting instructions are required. If the strings were not to be translated the standard PHP functions printf and sprintf could be used. The printf function outputs a string formatted using embedded formatting instructions; the sprintf function returns a string formatted using the same embedded formatting instructions.

The JText class provides wrapper methods for the printf and sprintf functions allowing static text to be translated while also allowing formatted fields to be embedded using the same syntax as the PHP functions.

For example, suppose you have the string “Donations of 12.45 GBP have been received” where the amount comes from a variable, $donations”, say. You could split the string into two like this

JText::_( 'Donations of' ) .$donations GBP “ . JText::_( 'have been received' )

with language definition strings

DONATIONS OF=Donations of
HAVE BEEN RECEIVED=have been received

but this does not work well in languages where the embedded data is not in a similar place in the translated string. Instead use the sprintf method like this

JText::sprintf( 'Donations have been received', $donations )

with language definition string

DONATIONS HAVE BEEN RECEIVED=Donations of %.2f GBP have been received

You can include more than one format specifier in a translation string. Substitutions are carried out in order so this works as expected

JText::sprintf( 'String with numbers in it', $num1, $num2, $num3 )

with language definition string

STRING WITH NUMBERS IN IT=First %d, second %d, third %d

Syntax of format specifiers

The format specifier consists of a percent sign (%), followed by one or more of these elements, in order:

Order
Type Values
Description
1.
Sign + or - Optional. Forces a sign (+ or -) to be used on a number. By default, only the – sign is used on a number if it's negative. This specifier forces positive numbers to have the + sign attached as well.
2.
Padding <space>

or 0

or '<char>

Optional. Character to be used for padding the results to the correct string size. May be a space character or a 0 (zero character). The default is to pad with spaces. An alternative padding character can be specified by prefixing it with a single quote ().
3.
Alignment <null> or - Optional. Determines if the result should be left-justified or right-justified. The default is right-justified; a - character here will make it left-justified.
4.
Width Number Optional. Number of characters (minimum) that the conversion should result in.
5.
Precision Number Optional. Number of decimal digits that should be displayed for floating-point numbers. When using this specifier on a string, it acts as a cutoff point, setting a maximum character limit to the string.
6.
Type Mandatory. The type of the argument data. Possible types are:
%
A literal percent character. No argument is required
b
The argument is treated as an integer and presented as a binary number.
c
The argument is treated as an integer and presented as the character with that ASCII value.
d
The argument is treated as an integer and presented as a signed decimal number.
e
The argument is treated as scientific notation (e.g. 1.2e+2). The precision specifier stands for the number of digits after the decimal point since PHP 5.2.1. In earlier versions, it was taken as the number of significant digits (one less).
u
The argument is treated as an integer and presented as an unsigned decimal number.
f
The argument is treated as a float and presented as a floating-point number (locale aware).
F
The argument is treated as a float and presented as a floating-point number (non-locale aware).
o
The argument is treated as an integer and presented as an octal number.
s
The argument is treated and presented as a string.
x
The argument is treated as an integer and presented as a hexadecimal number (with lowercase letters).
X
The argument is treated as an integer and presented as a hexadecimal number (with uppercase letters).

Format argument swapping

The format string supports argument numbering and even swapping. This is useful where two or more data items must be embedded in a string but differences in language structure means that the order of use of the data items is not the same.

For example, suppose we have the following code

echo JText::sprintf( 'Balls in the bucket', $number, $location );

with this language translation string

BALLS IN THE BUCKET=There are %d balls in the %s

Then if

$number = 3
$location = 'hat'

this would output “There are 3 balls in the hat”. But consider if you wanted to change the translation to

BALLS IN THE BUCKET=The %s contains %d balls

This would now output “The 3 contains hat balls” which is clearly nonsense. Rather than change the code, you can indicate in the translation string which argument each of the placeholders refer to. Change the translation to

BALLS IN THE BUCKET=The %2$s contains %1$d balls

and the output becomes “The hat contains 3 balls” as expected.

An added benefit of being able to number the arguments is that you can repeat the placeholders without adding more arguments in the code. For example, change the translation to

BALLS IN THE BUCKET=The %2$s contains %1$d balls, so there are %1$d balls in the %2$s

and this will correctly output “The hat contains 3 balls, so there are 3 balls in the hat”.