Tovább a tartalomhoz

SDK-k és kliensek

Itt két különböző dolgot hívunk SDK-nak, és más problémát oldanak meg.

  • A futásidejű kliensek OTA-csomagból töltik le a fordításokat, és az alkalmazásában oldják fel a kulcsokat. Go, Rust és NestJS változatban léteznek.
  • A böngésző-SDK semmit sem tölt le: megjelöli a DOM-elemeket azzal a kulccsal, amelyből származnak, hogy a Chrome-bővítmény a futó termék fölött megmutathassa és szerkeszthesse a fordítást.

Mindhárom ugyanúgy működik: megadja nekik a forrást, betöltik a memóriába, ötpercenként frissítik a háttérben, és névtér és nyelv szerint oldják fel a kulcsot.

Két forrás áll rendelkezésre:

  • OTA — egy vagy több közzétett csomag, hozzáférési kulccsal megcímezve. Minden csomagnak adható előtag, amely a névterévé válik; az azonos előtagú csomagok összeolvadnak, kulcsütközésnél az utolsó nyer.
  • Map — egy projekt fordítási térképe, projektazonosítóval és API-kulccsal megcímezve. Itt a fájlnév lesz a névtér.
Terminál
go get github.com/OwnLate/go-client
client, err := ownlate.New(ownlate.Config{
Source: ownlate.OTASource{Bundles: []ownlate.OTABundle{{AccessKey: accessKey}}},
Locale: "hu",
})
if err != nil {
return err
}
defer client.Close()
client.Start(ctx)
<-client.Ready()
client.T("notification.title", "en_US")
client.Translate("emails", "greeting", map[string]any{"name": "Roman"}, "hu")

A Start a háttérben frissít, és hiba esetén újrapróbálkozik; a Load egyetlen betöltést végez, és a hibát adja vissza.

[dependencies]
ownlate = { git = "https://github.com/OwnLate/rust-client" }
let client = ownlate::Client::ota(access_key, "en_US")?;
let refresh = client.start();
client.ready().await;
client.t("notification.title", "en_US");
client.translate("emails", "subject", Some(&json!({ "plan": "Pro" })), "en_US");

A Client olcsón klónozható — minden klón ugyanazokon a fordításokon és ugyanazon a frissítési feladaton osztozik. A visszakapott kezelő eldobása leállítja a frissítést.

Terminál
npm install @globalart/ownlate-nestjs-translator

A modul ugyanezt a viselkedést csomagolja be egy Nest-alkalmazáshoz: induláskor betölti a csomagot, és a háttérben frissíti.

A kliensek egyetértenek a szabályokban, és ettől ártalmatlan a hiányzó fordítás:

  1. A nyelv a hívásból jön, egyébként a kliens beállításából.
  2. A rendszer megkeresi a névteret; OTA-forrásnál az ismeretlen névtér az alapértelmezett csomagra esik vissza.
  3. A hiányzó nyelv helyére azonos nyelvű változat lép — az en_US eléri az en értéket és viszont —, ennek híján pedig az ábécében első, így a választás hívások közt állandó marad.
  4. Az ismeretlen kulcs úgy tér vissza, ahogy kérték, sosem üres szövegként.
  5. A {{name}} alakú helyőrzők az átadott értékekkel helyettesítődnek.

Mindkét kliens zár alatt olvas egy pillanatképet, és frissítéskor az egészet cseréli, így nyugodtan megosztható goroutine-ok vagy taskok között.

Az @ownlate/sdk a DOM-ot jelöli meg. Ez teszi a futó alkalmazását olyanná, amelyet a fordító helyben szerkeszthet.

Terminál
npm install @ownlate/sdk
import { init, wrapT } from '@ownlate/sdk'
init({
projectId: 'your-project-id',
workspaceId: 'your-workspace-id',
apiKey: 'sdk_…',
apiUrl: 'https://api.ownlate.com',
})

Csomagolja be egyszer az i18n-függvényét, és minden általa megjelenített szöveg megjelölődik:

import { useTranslation } from 'react-i18next'
import { wrapT } from '@ownlate/sdk'
function Title() {
const { t: rawT } = useTranslation()
const t = wrapT(rawT)
return <h1>{t('home.title')}</h1>
}
ExportSzignatúraMit tesz
init(config) => voidElindítja az SDK-t. Egyszer hívja.
wrapT(t) => tBecsomagolja az i18n t() függvényt, hogy a megjelenített csomópontok megjelölődjenek
annotateElement(el, key) => voidKézzel jelöl meg egy csomópontot
onTranslationUpdate(cb) => unsubscribeReagál a bővítményben végzett szerkesztésre
destroy() => voidEltávolítja a figyelőket, és alaphelyzetbe áll

Az annotateElement ott kell, ahol a wrapT nem látja a csomópontot — placeholder, aria-label, title attribútum:

annotateElement(document.querySelector('#search'), 'search.placeholder')

Az élő szerkesztéseket pedig újratöltés nélkül alkalmazhatja:

onTranslationUpdate(({ key, value, lang }) => {
i18next.addResource(lang, 'translation', key, value)
})
  1. Az init() postMessage üzenettel jelentkezik, amelyet a bővítmény content scriptje elkap.
  2. A wrapT() és az annotateElement() data-ownlate-key attribútumot tesz a csomópontokra.
  3. A bővítmény kiolvassa ezeket, és az oldalsó paneljében mutatja a hozzájuk tartozó szegmenseket.
  4. A panelben végzett szerkesztés piszkozatként mentődik a szegmensre, és visszakerül az oldalra, így a felület azonnal frissül.

Mivel a szerkesztések piszkozatként landolnak, a helyben szerkesztés soha nem kerüli meg a lektorálást.

A böngésző-SDK SDK-tokennel hitelesít, nem API-kulccsal. A tokeneket projektenként a projekt SDK lapján hozza létre, és mindegyik:

  • egyszer, a létrehozáskor jelenik meg, utána már csak az előtagja;
  • pontosan egy projektet ér el — azt, amelyhez létrehozták;
  • kulcs alapján tud szegmenst olvasni és piszkozatot menteni, semmi mást;
  • feljegyzi, mikor használták utoljára, és bármikor visszavonható.

Ez a szűkösség a lényeg: a token a böngészőcsomagban utazik, ezért nem tehet olyat, amit egy idegen kezében kifogásolna.