Skip to content

The XLIFF format

Edit this page

Most professional translation tools support XLIFF. These files use the XML format and are supported by Symfony by default. Besides supporting all Symfony translation features, the XLIFF format also has some specific features.

Adding Notes to Translation Contents

Sometimes translators need additional context to better decide how to translate some content. This context can be provided with notes, which are a collection of comments used to store end user readable information. The only format that supports loading and dumping notes is XLIFF version 2.

8.1

Support for XLIFF versions 2.1 and 2.2 was introduced in Symfony 8.1. Previously, only XLIFF 1.2 and 2.0 were supported.

If the XLIFF 2 document contains <notes> nodes, they are automatically loaded/dumped inside a Symfony application:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8" ?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0"
    srcLang="fr-FR" trgLang="en-US">
    <file id="messages.en_US">
        <unit id="LCa0a2j" name="original-content">
            <notes>
                <note category="state">new</note>
                <note category="approved">true</note>
                <note category="section" priority="1">user login</note>
            </notes>
            <segment state="translated" subState="Some custom value">
                <source>original-content</source>
                <target>translated-content</target>
            </segment>
        </unit>
    </file>
</xliff>

Plural, Gender and Select (PGS)

8.1

Support for the XLIFF PGS module was introduced in Symfony 8.1.

XLIFF 2.2 introduces the PGS module (Plural, Gender and Select) to handle plural, gender and select variations directly in the translation file. When the XLIFF loader encounters PGS attributes, it automatically converts them into ICU MessageFormat strings and registers them in the +intl-icu domain.

See also

Read more about using ICU message format in Symfony.

Here is an example of a plural translation using PGS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8" ?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0"
    xmlns:pgs="urn:oasis:names:tc:xliff:pgs:1.0"
    version="2.2" srcLang="en" trgLang="fr">
    <file id="f1">
        <unit id="tu1" name="file_deleted" pgs:switch="plural:file_count">
            <segment id="seg1" pgs:case="0">
                <source>You deleted no file.</source>
                <target>Vous n'avez supprimé aucun fichier.</target>
            </segment>
            <segment id="seg2" pgs:case="1">
                <source>You deleted one file.</source>
                <target>Vous avez supprimé un fichier.</target>
            </segment>
            <segment id="seg3" pgs:case="other">
                <source>You deleted <ph id="1" disp="file_count"/> files.</source>
                <target>Vous avez supprimé <ph id="1" disp="file_count"/> fichiers.</target>
            </segment>
        </unit>
    </file>
</xliff>

The pgs:switch attribute on the <unit> element declares the variable name and the switch type (plural, gender or select). Each <segment> uses pgs:case to define the matching value. The <ph> (placeholder) elements with a disp attribute are converted to ICU placeholders.

Gender variations work the same way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8" ?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0"
    xmlns:pgs="urn:oasis:names:tc:xliff:pgs:1.0"
    version="2.2" srcLang="en" trgLang="fr">
    <file id="f1">
        <unit id="tu1" name="party_invite" pgs:switch="gender:host_gender">
            <segment id="seg1" pgs:case="feminine">
                <source>You are invited to her party</source>
                <target>Vous êtes invité à sa fête</target>
            </segment>
            <segment id="seg2" pgs:case="masculine">
                <source>You are invited to his party</source>
                <target>Vous êtes invité à sa fête</target>
            </segment>
            <segment id="seg3" pgs:case="other">
                <source>You are invited to their party</source>
                <target>Vous êtes invité à leur fête</target>
            </segment>
        </unit>
    </file>
</xliff>

Tip

Multiple switches can be combined in a single pgs:switch attribute (e.g. pgs:switch="gender:host_gender plural:guest_count"). Symfony nests the ICU structures automatically.

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version