diff --git a/Example/adaptive_card_sample.md b/Example/adaptive_card_sample.md new file mode 100644 index 0000000..9928582 --- /dev/null +++ b/Example/adaptive_card_sample.md @@ -0,0 +1,91 @@ +# Example +This tool requires two different JSON inputs: the *data model* (`data_model.json`), and the *card payload* (`card_payload.json`). + +## The Data Model +This renderer employs an expanded data model, which is designed to allow rendering cards dynamically based on the data model's contents. I created this for another UWP project I'm working on, and I needed a means of including every possible field in my *card payload*, without the renderer displaying empty fields. + +### Syntax +There are two sections of the data model JSON object. The `template` section is a set of key-value pairs giving a friendly display name to every data key in the `item` section. + +The `template` section should only include fields to be displayed by the card renderer. + +The data model `item` definition is composed of key-value pairs. Each value may be either a string, or a single-level array of strings. + +### Example +In the below example (also found in `data_model.json`), note that images require no friendly name, and one of the attributes, `clade`, contains an array of strings. + +```JSON +{ + "template" : + { + "image" : "image", + "clade" : "Clades", + "name" : "Common Name", + "order" : "Order", + "family" : "Family", + "genus" : "Genus", + "species" : "Species (Latin Name)" + }, + "item" : + { + "image" : "almonds.jpg", + "clade" : [ + "Tracheophytes", + "Angiosperms", + "Eudicots", + "Rosids" + ], + "name" : "American Hazelnut", + "order" : "Fagales", + "family" : "Betulaceae", + "genus" : "Corylus", + "species" : "Corylus Americana" + } +} +``` + +## The Card Payload +The card payload can be generated using Microsoft's [Adaptive Cards Designer](https://adaptivecards.io/designer/), or you can create it by hand. The card payload should contain **every possible field** that may be passed by the *data model*. + +Vanilla adaptive cards display all available fields, including those with no value. My implementation makes it possible to bypass rendering any field that isn't included in the *data model*'s `template` section, which allows the renderer to dynamically adjust the rendered card based on the *data model* provided. + +This example includes `card_payload.json`, which is a card payload with empty fields, along with the fields defined in the *data model*. Of note, the `clade` field, which contains an array in the *data model*, includes additional parameters: + +```JSON +... + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "width": "stretch", + "horizontalAlignment": "Right", + "items": [ + { + "type": "TextBlock", + "text": "{template.clade}", + "weight": "Bolder", + "horizontalAlignment": "Right" + } + ] + }, + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "Container", + "items": [ + { + "$data": "{item.clade}", + "type": "TextBlock", + "text": "{$data}" + } + ] + } + ] + } + ] + } +... +``` \ No newline at end of file diff --git a/Example/card_payload.json b/Example/card_payload.json new file mode 100644 index 0000000..09aece7 --- /dev/null +++ b/Example/card_payload.json @@ -0,0 +1,199 @@ +{ + "type": "AdaptiveCard", + "body": [ + { + "type": "Container", + "items": [ + { + "type": "TextBlock", + "text": "{item.name}", + "size": "Large", + "weight": "Bolder", + "horizontalAlignment": "Center", + "color": "Accent" + }, + { + "type": "Image", + "url": "{item.image}", + "altText": "" + }, + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "width": "stretch", + "horizontalAlignment": "Right", + "items": [ + { + "type": "TextBlock", + "text": "{template.other}", + "weight": "Bolder", + "horizontalAlignment": "Right" + } + ] + }, + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": "{item.other}" + } + ] + } + ] + }, + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "width": "stretch", + "horizontalAlignment": "Right", + "items": [ + { + "type": "TextBlock", + "text": "{template.name}", + "weight": "Bolder", + "horizontalAlignment": "Right" + } + ] + }, + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": "{item.name}" + } + ] + } + ] + }, + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "width": "stretch", + "horizontalAlignment": "Right", + "items": [ + { + "type": "TextBlock", + "text": "{template.order}", + "weight": "Bolder", + "horizontalAlignment": "Right" + } + ] + }, + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": "{item.order}" + } + ] + } + ] + }, + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "width": "stretch", + "horizontalAlignment": "Right", + "items": [ + { + "type": "TextBlock", + "text": "{template.family}", + "weight": "Bolder", + "horizontalAlignment": "Right" + } + ] + }, + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": "{item.genus}" + } + ] + } + ] + }, + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "width": "stretch", + "horizontalAlignment": "Right", + "items": [ + { + "type": "TextBlock", + "text": "{template.species}", + "weight": "Bolder", + "horizontalAlignment": "Right" + } + ] + }, + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": "{item.species}" + } + ] + } + ] + }, + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "width": "stretch", + "horizontalAlignment": "Right", + "items": [ + { + "type": "TextBlock", + "text": "{template.clade}", + "weight": "Bolder", + "horizontalAlignment": "Right" + } + ] + }, + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "Container", + "items": [ + { + "$data": "{item.clade}", + "type": "TextBlock", + "text": "{$data}" + } + ] + } + ] + } + ] + } + ] + } + ], + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.0" +} \ No newline at end of file diff --git a/Example/data_model.json b/Example/data_model.json new file mode 100644 index 0000000..baa9618 --- /dev/null +++ b/Example/data_model.json @@ -0,0 +1,27 @@ +{ + "template" : + { + "image" : "image", + "clade" : "Clades", + "name" : "Common Name", + "order" : "Order", + "family" : "Family", + "genus" : "Genus", + "species" : "Species (Latin Name)" + }, + "item" : + { + "image" : "almonds.jpg", + "clade" : [ + "Tracheophytes", + "Angiosperms", + "Eudicots", + "Rosids" + ], + "name" : "American Hazelnut", + "order" : "Fagales", + "family" : "Betulaceae", + "genus" : "Corylus", + "species" : "Corylus Americana" + } +} \ No newline at end of file diff --git a/README.md b/README.md index 3547c72..a4f9eb5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Adaptive-Card-Editor +# Adaptive Card Editor -An editor for Microsoft Adaptive Cards that supports the new templating language and DOESN'T use JavaScript, because JavaScript is fake and gay. +A UWP editor for Microsoft Adaptive Cards that supports the new templating language and DOESN'T use JavaScript, because JavaScript is fake and gay. ## Features * VSCode's amazing text editor, Monaco, is baked right in! @@ -8,6 +8,23 @@ An editor for Microsoft Adaptive Cards that supports the new templating language * Uses native .NET for everything! ## Planned Features -* Save your work! -* Style rendered output! -* Actually implement templating! \ No newline at end of file +### Save your work! +The goal is to make it possible to both save and read `zip` files containing the payload, the + +## Usage +This renderer takes JSON input to output a standard adaptive card. The top output box (labeled *UWP Library*) displays the formatted card payload without any data. The bottom output box (labeled *Template Library*) displays the formatted card payload with data. + +# About Adaptive Cards +Adaptive Cards is a Microsoft product that makes it relatively simple to generate a nicely-formatted display of data passed as JSON to the card renderer. You can learn more about adaptive cards [here](https://adaptivecards.io/). + +Microsoft has released SDKs to make it easier to implement adaptive cards on various platforms. The .NET SDK was originally a wrapper for the JavaScript SDK, so I wrote my own adaptive card renderer using pure .NET. + +## Microsoft's .NET SDK +It appears the latest [.NET SDK on GitHub](https://github.com/microsoft/AdaptiveCards/tree/main/source/dotnet) no longer relies on JavaScript for card rendering, which means that at some point, I might update this application to use Microsoft's library. + +On the other hand, my implementation takes no dependencies other than [Json.NET](https://www.newtonsoft.com/json), which is well-maintained, so I might just leave it as-is. My implementation hasn't been updated since 2020, so it doesn't support any features or changes since then. + +# Other Notes +This UWP app makes use of VSCode's very awesome text editor library, [Monaco](https://microsoft.github.io/monaco-editor/). + +It also implements a timer function, which allows realtime updates to both rendered sections as you work with the app. It makes use of [System.Windows.Threading.DispatcherTimer](https://docs.microsoft.com/en-us/dotnet/api/system.windows.threading.dispatchertimer?view=windowsdesktop-6.0) to handle realtime updates properly. \ No newline at end of file