GT JSX データ形式

省略化された General Translation の JSX データ形式に関するリファレンス

GT JSX データ形式は、General Translation のライブラリが React アプリケーション内の翻訳済み UI を表現するために使用する、縮約(最小化)データ形式です。

はじめに: JSX ツリー

React は、JSX ツリーを次の構造のオブジェクトとして表現します。

type Element = {
    type: string;
    props: {
        children: JSXTree[] | JSXTree;
        // ...その他の props
    };
    // ...その他の属性
};
type JSXTree = Element | string;

GT JSX は、React アプリケーション内の翻訳済み UI を表現するために General Translation のライブラリで使用される、この JSX ツリー構造を圧縮した形式です。

リファレンス

type Element = {
    t?: string; // タグ名
    c?: (Element | Variable | string)[]; // 子要素
    i?: number; // GT 要素ID
    d?: {
        b?: Record<string, Element | Variable | string>; // ブランチ
        t?: "p" | "b"; // ブランチ変換タイプ(複数形またはブランチ)
        pl?: string; // プレースホルダー
        ti?: string; // タイトル
        alt?: string; // 代替テキスト
        arl?: string; // aria-label
        arb?: string; // aria-labelledby
        ard?: string; // aria-describedby
        s?: Record<string, string>; // スタイル
    };
}
type Variable = {
    k: string; // キー
    v?: "v" | "n" | "c" | "d"; // 種別
    i?: number; // GT ID
}
type GTJSXTree = Element | Variable | string | (Element | Variable | string)[];

GT JSX:文字列

GT JSX の最も基本的な形は文字列で、固定的なテキストを表します。

例:

<T>こんにちは、世界!</T>

GT の JSX では次のように表されます:

「こんにちは、世界!」

文字列の配列も有効な GT の JSX です:

["こんにちは、", "世界!"]

GT JSX:Elements

GT は JSX の Element 型を 2 つの方法で表現します。

Variables

最初は変数で、キーと任意の型を持つシンプルなオブジェクトです。これは、実行時に変化する可能性のある変数を表すために使います。

type Variable = {
    k: string; // `k` はキー、変数の名称を表します
    v?: ( // 変数の型を表します。省略した場合は `v` と見なされます
        "v" | // `v`: 汎用変数
        "n" | // `n`: 数値変数
        "c" | // `c`: 通貨変数
        "d" // `d`: 日時変数
    );
    i?: number; // 変数の GT の id
}

例 1:Var

<T>こんにちは、<Var>{name}</Var>!</T>

GT の JSX では次のように表現されます:

["こんにちは、", { k: "_gt_var_1", i: 1 }, "!"]

name プロパティのない Variables には、GT の ID に基づいて一意の内部名が割り当てられます。

例2: Num

<T>件数は<Num>{count}</Num>です</T>

GT の JSX では次のように表されます:

["カウントは ", { k: "count", v: "n", i: 1 }]

例 3: name プロップ付き

<T>この製品の価格は<Currency name="cost">{amount}</Currency>です。</T>

GT の JSX では次のように表されます:

["この製品の価格は ", { k: "cost", v: "c", i: 1 }]

要素

Variable ではない要素は、次のデータ構造で表されます。

これらの属性はすべて任意です。 空のオブジェクトは、子孫に翻訳対象のコンテンツが一切ない状態で、元の要素と同じ位置にある翻訳済み要素を表します。 実際には、i は常に含まれます。

type Element = {
    t?: string; // タグ名
    c?: GTJSXTree | GTJSXTree[]; // children
    i?: number; // 要素の GT ID
    d?: { // data-_gt プロパティ
        b?: Record<string, GTJSXTree | GTJSXTree[]>; // ブランチ
        t?: "p" | "b"; // ブランチ変換タイプ(複数形またはブランチ)
        pl?: string; // プレースホルダー
        ti?: string; // タイトル
        alt?: string; // alt
        arl?: string; // aria-label
        arb?: string; // aria-labelledby
        ard?: string; // aria-describedby
        s?: Record<string, string>; // スタイル
    }
}

例 1:シンプルなタグ

<T>こんにちは、<b>世界</b>!</T>

GT の JSX では次のように表現します:

["こんにちは、", { c: "世界", i: 1 }, "!"]

例 2: ネスト + variables

<T><b>こんにちは</b>、私の名前は<i><Var>{name}</Var></i>です</T>

GT の JSX では次のように表現されます:

[
    { t: "b", c: "こんにちは", i: 1 },
    "、私の名前は ",
    { 
        t: "i",
        c: { k: "_gt_var_3", i: 3 }, 
        i: 2 
    }
]

例 3: 複数形あり

<T>
    <Plural 
        n={count} 
        one={<><Num>{count}</Num>個のアイテムを持っています</>} 
        other={<><Num>{count}</Num>個のアイテムを持っています</>}
    />
</T>

GT の JSX では次のように表現されます:

{ 
    i: 1,
    d: {
        t: "p",
        b: {
            one: {
                c: ["私は", { k: "_gt_num_4", v: "n", i: 3 }, "個のアイテムを持っています"],
                i: 2 
            },
            other: {
                c: ["私は", { k: "_gt_num_4", v: "n", i: 3 }, "個のアイテムを持っています"],
                i: 2 // 並列分岐で同じidが使用されている点に注意
            }
        }
    }
}

GTJSX 型

type GTJSXTree = Element | Variable | string | (Element | Variable | string)[];

GT ID

GT ID は、JSX ツリー内の要素や変数に対して、深さ優先で 1 から順に割り当てられます。

<Branch><Plural> のような分岐コンポーネントがある場合、並列する各ブランチには同じ GT ID が割り当てられます。これは、ある言語のほうが別の言語より分岐(例: 複数形の形)が多い場合でも、適切な props とロジックを備えた要素を生成できるようにするためです。

GT JSX JSON ファイル

各 JSX ツリーは <T> コンポーネントの children(子コンテンツ)を表します。 コンポーネントは翻訳用の JSON ファイルにまとめて保存されます。 これらのファイルに保存される JSON オブジェクトの型は次のとおりです。

type GTJSXFile = {
    [key: string]: GTJSXTree;
}

ここで、key はユーザー定義の値、または元の言語の GTJSXTree のハッシュのいずれかで、 GTJSXTree は前述の GT の JSX ツリーの型を指します。

完全な例

記述された JSX:

<T>
    <b>Alice の</b>満足した<i>顧客</i>
</T>

次のJSXツリーで表現されます:

[
    {
        type: "b",
        "props": {
            "children": "アリスの"
        }
    },
    " ハッピーな "
    {
        type: "i",
        "props": {
            "children": "お客様"
        }
    }
]

これは GT の JSX に最小化(minify)されます:

[{ t: "b", c: "Aliceの", i: 1 }, " 幸せな ", { t: "i", c: "顧客", i: 2 }]

スペイン語に翻訳すると、GT の JSX は次のようになります。

[{ c: "顧客", i: 2 }, " は ", { c: "アリスの", i: 1 }, " 満足そうだ"]

次のような内容のファイルに保存されます:

{ "abc123": [{ "c": "その顧客", "i": 2 }, " は幸せだ ", { "c": "Aliceの", "i": 1 }] }
abc123 は、スペイン語訳ではなく、元の英語版 GT JSX ツリーのハッシュです。

スペイン語訳を元の JSX ツリーと突き合わせると、次の結果が得られます。

[
    {
        type: "i",
        "props": {
            "children": "顧客"
        }
    },
    " は ",
    {
        type: "b",
        "props": {
            "children": "Aliceの"
        }
    }
]

その結果、意図したとおりのUIとして表示できます:

<><i>アリス</i>の<b>満足した顧客</b></>

ハッシュ

ハッシュアルゴリズムおよびハッシュ長は未定

ランタイムでハッシュを避ける

ランタイムでハッシュ計算を行わないようにするため、ライブラリにはオプションのfallback機構が用意されており、ユーザーはIDを指定できます。

<T id="example">
    こんにちは、世界
</T>

翻訳用のJSONファイルにidが含まれている場合は、ハッシュではなくそのidが使用されます。

{ "example": "こんにちは、世界" }

このガイドはどうでしたか?

GT JSX データ形式