※2019/3/11に内容を更新しました。
今回は、画面デザインを定義する APL ドキュメントとその構成要素を紹介します。
APLでは画面デザインを JSON オブジェクトで定義しますが、これを APL ドキュメント と呼びます。 下の aplDocument
が簡単な APL ドキュメントの例です。 "こんにちは" というテキストとURLで指定された画像が、画面中央に縦に並んで表示されます。
handle(handlerInput) {
const aplDocument =
{
"type": "APL",
"version": "1.0",
"mainTemplate": {
"item": {
"type": "Container",
"direction": "column",
"alignItems": "center",
"justifyContent": "center",
"width": "100vw",
"height": "100vh",
"items": [
{
"type": "Text",
"text": "こんにちは"
},
{
"type": "Image",
"source": "https://d2o906d8ln7ui1.cloudfront.net/images/cheeseskillicon.png",
"width": "120dp",
"height": "120dp"
}
]
}
}
};
return handlerInput.responseBuilder
.addDirective({
type : 'Alexa.Presentation.APL.RenderDocument',
version: '1.0',
document: aplDocument,
datasources: {}
})
.getResponse();
}
type
と version
はお決まりです。 APLでは、画面配置の定義を レイアウト、配置される各要素を コンポーネント と呼びます。 mainTemplate
の部分が最初に表示されるレイアウト、mainTemplate.item にコンポーネントを指定します。 例中では APL Text と APL Image コンポーネントを利用していますが、それぞれを JSONの object
として定義し、type
プロパティでコンポーネントの種類を指定します。 その他利用できるコンポーネントの種類や各コンポーネントのプロパティなどの詳細は、 APLのコンポーネント を参照してください。 また、プロパティで扱う値に関しては、 APLのデータ型 をご参照ください。
実はレイアウトは子コンポーネントを1つだけ持ちます。 複数のコンポーネントを配置する場合には APL Containerを利用します。 横方向や縦方向にコンポーネントを並べて配置することもできますし、絶対値で指定の場所に配置することもできます。 また、APL Container はネストする形で、子 APL Container を含めることもできます。上下左右のパディング、アライメント、スペーシングなど細かく指定できますので、いろいろ試してみてください。
下例は Alexa DevSummit Tokyo 2018 公式スキル の画面ですが、コンポーネントを縦方向に配置してこのような画面を実装しています。
静的にコンポーネントを配置する APL Container 以外にも、動的データを配置するのに適した APL Sequenceや APL Pagerもあります。 これらは後ほどまた紹介します。
パラメータとデータバインディングを使うことで、画面の内容に変化をつけることができます。 下の例は、mainTemplate にパラメータ payload
を定義して、 それを介してプログラムから データソース を受け取り、${payload.myData.title} として参照しています。 datasources
に渡すオブジェクトは、一つ以上のオブジェクト(下例では myData)を含むようにしてください。 このように参照値を含む式をプロパティ値として利用することを データバインディング と呼びます。
handle(handlerInput) {
const aplDocument =
{
"type": "APL",
"version": "1.0",
"mainTemplate": {
"parameters": [
"payload"
],
"item": {
"type": "Text",
"text": "${payload.myData.title}",
"width": "100vw",
"height": "100vh",
"textAlign": "center",
"textAlignVertical": "center"
}
}
};
const data =
{
myData: {
title: 'こんばんは'
}
}
return handlerInput.responseBuilder
.addDirective({
type : 'Alexa.Presentation.APL.RenderDocument',
version: '1.0',
document: aplDocument,
datasources: data
})
.getResponse();
}
下例では色値を colorTextPrimary という名前のリソースとして定義することで、以降、直接の色値の代わりに @colorTextPrimary という構文で共通して参照できるようになります。 リソースは APLドキュメントの resources
で指定します。
また、 いくつかのプロパティ設定 をスタイルとして定義することができます。 APLコンポーネントの style
プロパティに、スタイル名を指定することで、同様のスタイルをもつ複数のAPLコンポーネントで定義を共有することができます。 スタイルは APLドキュメントの styles
で定義します。
他にも レイアウト を再利用するしくみや、別ファイルで定義したドキュメントを インポートするしくみ などもあります。 リソースやスタイル・レイアウトなどを上手に使うことで、定義が簡単になるだけでなく、メンテナンス性に大きく影響しますので、是非ご活用ください。
また、下例の resources
の中に when
というプロパティがあります。 式中の viewport
はスキルが動作するデバイスの特性を示すもので、この例では Echo Spot の画面のように円形かどうかを検査して、テキストの色を変化させています。 when
プロパティは、リソースやスタイル、レイアウトなどで幅広く利用できます。 いずれも when
プロパティが true
のとき、そのオブジェクトが採択されますが、リソースやスタイルの配列では true
になった後者の定義で上書きされるのに対し、レイアウトのコンポーネント配列では最初に true
になったコンポーネントが採択されます。 詳しくは こちらをご参照ください。条件式を上手に使うことで、デバイスの特性やデータソースの状況に応じて、表示を最適化することができます。
{
"type": "APL",
"version": "1.0",
"resources": [
{
"colors": {
"colorTextPrimary": "#00FFFF"
}
},
{
"when": "${viewport.shape == 'round'}",
"colors": {
"colorTextPrimary": "#FF00FF"
}
}
],
"styles": {
"myTextStyle1": {
"values": {
"color": "@colorTextPrimary",
"fontStyle": "italic"
}
}
},
"mainTemplate": {
"item": {
"type": "Container",
"alignItems": "center",
"justifyContent": "center",
"width": "100vw",
"height": "100vh",
"items":[
{
"type": "Text",
"style": "myTextStyle1",
"text": "こんにちは"
},
{
"type": "Text",
"style": "myTextStyle1",
"text": "こんばんは"
}
]
}
}
}
リソースやスタイル、Viewport のプロファイル、レイアウトなど、Amazon から提供される Alexa パッケージ があります。 Alexa パッケージを利用することにより、いろいろな画面付きデバイスを考慮した、統一されたデザインが手軽に実装できます。 下のように Alexa パッケージを名前でインポートすることで、Alexaのリポジトリから取得されますので、別途パッケージのダウンロードは必要ありません。
"import": [
{
"name": "alexa-styles",
"version" : "1.0.0"
}
]
「 はじめての APL 」の回でも紹介しましたが、APL ドキュメントとサンプルデータソースを1つのJSONファイルにまとめると、開発者コンソールの APLオーサリングツール で画面デザインの確認と編集をすることができます。
以下、アップロードするファイルの例です。
{
"document": {
"type": "APL",
"version": "1.0",
"import": [
{
"name": "alexa-styles",
"version" : "1.0.0"
}
],
"mainTemplate": {
"parameters": [
"payload"
],
"item": {
"type": "Container",
"alignItems": "center",
"justifyContent": "center",
"width": "100vw",
"height": "100vh",
"items": [
{
"type": "Text",
"style": "textStyleBody",
"text": "${payload.sample.message}"
},
{
"type": "Image",
"source": "${payload.sample.imageurl}",
"width": "120dp",
"height": "120dp"
}
]
}
}
},
"datasources": {
"sample": {
"message": "こんにちは",
"imageurl": "https://d2o906d8ln7ui1.cloudfront.net/images/cheeseskillicon.png"
}
}
}
開発者コンソールの「ビルド」タグの左側、「画面表示」をクリックすると、次のような画面が現れます。 ここで「コードをアップロード」を選んで、ファイルを選択してください。
すると次のような画面が表示されます。
① 表示する各画面タイプを選択します。
② ここを選択すると、レイアウトのコンポーネントツリーが下に表示されます。 ツリー内のコンポーネントを選択すると、そのコンポーネントのプロパティの一覧が右に表示されます。
③ ここを選択すると、データーソースのサンプルが表示されます。
④ ここでその他のAPLドキュメントの要素が参照できます。
各画面タイプで表示具合を確認してください。(ただし実際のデバイスとは表示の具合が異なる場合もあります)
今回のご紹介はここまでになります。 APLドキュメントの全体像が見えてきましたでしょうか? できれば、前回ダウンロードしたサンプルがどのように定義されているのか、観察してみてください。 テンプレートのどこを変更すればどのような効果があるのか分かるようになったら、是非テンプレートのカスタマイズにもチャレンジしてみてください。