Lingara Lingara Belgeler Rehberler API Kütüphaneler Uygulamalar Oluştur Gömme Web uygulaması
Dil: Türkçe

Web sitesi widget'ı

Bu sayfa İngilizceden çevrilmiştir. İkisi arasında fark varsa İngilizce sayfa doğrudur. İngilizce sayfayı oku

Bir web sitesinde Lingara, <lingara-embed> adlı özel bir öğe olarak çalışır. Öğe, Lingara’nın alıştırmasını Lingara tarafından sunulan bir çerçevede çizer; böylece sayfanız öğrencinin verilerini hiçbir zaman görmez, Lingara’nın sayfası da sizinkini hiçbir zaman görmez.

Öğeyi yerleştirin

@lingara/embed paketini npm’den kurun ya da sitenizde bir paketleyici yoksa modül derlemesini bir CDN’den yükleyin. Ardından <lingara-embed> öğesini sayfaya koyun ve tanımlayın. Öğe şunları alır:

  • plan-id, alıştırması yapılacak ders planı; oyuncunun sahip olduğu bir plan;
  • surface, ne gösterileceği: practice, varsayılan olan ve mevcut tek yüzey;
  • theme, light, dark veya auto değerlerinden biri;
  • locale, çerçevenin kendi sözcüklerinin dili; belirtilmezse öğrencinin dilini izler;
  • title, çerçevenin erişilebilir adı.

Biçimlendirme temada biter. Sayfanız çerçevenin içine ulaşamaz ve tema, çerçevenin sunduğu tek ayardır.

Ona belirteç verin

Öğenin tokenProvider özelliğini, kendi sunucunuzdan belirteç isteyen bir işleve ayarlayın. Sunucunuz bir sunucu kiti kullanarak belirteci sayfanın kökeniyle üretir ve belirteci ve son kullanma zamanını yanıt olarak döndürür. Öğe belirteci çerçeveye mesajla iletir ve belirteç hiçbir zaman bir URL içinde dolaşmaz.

Widget’ın çalıştığı her kökeni, onun için belirteç üretmeden önce konsolda istemcinizin ayarlarına kaydedin. Sunucu kitleri sayfası nasıl yapılacağını anlatır. API, başka herhangi bir köken için üretilmiş bir belirteci reddeder ve çerçeve alıştırma yerine bir hata gösterir.

Bir sunucu kiti, öğe ve belirteç sağlayıcısı bir arada olmak üzere bütün kod parçacığını da sizin için yazabilir; içerik güvenlik politikanız gerektiriyorsa sayfanızın betik nonce değeriyle birlikte. Aşağıdaki son örnek bunu gösterir.

Çerçevenin söylediklerini dinleyin

Çerçeve öğeyle sürümlü bir mesaj protokolü üzerinden konuşur ve öğe, sayfanızın ihtiyaç duyduklarını DOM olaylarına dönüştürür:

  • öğrenci bir seti bitirdiğinde lingara:practice-completed; planId, setNumber, correct ve total ile birlikte;
  • çerçeve durduğunda lingara:error; bir code ve retryable ile birlikte. Yeniden denenebilir bir hata, yeni bir yerleştirmenin başarılı olabileceği anlamına gelir; ne zaman yeniden deneneceğine siz karar verirsiniz.

Alıştırmanın sonucu, alıştırma sonuçları sayfasında anlatıldığı gibi sunucunuza da ulaşır.

npm install @lingara/embed@0.1.0-alpha.6
# No bundler? One module script instead:
# <script type="module" src="https://cdn.jsdelivr.net/npm/@lingara/embed@0.1.0-alpha.6/dist/lingara-embed.min.js"></script>
<!-- plan-id is a lesson plan your server made for this player. -->
<lingara-embed surface="practice" plan-id="0b9d4f2e-3c1a-4e8b-9f6d-2a7c5e1b8d40" theme="auto" title="Practice"></lingara-embed>
<script type="module">
  import { defineLingaraEmbed } from '@lingara/embed'
  defineLingaraEmbed()
</script>
// Your own endpoint, on your own server. It mints with this page's origin and
// returns exactly { token, expires_at }: the token (lgr_et_…) never touches a URL.
widget.tokenProvider = async () => {
  const response = await fetch('/lingara/token', { method: 'POST', credentials: 'same-origin' })
  if (!response.ok) throw new Error(`token endpoint answered ${response.status}`)
  return response.json()
}
widget.addEventListener('lingara:practice-completed', (event) => {
  const { planId, setNumber, correct, total } = (event as CustomEvent).detail
  console.log(`set ${setNumber} of ${planId}: ${correct}/${total}`)
})
widget.addEventListener('lingara:error', (event) => {
  const { code, retryable } = (event as CustomEvent).detail
  // `retryable` means a remount may succeed; when to try is yours to decide.
  if (retryable) setTimeout(() => widget.reload(), 30_000)
  else console.warn('Lingara practice stopped:', code)
})
Kod örneğinin dili

TypeScript

// The page that mounts the widget: the token never appears in it.
export function practicePage(planId: string, cspNonce: string): string {
  const widget = widgetSnippet({ planId, tokenEndpoint: '/lingara/token', theme: 'auto', locale: 'fr', title: 'Pratique', nonce: cspNonce })
  return `<!doctype html><title>Practice</title>${widget}`
}

Rust

// The element, its script build and a token provider that POSTs to your
// token route. The token never appears in the markup.
let html = widget_snippet(&SnippetOptions {
    locale: Some("fr".into()),
    nonce: Some(csp_nonce.into()), // your page's CSP nonce, for a strict script-src
    ..SnippetOptions::new(plan_id, "/lingara/token")
})?;

Go

// The plan your server made for this player, and the token route above.
// Pass the request's CSP nonce when your script-src allows no inline
// script; the token itself never appears in the markup.
theme := "auto"
html, err := lingaraembed.WidgetSnippet(lingaraembed.SnippetOptions{
	PlanID:        planID,
	TokenEndpoint: "/lingara/token",
	Theme:         &theme,
	Nonce:         &cspNonce,
})
if err != nil {
	return "", err // a *lingaraembed.SnippetError names the refused option
}
return template.HTML(html), nil // already escaped by the kit

Java

// planId is the lesson plan your server made for this player. The element
// POSTs to tokenEndpoint with same-origin cookies: the token never appears
// in the markup. Pass this request's CSP nonce if your page sets one.
String html =
    WidgetSnippet.render(
        SnippetOptions.builder(planId, "/lingara/token").locale("fr").nonce(cspNonce).build());

Kotlin

// planId is the lesson plan your server made for this player. The element
// POSTs to tokenEndpoint with same-origin cookies: the token never appears
// in the markup. Pass this request's CSP nonce if your page sets one.
val html =
    widgetSnippet(
        SnippetOptions(planId, tokenEndpoint = "/lingara/token").apply {
            locale = "fr"
            nonce = cspNonce
        },
    )

Ruby

# The plan your server made for this player, rendered into your page.
# nonce: your page's CSP nonce, when its script-src allows no inline script.
def self.widget(plan_id, csp_nonce)
  Lingara::Embed.widget_snippet(plan_id: plan_id, token_endpoint: "/lingara/token", locale: "fr", nonce: csp_nonce)
end

PHP

use Lingara\Embed\SnippetOptions;
use Lingara\Embed\WidgetSnippet;

// In your page's template: the plan your server made for this player, and
// your token route. Pass the request's CSP nonce if your script-src allows
// no inline script. A bad option throws SnippetException naming its field.
function practiceWidget(string $planId, string $cspNonce): string
{
    return WidgetSnippet::render(new SnippetOptions(
        planId: $planId,
        tokenEndpoint: '/lingara/token',
        theme: 'auto',
        nonce: $cspNonce,
    ));
}

C#

app.MapGet("/practice/{planId}", (string planId, HttpContext http) =>
{
    var widget = WidgetSnippet.Render(new SnippetOptions
    {
        PlanId = planId,                              // the plan your server made for this player
        TokenEndpoint = "/lingara/token",             // same origin: the element sends this page's cookies
        Nonce = http.Items["csp-nonce"] as string,     // your CSP's nonce, if script-src has one
    });
    return Results.Content($"<!doctype html><title>Practice</title>\n{widget}", "text/html");
}).RequireAuthorization();