다음을 통해 공유


적응형 카드 템플릿 언어

템플릿 작성을 사용하면 적응형 카드의 레이아웃에서 데이터를 분리할 수 있습니다. 템플릿 언어는 템플릿을 작성하는 데 사용되는 구문입니다.

이에 대해서는 적응형 카드 템플릿 작성 개요를 참조하세요.

중요

2020년 5월 릴리스 후보주요 변경 내용

템플릿을 출시하기 위해 열심히 일했고 마침내 마지막 단계에 접어들었습니다! 릴리스를 마무리할 때 약간의 주요 변경 사항을 적용해야 했습니다.

2020년 5월 현재 주요 변경 내용

  1. 바인딩 구문이 {...}에서 ${...}로 변경되었습니다.
    • 예를 들어, "text": "Hello {name}""text": "Hello ${name}"가 됩니다.

데이터에 바인딩

템플릿을 작성하는 것은 카드의 "비정적" 콘텐츠를 "바인딩 식"으로 대체하는 것만큼 간단합니다.

정적 카드 페이로드

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

템플릿 페이로드

{
   "type": "TextBlock",
   "text": "${firstName}"
}
  • 바인딩 식은 정적 콘텐츠가 포함될 수 있는 거의 모든 위치에 배치할 수 있습니다.
  • 바인딩 구문은 ${로 시작하고 }로 끝납니다. ${myProperty}).
  • 개체 계층의 하위 개체에 액세스하려면 점 알림을 사용합니다. ${myParent.myChild}).
  • 정상적으로 null 처리가 되면 개체 그래프의 null 속성에 액세스할 때 예외가 발생하지 않습니다.
  • 배열의 키 또는 항목별로 속성을 검색하는 인덱서 구문를 사용합니다. ${myArray[0]}).

데이터 제공

이제 템플릿이 완성되었으므로 완성된 데이터를 제공해야 합니다. 이를 수행하는 옵션은 다음과 같이 두 가지가 있습니다.

  1. 옵션 A: 템플릿 페이로드 내에서 인라인. AdaptiveCard 템플릿 페이로드 내에서 데이터를 인라인으로 제공할 수 있습니다. 이렇게 하려면 루트 AdaptiveCard 개체에 $data 속성을 추가하기만 하면 됩니다.
  2. 옵션 B: 별도의 데이터 개체. 이 옵션을 사용하면 런타임 시 템플릿 SDK, 즉, templatedata에 두 개의 별도의 개체를 제공합니다. 보통 템플릿을 만들고 나중에 동적 데이터를 제공하기 때문에 이 방법이 더 일반적인 방법입니다.

옵션 A: 인라인 데이터

{
    "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}"
        }
    ]
}

옵션 B: 데이터에서 템플릿 분리

또는 데이터를 포함하지 않고 다시 사용할 수 있는 카드 템플릿을 만드는 것이 좋습니다. 이 템플릿을 파일로 저장하고 소스 제어에 추가할 수 있습니다.

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}"
        }
    ]
}

그런 다음, 템플릿 작성 SDK를 사용하여 이를 로드하고 런타임에 데이터를 제공합니다.

JavaScript 예제

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!

디자이너 지원

적응형 카드 디자이너는 템플릿 작성을 지원하도록 업데이트되었습니다.

https://adaptivecards.io/designer 에서 사용해 보세요.

image

  • 샘플 데이터 에디터 - "미리 보기 모드"에서 데이터 바인딩된 카드를 보려면 여기에 샘플 데이터를 지정합니다. 이 창에는 기존 샘플 데이터에서 데이터 구조를 채우는 작은 단추가 있습니다.
  • 미리 보기 모드 - 도구 모음 단추를 눌러 편집 환경과 샘플 데이터 미리 보기 환경 간을 전환합니다.
  • 샘플 열기 - 이 단추를 클릭하면 다양한 샘플 페이로드가 열립니다.

고급 바인딩

바인딩 범위

다양한 바인딩 범위에 액세스하기 위해 예약된 몇 가지 키워드가 있습니다.

{
    "${<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"
}

요소에 데이터 컨텍스트 할당

"데이터 컨텍스트"를 요소에 할당하려면 $data 특성을 해당 요소에 추가합니다.

{
    "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}"
        }
    ]
}

배열의 항목 반복

  • 적응형 카드 요소의 $data 속성이 배열에 바인딩되는 경우 배열의 각 항목에 대해 요소 자체가 반복됩니다.
  • 속성 값에 사용된 모든 바인딩 식(${myProperty})의 범위는 배열 내의 개별 항목으로 지정됩니다.
  • 문자열 배열에 바인딩하는 경우 ${$data}를 사용하여 개별 문자열 요소에 액세스합니다(예: "text": "${$data}").

예를 들어 해당 $data가 배열이므로 아래 TextBlock이 세 번 반복됩니다. text 속성이 배열 내 개별 개체의 name 속성에 바인딩되는 방법을 확인합니다.

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

결과:

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

기본 제공 함수

풍부한 도우미 함수가 없으면 템플릿 작성 언어가 완전하지 않습니다. 적응형 카드 템플릿은 여러 플랫폼에서 평가할 수 있는 식 선언의 개방형 표준인 AEL(Adaptive Expression Language) 위에 빌드됩니다. 또한 "Logic Apps"의 적절한 상위 집합이므로 Power Automate 등과 유사한 구문을 사용할 수 있습니다.

이는 기본 제공 함수의 작은 샘플링입니다.

Adaptive Expression Language Pre-built 함수의 전체 목록을 확인합니다.

조건부 평가

  • if(expression, trueValue, falseValue)

if 예제

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

JSON 구문 분석

  • json(jsonString) - JSON 문자열 구문 분석

json 예제

message 속성이 직렬화된 JSON 문자열인 Azure DevOps 응답입니다. 문자열 내의 값에 액세스하려면 템플릿에서 json 함수를 사용해야 합니다.

데이터

{
    "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"
}

사용법

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

결과

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

사용자 지정 함수

사용자 지정 함수는 템플릿 SDK의 API를 통해 지원됩니다.

$when이 있는 조건부 레이아웃

조건이 충족되는 경우 전체 요소를 삭제하려면 $when 속성을 사용합니다. $whenfalse로 평가되면 요소가 사용자에게 표시되지 않습니다.

{
    "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"
        }
    ]
}

템플릿 작성

현재 템플릿 "파트"를 함께 작성할 수는 없습니다. 그러나 이 옵션을 살펴보고 있으며 곧 더 많은 것을 공유하려고 합니다. 이에 대해 어떤 피드백이라도 환영합니다!

업데이트된 샘플 페이지를 찾아서 모든 종류의 새 템플릿 기반 카드를 살펴보세요.