Compartir a través de


Lenguaje de plantillas de tarjetas adaptables

Las plantillas permiten separar los datos del diseño en una tarjeta adaptable. El lenguaje de plantilla es la sintaxis que se usa para crear una plantilla.

Sigue leyendo para obtener una introducción a las plantillas de tarjetas adaptables.

Importante

Cambios importantes en la versión candidata para lanzamiento de mayo de 2020

Nos hemos estado esforzando para poder publicar las plantillas y, finalmente, ya nos encontramos en la recta final. Tuvimos que realizar algunos cambios menores importantes antes de completar la versión.

Cambios importantes de mayo de 2020

  1. La sintaxis de enlace se cambió de {...} a ${...}.
    • Por ejemplo, "text": "Hello {name}" se convierte en "text": "Hello ${name}".

Enlace de datos

Escribir una plantilla es tan sencillo como reemplazar el contenido "no estático" de la tarjeta por "expresiones de enlace".

Carga de la tarjeta estática

{
   "type": "TextBlock",
   "text": "Matt"
}

Carga de plantilla

{
   "type": "TextBlock",
   "text": "${firstName}"
}
  • Las expresiones de enlace se pueden colocar prácticamente en cualquier lugar en el que pueda haber contenido estático.
  • La sintaxis de enlace comienza con ${ y termina con }. Por ejemplo, ${myProperty}
  • Usa Dot-notation para acceder a los subobjetos de una jerarquía de objetos. Por ejemplo, ${myParent.myChild}
  • El control de valores NULL correctos garantiza que no obtendrás excepciones si accedes a una propiedad nula en un gráfico de objetos.
  • Usa la sintaxis del indexador para recuperar propiedades por clave o elementos de una matriz. Por ejemplo, ${myArray[0]}

Aprovisionamiento de datos

Ahora que tienes una plantilla, querrás proporcionar los datos para completarla. Para ello, tienes dos opciones:

  1. Opción A: de forma alineada en la carga de la plantilla. Puedes proporcionar los datos alineados en la carga de la plantilla AdaptiveCard. Para ello, simplemente agrega un atributo $data al objeto raíz AdaptiveCard.
  2. Opción B: como un objeto de datos independiente. Con esta opción, proporcionas dos objetos independientes al SDK de plantillas en tiempo de ejecución: template y data. Este será el enfoque más común, ya que normalmente crearás una plantilla y querrás proporcionar datos dinámicos más adelante.

Opción A: datos alineados

{
    "type": "AdaptiveCard",
    "$data": {
        "employee": {
            "name": "Matt",
            "manager": { "name": "Thomas" },
            "peers": [{
                "name": "Andrew" 
            }, { 
                "name": "Lei"
            }, { 
                "name": "Mary Anne"
            }, { 
                "name": "Adam"
            }]
        }
    },
    "body": [
        {
            "type": "TextBlock",
            "text": "Hi ${employee.name}! Here's a bit about your org..."
        },
        {
            "type": "TextBlock",
            "text": "Your manager is: ${employee.manager.name}"
        },
        {
            "type": "TextBlock",
            "text": "3 of your peers are: ${employee.peers[0].name}, ${employee.peers[1].name}, ${employee.peers[2].name}"
        }
    ]
}

Opción B: Separación de la plantilla de los datos

como alternativa (y más probablemente), crearás una plantilla de tarjeta reutilizable sin incluir los datos. Esta plantilla se puede almacenar como archivo y agregar al control de origen.

EmployeeCardTemplate.json

{
    "type": "AdaptiveCard",
    "body": [
        {
            "type": "TextBlock",
            "text": "Hi ${employee.name}! Here's a bit about your org..."
        },
        {
            "type": "TextBlock",
            "text": "Your manager is: ${employee.manager.name}"
        },
        {
            "type": "TextBlock",
            "text": "3 of your peers are: ${employee.peers[0].name}, ${employee.peers[1].name}, ${employee.peers[2].name}"
        }
    ]
}

Luego, puedes cargarla y proporcionar los datos en tiempo de ejecución mediante los SDK de plantillas.

Ejemplo de JavaScript

Uso del paquete adaptivecards-templating.

var template = new ACData.Template({ 
    // EmployeeCardTemplate goes here
});

// Specify data at runtime
var card = template.expand({
    $root: {
        "employee": {
            "name": "Matt",
            "manager": { "name": "Thomas" },
            "peers": [{
                "name": "Andrew" 
            }, { 
                "name": "Lei"
            }, { 
                "name": "Mary Anne"
            }, { 
                "name": "Adam"
            }]
        }
    }
});

// Now you have an AdaptiveCard ready to render!

Compatibilidad del diseñador

El diseñador de tarjetas adaptables se ha actualizado para admitir plantillas.

Pruébalo en https://adaptivecards.io/designer

image

  • Editor de datos de ejemplo: Especifique los datos de ejemplo aquí para ver la tarjeta enlazada a datos en "Modo de vista previa". Hay un botón pequeño en este panel para rellenar la estructura de datos a partir de los datos de ejemplo existentes.
  • Modo de vista previa: presiona el botón de la barra de herramientas para alternar entre la experiencia de edición y la experiencia de vista previa de datos de ejemplo.
  • Open sample (Abrir ejemplo): haz clic en este botón para abrir varias cargas de ejemplo.

Enlace avanzado

Ámbitos de enlace

Hay algunas palabras clave reservadas para acceder a distintos ámbitos de enlace.

{
    "${<property>}": "Implicitly binds to `$data.<property>`",
    "$data": "The current data object",
    "$root": "The root data object. Useful when iterating to escape to parent object",
    "$index": "The current index when iterating"
}

Asignar un contexto de datos a elementos

Para asignar un "contexto de datos" a cualquier elemento, agrega un atributo $data al elemento.

{
    "type": "Container",
    "$data": "${mySubObject}",
    "items": [
        {
            "type": "TextBlock",
            "text": "This TextBlock is now scoped directly to 'mySubObject': ${mySubObjectProperty}"
        },
        {
            "type": "TextBlock",
            "text": "To break-out and access the root data, use: ${$root}"
        }
    ]
}

Repetición de elementos en una matriz

  • Si la propiedad $data de un elemento de tarjeta adaptable está enlazada con una matriz, el propio elemento se repetirá para cada elemento de la matriz.
  • Todas las expresiones de enlace (${myProperty}) usadas en los valores de la propiedad se limitarán al elemento individual dentro de la matriz.
  • Si el enlace es a una matriz de cadenas, usa ${$data} para acceder al elemento de cadena individual. Por ejemplo, "text": "${$data}"

Por ejemplo, el elemento TextBlock siguiente se repetirá 3 veces, ya que su valor de $data es una matriz. Observa cómo la propiedad text se enlaza con la propiedad name de un objeto individual dentro de la matriz.

{
    "type": "Container",
    "items": [
        {
            "type": "TextBlock",
            "$data": [
                { "name": "Matt" }, 
                { "name": "David" }, 
                { "name": "Thomas" }
            ],
            "text": "${name}"
        }
    ]
}

Elemento resultante:

{
    "type": "Container",
    "items": [ 
        {
            "type": "TextBlock",
            "text": "Matt"
        },
        {
            "type": "TextBlock",
            "text": "David"
        }
        {
            "type": "TextBlock",
            "text": "Thomas"
        }
    ]
}

Funciones integradas

Ningún lenguaje de plantillas se considera completo sin un conjunto avanzado de funciones auxiliares. Las plantillas de tarjetas adaptables se basan en Adaptive Expression Language (AEL), que es un estándar abierto para declarar expresiones que se pueden evaluar en muchas plataformas diferentes. Además, se trata de un supraconjunto adecuado de "Logic Apps", por lo que puedes usar una sintaxis similar a la de Power Automate, etc.

Esta es solo una pequeña muestra de las funciones integradas.

Consulta la lista completa de funciones precompiladas de Adaptive Expression Language.

Evaluación condicional

  • if(expresión, valorVerdadero, valorFalso)

Ejemplo de if

{
    "type": "TextBlock",
    "color": "${if(priceChange >= 0, 'good', 'attention')}"
}

Análisis de JSON

  • json(jsonString): analizar una cadena JSON

Ejemplo de json

Se trata de una respuesta de Azure DevOps en la que la propiedad message es una cadena serializada en JSON. Para acceder a los valores de la cadena, es necesario usar la función json de la plantilla.

Datos

{
    "id": "1291525457129548",
    "status": 4,
    "author": "Matt Hidinger",
    "message": "{\"type\":\"Deployment\",\"buildId\":\"9542982\",\"releaseId\":\"129\",\"buildNumber\":\"20180504.3\",\"releaseName\":\"Release-104\",\"repoProvider\":\"GitHub\"}",
    "start_time": "2018-05-04T18:05:33.3087147Z",
    "end_time": "2018-05-04T18:05:33.3087147Z"
}

Uso

{
    "type": "TextBlock",
    "text": "${json(message).releaseName}"
}

Elemento resultante

{
    "type": "TextBlock",
    "text": "Release-104"
}

Funciones personalizadas

Las funciones personalizadas se admiten mediante las API de los SDK de plantillas.

Diseño condicional con $when

Para quitar un elemento completo si se cumple una condición, usa la propiedad $when. Si $when se evalúa como false, el elemento no se mostrará al usuario.

{
    "type": "AdaptiveCard",
    "$data": {
        "price": "35"
    },
    "body": [
        {
            "type": "TextBlock",
            "$when": "${price > 30}",
            "text": "This thing is pricy!",
            "color": "attention",
        },
         {
            "type": "TextBlock",
            "$when": "${price <= 30}",
            "text": "Dang, this thing is cheap!",
            "color": "good"
        }
    ]
}

Composición de plantillas

Actualmente, no se admite la composición de "partes" de plantillas. Pero estamos explorando opciones y esperamos tener novedades pronto. Agradecemos cualquier idea al respecto.

Ejemplos

Examina la página de ejemplos actualizada para explorar todos los tipos de nuevas tarjetas con plantilla.