Lingara Lingara Documentación Guías API Bibliotecas Apps Crear Aplicación web
Idioma: Español

Tarjetas

Esta página está traducida del inglés. Si ambas difieren, la página en inglés es la correcta. Leer la página en inglés

Una tarjeta es una lista corta de elementos que Lingara dibuja con su propio estilo. No hay campos de entrada, imágenes, scripts ni marcado. Una app no puede poner su propio código ni su propio aspecto en la pantalla de un estudiante, así que cada tarjeta se lee como el resto de Lingara. Tu respuesta es JSON: una card que contiene sus elements y, opcionalmente, una tutor_note (consulta La nota para el tutor).

Los elementos

Cada elemento tiene un type, que es uno de estos ocho:

ElementoCamposQué muestra
headingtext, levelUn encabezado. level es 1 o 2, y cualquier otro valor pasa a ser 2. Su texto tiene como máximo 80 caracteres.
texttext, langUn párrafo de como máximo 600 caracteres. Es el único lugar donde se conserva un salto de línea.
termword, reading, gloss, langUna palabra para aprender. Solo word es obligatorio. La palabra tiene como máximo 60 caracteres, la lectura 120 y la glosa 160.
listitemsHasta 20 elementos de lista. Cada uno es un text o un term, con los mismos campos que el elemento de ese nombre.
progressvalue, labelUna barra de progreso. value va de 0 a 1, y la etiqueta tiene como máximo 60 caracteres.
dividerUna línea entre partes de la tarjeta.
buttonlabel, action, styleUn botón que envía su action a tu servidor. style es primary o secondary, y la etiqueta tiene como máximo 32 caracteres.
linklabel, urlUn enlace que el estudiante abre en su navegador, después de que Lingara se lo pregunte. La etiqueta tiene como máximo 60 caracteres.

Un lang es una etiqueta de idioma como ja, para que Lingara dibuje la escritura correcta. Un valor que no es una etiqueta de idioma se elimina.

Los límites

  • Una tarjeta contiene como máximo 24 elementos. Los elementos posteriores al 24.º se descartan.
  • Una lista contiene como máximo 20 elementos de lista. Los posteriores al 20.º se descartan, y una lista vacía se descarta.
  • Una tarjeta contiene como máximo 4 botones. Los botones posteriores al 4.º se descartan.
  • Un texto más largo que su límite se recorta para que quepa y termina en …. Los caracteres se cuentan como valores escalares Unicode.
  • Los caracteres de control y las anulaciones de dirección se eliminan de cada cadena.
  • Se descarta un enlace cuya dirección no es HTTPS, lleva un nombre de usuario o apunta a una dirección IP.
  • Se descarta un botón cuyo action tiene más de 64 caracteres o usa algo distinto de letras, dígitos, _, ., : y -.
  • Se descarta un elemento al que no le queda texto después de estas reglas.

Estas reglas son permisivas: Lingara recorta o descarta lo que no cabe y dibuja el resto. Los kits aplican las mismas reglas antes de que respondas, para que puedas ver qué cambiaría.

Análisis estricto

El vocabulario es cerrado. Un tipo de elemento desconocido, un campo que un elemento no tiene, un valor del tipo JSON equivocado o una respuesta que no es JSON en absoluto convierte toda la respuesta en una tarjeta de reserva. Lingara nunca dibuja una parte de una tarjeta que no pudo leer.

Tamaño y tiempo

Una respuesta puede ocupar como máximo 32 KiB. Lingara da a tu servidor 3 segundos para responder a un renderizado y 5 segundos para responder a una acción, y no reintenta ninguno de los dos. Una respuesta debe tener el estado 200 y un tipo de contenido JSON. Las redirecciones no se siguen.

Botones y acciones

Cuando el estudiante pulsa un botón, Lingara envía a tu servidor una solicitud de acción con el action de ese botón. Tu servidor responde con una tarjeta nueva, que sustituye a la anterior. La misma pulsación puede llegar dos veces, así que haz que cada acción se pueda repetir sin riesgo.

Cuando una tarjeta falla

Cuando Lingara no consigue una tarjeta que pueda dibujar, el estudiante ve la tarjeta propia de Lingara «Esta app no respondió» en su idioma, o tu última tarjeta válida marcada como «No actualizada». Al estudiante nunca se le dice por qué. Solo tú, como propietario de la app, ves el motivo:

  • Tu respuesta: invalid (no es una tarjeta que Lingara pueda leer), empty (no queda nada que mostrar tras los límites) o too_large (más de 32 KiB).
  • La conexión con tu servidor: timeout, http_error (cualquier estado distinto de 200), transport (un fallo de conexión o de TLS, como un certificado caducado) o blocked (un render_url que lleva a una dirección privada o a una dirección IP literal).
  • El lado de Lingara: unavailable (Lingara no pudo firmar la solicitud) o busy (demasiadas solicitudes ya en curso).
Lenguaje del ejemplo de código

TypeScript

function todayCard(streak: number): Card {
  return card()
    .heading("Today's five", 1)
    .term({ word: "雨", reading: "yǔ", gloss: "rain", lang: "zh" })
    .list([item.text("Review 3 words"), item.term({ word: "二", reading: "èr" })])
    .button(`Done (${streak})`, "done")
    .build(); // Throws CardLimitError naming the rule the relay would clamp.
}

Rust

fn today_card(title: &str, lang: &str) -> Result<lingara_apps::Card, BoxError> {
    Ok(card()
        .heading(title, 1)
        .term(Term::new("雨").reading("yǔ").gloss("rain").lang(lang))
        .list([item::text("Say it aloud"), item::term(Term::new("下雨").gloss("to rain"))])
        .button("Next word", "next")
        .build()?)
}

Go

card, err := lingaraapps.NewCard().
	Heading("Today", 1).
	Term(lingaraapps.Term{Word: "雨", Reading: "yǔ", Gloss: "rain", Lang: "zh"}).
	List(
		lingaraapps.Item.Text("Say it aloud three times."),
		lingaraapps.Item.Term(lingaraapps.Term{Word: "雨天", Gloss: "rainy day", Lang: "zh"}),
	).
	Button("Next", "next").
	Build()
if err != nil {
	// A *lingaraapps.CardLimitError names the rule the card breaks,
	// such as text_length or list_items. Nothing is cut for you.
	return lingaraapps.Card{}, err
}

Java

import com.getlingara.apps.Card;
import com.getlingara.apps.Item;

Card card =
    Card.card()
        .heading("Today's five", 1)
        .term("雨", "yǔ", "rain", "zh")
        .list(Item.text("Say it aloud"), Item.term("二", "èr", "two", "zh"))
        .button("Next", "next")
        .build(); // a CardLimitException names the first rule the card breaks

Kotlin

import com.getlingara.apps.kotlin.Card
import com.getlingara.apps.kotlin.card

val c =
    card {
        heading("Today's five", 1)
        term("雨", reading = "yǔ", gloss = "rain", lang = "zh")
        list(item.text("Say it aloud"), item.term("二", reading = "èr", gloss = "two", lang = "zh"))
        button("Next", "next")
    } // a CardLimitException names the first rule the card breaks

Ruby

def self.today_card(streak)
  Lingara::Apps.card
    .heading("Today's five", 1)
    .term(word: "雨", reading: "yǔ", gloss: "rain", lang: "zh")
    .list([Lingara::Apps.item.text("Review 3 words"), Lingara::Apps.item.term(word: "二", reading: "èr")])
    .button("Done (#{streak})", "done")
    .build # Raises Lingara::Apps::CardLimitError naming the rule Lingara would clamp.
end

PHP

use Lingara\Apps\Card;
use Lingara\Apps\Generated\Card as CardModel;
use Lingara\Apps\Item;

function todayCard(int $streak): CardModel
{
    return Card::create()
        ->heading("Today's five", 1)
        ->term('雨', reading: 'yǔ', gloss: 'rain', lang: 'zh')
        ->list([Item::text('Review 3 words'), Item::term('二', reading: 'èr')])
        ->button("Done ({$streak})", 'done')
        ->build(); // Throws CardLimitException naming the rule the relay would clamp.
}