Formato dati GT JSX

Riferimento al formato dati JSX compattato di General Translation

Il formato dati GT JSX è un formato dati compattato utilizzato dalle librerie di General Translation per rappresentare l'interfaccia utente tradotta nella tua applicazione React.

Introduzione: alberi JSX

React rappresenta gli alberi JSX come oggetti con la seguente struttura:

type Element = {
    type: string;
    props: {
        children: JSXTree[] | JSXTree;
        // ...other props
    };
    // ...other attributes
};
type JSXTree = Element | string;

GT JSX è una versione compressa di questa struttura ad albero JSX, utilizzata dalle librerie di General Translation per rappresentare l’interfaccia utente tradotta nella tua applicazione React.

Riferimenti

type Element = {
    t?: string; // nome del tag
    c?: (Element | Variable | string)[]; // figli
    i?: number; // ID GT dell'elemento
    d?: {
        b?: Record<string, Element | Variable | string>; // diramazioni
        t?: "p" | "b"; // tipo di trasformazione della diramazione (plurale o branch)
        pl?: string; // segnaposto
        ti?: string; // titolo
        alt?: string; // alt
        arl?: string; // aria-label
        arb?: string; // aria-labelledby
        ard?: string; // aria-describedby
        s?: Record<string, string>; // stile
    };
}
type Variable = {
    k: string; // chiave
    v?: "v" | "n" | "c" | "d"; // tipo
    i?: number; // ID GT
}
type GTJSXTree = Element | Variable | string | (Element | Variable | string)[];

GT JSX: Stringhe

La forma più semplice di GT JSX è una stringa, ovvero un testo statico.

Ad esempio:

<T>Salve, mondo!</T>

Verrebbe rappresentato in GT JSX come:

"Ciao, mondo!"

Anche gli array di stringhe sono GT JSX validi:

["Ciao, ", "mondo!"]

GT JSX: Elementi

GT rappresenta i tipi di Element JSX in due modi.

Variabili

La prima è una variabile, un semplice oggetto che contiene una chiave e un tipo opzionale. Viene usata per rappresentare variabili che possono cambiare durante l’esecuzione.

type Variable = {
    k: string; // `k` indica la chiave, ovvero il nome della variabile
    v?: ( // indica il tipo della variabile; se omesso, è considerato come `v`
        "v" | // `v`, variabile generica
        "n" | // `n`, variabile numerica
        "c" | // `c`, variabile valutaria
        "d" // `d`, variabile data/ora
    );
    i?: number; // ID GT della variabile
}

Esempio 1: Var

<T>Ciao, <Var>{name}</Var>!</T>

Verrebbe rappresentato in GT JSX come:

["Ciao, ", { k: "_gt_var_1", i: 1 }, "!"]

Le variabili prive della prop name vengono assegnate a nomi interni unici in base al loro GT ID

Esempio 2: Num

<T>Il totale è <Num>{count}</Num></T>

Verrebbe rappresentato in GT JSX come:

["Il conteggio è ", { k: "count", v: "n", i: 1 }]

Esempio 3: con la prop Name

<T>Questo prodotto costa <Currency name="cost">{amount}</Currency></T>

Verrebbe rappresentato in GT JSX come:

["Il prodotto costa ", { k: "cost", v: "c", i: 1 }]

Elementi

Gli elementi non variabili sono rappresentati con la seguente struttura dati:

Nota che tutti questi attributi sono facoltativi. Un oggetto vuoto rappresenta un elemento tradotto nella stessa posizione del corrispettivo originale, senza contenuti traducibili tra i suoi discendenti. In pratica, i è sempre incluso.

type Element = {
    t?: string; // nome del tag
    c?: GTJSXTree | GTJSXTree[]; // figli (children)
    i?: number; // ID GT dell'elemento
    d?: { // prop data-_gt
        b?: Record<string, GTJSXTree | GTJSXTree[]>; // diramazioni
        t?: "p" | "b"; // tipo di trasformazione (plurale o diramazione)
        pl?: string; // placeholder
        ti?: string; // title
        alt?: string; // alt
        arl?: string; // aria-label
        arb?: string; // aria-labelledby
        ard?: string; // aria-describedby
        s?: Record<string, string>; // style
    }
}

Esempio 1: Tag semplici

<T>Ciao, <b>mondo</b>!</T>

Verrebbe rappresentato in GT JSX come:

["Ciao, ", { c: "world", i: 1 }, "!"]

Esempio 2: Nidificato, con variabili

<T><b>Salve</b>, mi chiamo <i><Var>{name}</Var></i></T>

Verrebbe rappresentato in GT JSX come:

[
    { t: "b", c: "Ciao", i: 1 },
    ", mi chiamo ",
    { 
        t: "i",
        c: { k: "_gt_var_3", i: 3 }, 
        i: 2 
    }
]

Esempio 3: con plurali

<T>
    <Plural 
        n={count} 
        one={<>Ho <Num>{count}</Num> articolo</>} 
        other={<>Ho <Num>{count}</Num> articoli</>}
    />
</T>

Verrebbe rappresentato in GT JSX come:

{ 
    i: 1,
    d: {
        t: "p",
        b: {
            one: {
                c: ["Ho", { k: "_gt_num_4", v: "n", i: 3 }, "elemento"],
                i: 2 
            },
            other: {
                c: ["Ho", { k: "_gt_num_4", v: "n", i: 3 }, "elementi"],
                i: 2 // note the same ID is used for parallel branches
            }
        }
    }
}

Tipo GTJSX

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

ID GT

Gli ID GT vengono assegnati agli elementi e alle variabili in un albero JSX in modo depth‑first e sequenziale, a partire da 1.

Quando ci sono componenti ramificati come <Branch> o <Plural>, gli stessi ID GT vengono assegnati ai rami paralleli. Questo consente, se in una lingua sono presenti più rami che in un’altra (ad esempio lingue con più forme plurali), di creare comunque elementi con le prop e la logica corrette.

File JSON JSX di GT

Ogni albero JSX rappresenta i figli di un componente <T>. I componenti sono salvati insieme in file JSON di traduzione. Il tipo dell’oggetto JSON contenuto in questi file corrisponde a:

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

Dove key è definita dall’utente oppure è l’hash del GTJSXTree nella lingua originale, e GTJSXTree è il tipo dell’albero GT JSX descritto sopra.

Esempio completo

Il JSX scritto:

<T>
    <i>cliente</i> <b>di Alice</b> felice
</T>

Sarebbe rappresentato dal seguente albero JSX:

[
    {
        type: "b",
        "props": {
            "children": "Alice"
        }
    },
    " ",
    {
        type: "i",
        "props": {
            "children": "cliente felice"
        }
    }
]

Questo verrebbe minificato in GT JSX come:

[{ c: "Il cliente", i: 2 }, " soddisfatto ", { c: "di Alice", i: 1 }]

Se tradotto in spagnolo, il JSX di GT sarebbe:

[{ c: "Il cliente", i: 2 }, " felice ", { c: "di Alice", i: 1 }]

Verrebbe salvato in un file che ha questo aspetto:

{ "abc123": [{ "c": "Il cliente", "i": 2 }, " felice ", { "c": "di Alice", "i": 1 }] }
abc123 è l’hash dell’albero JSX originale in inglese di GT, non della traduzione in spagnolo.

Quando la traduzione in spagnolo viene riconciliata con l’albero JSX originale, si ottiene quanto segue:

[
    {
        type: "i",
        "props": {
            "children": "Il cliente"
        }
    },
    " felice ",
    {
        type: "b",
        "props": {
            "children": "di Alice"
        }
    }
]

Che può quindi essere mostrata come l’UI prevista:

<><i>Il cliente</i> felice <b>di Alice</b></>

Hash

Algoritmo di hashing, lunghezza dell’hash da definire

Evitare gli hash in fase di esecuzione

Per evitare di calcolare gli hash in fase di esecuzione, le librerie offrono un meccanismo di fallback opzionale che consente all’utente di specificare un ID.

<T id="example">
    Ciao, mondo
</T>

Se l’ID è presente nel file JSON delle traduzioni, verrà usato anziché l’hash.

{ "example": "Ciao, mondo" }

Come valuti questa guida?

Formato dati GT JSX