적응형 카드 템플릿 언어
템플릿 작성을 사용하면 적응형 카드의 레이아웃에서 데이터를 분리할 수 있습니다. 템플릿 언어는 템플릿을 작성하는 데 사용되는 구문입니다.
이에 대해서는 적응형 카드 템플릿 작성 개요를 참조하세요.
중요
2020년 5월 릴리스 후보의 주요 변경 내용
템플릿을 출시하기 위해 열심히 일했고 마침내 마지막 단계에 접어들었습니다! 릴리스를 마무리할 때 약간의 주요 변경 사항을 적용해야 했습니다.
2020년 5월 현재 주요 변경 내용
- 바인딩 구문이
{...}
에서${...}
로 변경되었습니다.- 예를 들어,
"text": "Hello {name}"
는"text": "Hello ${name}"
가 됩니다.
- 예를 들어,
데이터에 바인딩
템플릿을 작성하는 것은 카드의 "비정적" 콘텐츠를 "바인딩 식"으로 대체하는 것만큼 간단합니다.
정적 카드 페이로드
{
"type": "TextBlock",
"text": "Matt"
}
템플릿 페이로드
{
"type": "TextBlock",
"text": "${firstName}"
}
- 바인딩 식은 정적 콘텐츠가 포함될 수 있는 거의 모든 위치에 배치할 수 있습니다.
- 바인딩 구문은
${
로 시작하고}
로 끝납니다.${myProperty}
). - 개체 계층의 하위 개체에 액세스하려면 점 알림을 사용합니다.
${myParent.myChild}
). - 정상적으로 null 처리가 되면 개체 그래프의 null 속성에 액세스할 때 예외가 발생하지 않습니다.
- 배열의 키 또는 항목별로 속성을 검색하는 인덱서 구문를 사용합니다.
${myArray[0]}
).
데이터 제공
이제 템플릿이 완성되었으므로 완성된 데이터를 제공해야 합니다. 이를 수행하는 옵션은 다음과 같이 두 가지가 있습니다.
- 옵션 A: 템플릿 페이로드 내에서 인라인.
AdaptiveCard
템플릿 페이로드 내에서 데이터를 인라인으로 제공할 수 있습니다. 이렇게 하려면 루트AdaptiveCard
개체에$data
속성을 추가하기만 하면 됩니다. - 옵션 B: 별도의 데이터 개체. 이 옵션을 사용하면 런타임 시 템플릿 SDK, 즉,
template
및data
에 두 개의 별도의 개체를 제공합니다. 보통 템플릿을 만들고 나중에 동적 데이터를 제공하기 때문에 이 방법이 더 일반적인 방법입니다.
옵션 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 에서 사용해 보세요.
- 샘플 데이터 에디터 - "미리 보기 모드"에서 데이터 바인딩된 카드를 보려면 여기에 샘플 데이터를 지정합니다. 이 창에는 기존 샘플 데이터에서 데이터 구조를 채우는 작은 단추가 있습니다.
- 미리 보기 모드 - 도구 모음 단추를 눌러 편집 환경과 샘플 데이터 미리 보기 환경 간을 전환합니다.
- 샘플 열기 - 이 단추를 클릭하면 다양한 샘플 페이로드가 열립니다.
고급 바인딩
바인딩 범위
다양한 바인딩 범위에 액세스하기 위해 예약된 몇 가지 키워드가 있습니다.
{
"${<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
속성을 사용합니다. $when
이 false
로 평가되면 요소가 사용자에게 표시되지 않습니다.
{
"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"
}
]
}
템플릿 작성
현재 템플릿 "파트"를 함께 작성할 수는 없습니다. 그러나 이 옵션을 살펴보고 있으며 곧 더 많은 것을 공유하려고 합니다. 이에 대해 어떤 피드백이라도 환영합니다!
예
업데이트된 샘플 페이지를 찾아서 모든 종류의 새 템플릿 기반 카드를 살펴보세요.