# DPL 渲染指令结构(RenderDocument)

# 简介

当一个技能服务收到来自设备端的请求时,它可以以一个 DPL.RenderDocument 页面渲染指令作为响应(在 bot sdk:PHP SDK 技术文档Node.js SDK 技术文档中提供),在 RenderDocument 指令中包含了一个 document 字段内容作为页面渲染的模板描述,并指定一个唯一的 token 字段作为页面的标识下发该指令到支持 DPL 渲染的设备端上来渲染页面模板。

# 功能

用于渲染 DPL 模板指令,通过下发该指令在设备端上渲染一个 DPL 页面

# 指令参数与样例

# 指令参数

property type required default description
type DPL.directive DPL.RenderDocument 目前仅提供 DPL.RenderDocument 作为页面的渲染模板指令
token string - 作为当前页面渲染指令在页面渲染后的唯一标识
document DPL_DOCUMENT - 包含渲染环境、指定渲染页面的 document 协议内容数据对象,具体格式详见 document

# 指令样例

{
  "type":"DPL.RenderDocument",
  "token": "{{STRING}}",
  "document": {{DPL_DOCUMENT}}
}

# document

DPL document 是一个基于 bot 协议的描述、有着完整结构定义的 JSON 对象数据,它定义了协议中对应于在页面中需要渲染展现的动态渲染模板部分(包括在页面上渲染展示的所有组件、数据内容和布局结构)以及设定页面模板的默认配置和交互能力(无交互超时退出时间、预设事件绑定指令执行机制等)。

该字段的解析都必须通过 bot 端下发的方式来执行,目前对于 DPL document 字段属性有两种应用场景:

  1. DPL.RenderDocument 指令下发必须包含该字段;
  2. DPL.ExecuteCommands 指令中包含 document 更新的指令类型必须包含该字段;

# document 结构样例

{
  "type":"DPL",
  "version":"2.0",
  "duration": {{INTEGER}},
  "onStackDuration": {{INTEGER}},
  "pageName": "{{STRING}}",
  "renderConfig": {
    "viewport": {
      "width": "{{STRING}}",
      "height": "{{STRING}}"
    },
    "globalVslDisabled": {{BOOLEAN}}
  },
  "events": {
    "{{STRING}}": ["{{COMMAND}}", ...],
    ...
  },
  "resources":[
    {
      "description": "{{STRING}}",
      "colors": {
        "{{STRING}}": "{{Color}}"
      }
    },
    {
      "description": "{{STRING}}",
      "dimensions": {
        "{{STRING}}": "{{STRING}}"
      }
    },
    ...
  ],
  "styles":{
    "{{STRING}}": {
      "extend":[
        "{{STRING}}"
      ],
      "values": {
        "{{ATTRIBUTE}}": "{{STRING}}"
      }
    },
    "{{STRING}}": {
       "values": {
          "{{ATTRIBUTE}}": "{{STRING}}"
       }
    }
    ...
  },
  "dataSource": {
    "{{STRING}}": {
      "{{STRING}}": "{{STRING}}",
      ...
    }
  },
  "layouts":{
    "{{STRING}}": {
      "parameters": [
        "{{PARAM}}",
        ...
      ],
      "item": [
        {{COMPONENT}},
        ...
      ]
    }
  },
  "stylesheet": [
    {
      "{{STRING}}": {
        "{{STRING}}": "{{STRING}}"
      },
      ...
    },
    {
      "mediaQuery": "{{STRING}}",
      "classList": {
        "{{STRING}}": {
          "{{STRING}}": "{{STRING}}"
        }
      }
    }
  ],
  "abilities": [
    {
      "type": "{{ENUM}}",
      "componentId": "{{STRING}}",
      "events": {
        "{{STRING}}": [{{COMMANDS}}, ...],
        ...
      }
    },
    ...
  ],
  "mainTemplate": {
    "parameters": [
      "payload"
    ],
    "items": [
      {{COMPONENT}},
      ...
    ]
  }
}

# 参数说明

  • type
    • 指令类型,即"DPL"
  • version
    • 指定版本信息,目前推荐使用 2.0 版本
  • (optional)renderConfig
    • 页面渲染配置信息
      • viewport
        • 页面可视区域大小
  • (optional)duration
    • 用户指定模版无交互超时退出时间,单位毫秒ms, 取值需要大于0, 默认 30 秒
  • (optional)onStackDuration
    • 当模版被压栈时的超时退出时间,单位毫秒ms, 默认 10 分钟
  • (optional)pageName
    • 全局定义的 pageName 参数,用来给 bot 端定义该页面的名称
  • (optional)events
    • 基于模板的全局 events 描述
  • (optional)resources
    • 用户自定义 style 的属性常量, 可以在 styles 属性中引用属性常量, 引用方式@
    • 对应的属性只能是 description、colors、dimensions
    • description
      • 对属性常量的描述,解析的时候会被忽略
    • colors
      • 定义颜色的属性常量,只能是颜色值
    • dimensions
      • 定义其他属性值, 如宽高、左右间距
  • (optional)styles
    • 用户自定义 styles 样式, 可以在 COMPONENT 中引入对应的自定义 styles 名称
  • (optional)dataSource
    • 用户自定义的数据部分, 可以在 COMPONENT 中引用 dataSource, 引用方式${}
  • (optional)layouts
    • 用户自定义样式, 可以在 mainTemplate 中的 items 中引用自定义的 layout
  • (optional)stylesheet
    • 通过 class 与 mediaQuery 的组合使用,更好的支持基于不同尺寸的设备适配
      • 配置形式一
        • 'classNameString'
          • 样式聚合类名
        • {'styleNameString': 'styleProp'}
          • 样式属性对象
      • 配置形式二
        • mediaQuery
          • 设备类型(X5)或设备条件判断属性
        • classList
          • 样式聚合类列表
            • 'classNameString'
              • 样式聚合类名
            • {'styleNameString': 'styleProp'}
              • 样式属性对象
  • (optional)abilities
    • 模板接入的能力,数组: ability[]
      • ability
        • 能力组件,目前支持了手势(Gesture),表单(Form)能力
  • mainTemplate
    • 基于嵌套组件组合的模板解析入口
      • parameters
        • 指定 dataSource 的引用别名
      • items
        • 模版的子组件数组

# 重点参数描述

# document.mainTemplate

基于嵌套组件组合的模板解析入口

  • parameters
    • 作为指定 dataSource 数据源的引用别名
  • items
    • 模版的嵌套子组件数组,基于嵌套的结构和组件的类型提供了整个模板页面的渲染展现和布局、功能
"mainTemplate": {
  "parameters": [
    "payload"
  ],
  "items": [{
    "type": "Container",
    "styles": {
      "flex": 1
    },
    "items": [{
        "type": "Image",
        "componentId": "background",
        "styles": {
          "position": "absolute",
          "left": "0dp",
          "top": "0dp",
          "scale-type": "centerCrop",
          "height": "100%",
          "width": "100%"
        },
        "props": {
          "src": "https://duerstatic.cdn.bcebos.com/swan%2Fdpl_demo%2Fcommon-bg.png"
        }
      },
      {
        "type": "Header",
        "props": {
          "title": "title 展现,基础布局结构",
          "sideIcon": "https://d2o906d8ln7ui1.cloudfront.net/images/cheeseskillicon.png",
          "sideText": "demo2.0"
        }
      },
      {
        "type": "Container",
        "styles": {
          "flex": 1,
          "background-color": "rgba(1, 1, 1, .8)",
          "flex-direction": "column",
          "align-items": "center"
        },
        "items": []
      }
    ]
  }]
}

# document.abilities

模板接入的非展现类能力,数组类型: ability[]

  • ability
    • 能力组件
      • Gesture

        • 支持在端上打开手势识别能力,可以识别 手掌,Ok类型手势,触发对应的事件:
          • onPalm
            • 识别手掌手势成功,触发事件
          • onOk
            • 识别Ok手势成功,触发事件
      • Form

        • 支持表单能力,可以声明多个表单项组件(Input)属于该表单,然后基于调用表单方法与事件统一、部分操控表单项
          • onReady
            • 表单中所有表单项满足校验条件,进入可被提交状态
          • onPrepare
            • 表单中存在部分表单项未满足校验条件,不可被提交
          • onSubmit
            • 表单成功提交 = onValidateFail
            • 表单提交验证失败
"abilities": [{
    "type": "Form",
    "componentId": "demo_form",
    "events": {
      "onSubmit": [{
        "type": "SendEvent",
        "componentId": "demo_form",
        "arguments": ["demo_form_submit"]
      }]
    }
  },
  {
    "type": "Gesture",
    "componentId": "demo_gesture",
    "props": {
      "enable": true
    },
    "events": {
      "onOk": [{
        "type": "SendEvent",
        "componentId": "demo_gesture_ok"
      }],
      "onPalm": [{
        "type": "SendEvent",
        "componentId": "demo_gesture_palm"
      }]
    }
  }
]

# document.stylesheet

页面样式属性基于 class 类的聚合与设置不同类型的设备屏幕分辨率条件,选择不同的样式属性配置能力

  • 通过 class 与 mediaQuery 的组合使用,更好的支持基于不同尺寸的设备适配 - 配置形式一 - 'classNameString' - 样式聚合类名 - {'styleNameString': 'styleProp'} - 样式属性对象 - 配置形式二 - mediaQuery - 设备类型(X5)或设备条件判断属性 - classList - 样式聚合类列表 - 'classNameString' - 样式聚合类名 - {'styleNameString': 'styleProp'} - 样式属性对象
"stylesheet": [{
    "bubble_Hint": {
      "height": "44dp",
      "padding-left": "24dp",
      "padding-right": "24dp",
      "min-width": "120dp",
      "max-width": "600dp",
      "justify-content": "center",
      "align-items": "center",
      "background-color": "rgba(255, 255, 255, 0.1)",
      "border-radius": "18dp 20dp 20dp 0dp"
    },
    "test-height": {
      "height": "320dp"
    }
  },
  {
    "mediaQuery": "x5",
    "classList": {
      "test-height": {
        "height": "220dp"
      }
    }
  }
]

# document.renderConfig

页面渲染配置信息

  • viewport
    • 页面可视区域大小,通过设置viewport,可实现不同分辨率屏幕的适配(viewport.height 与 viewport.width不能同时使用,width 设定优先级高于 height)
      • width
        • 设置viewport的宽度,根据viewport宽度与屏幕宽度的比例,将viewport等比缩放到整个屏幕(默认,show端设备宽 960dp)
      • height
        • 设置viewport的高度,根据viewport高度与屏幕高度的比例,将viewport等比缩放到整个屏幕(show端设备高 562dp)
  • globalVslDisabled
    • 页面中对应所有组件是否禁用组件自身的默认话术语音注册的总开关(默认启用 false,若该字段为 true, 则禁用掉端上组件注册的所有话术内容。用户的语音请求或意图都将交由服务端来进行处理)
"renderConfig": {
  "viewport": {
    "width": 960,
    "height": 562
  },
  "globalVslDisabled": false
}

# document.events

适用于dpl应用模板的全局事件,在模板执行触发对应事件时(例如页面模板加载完成后,onLoaded事件触发),执行绑定的相应指令

  • onLoaded
    • 页面渲染完成时触发该事件,兼容旧版(loaded)事件类型
  • onPagePause
    • 页面被压栈时触发该事件(该事件无法触发执行SendEvent、ClickLink、SendLog等事件上报类型指令)
  • onPageResume
    • 页面压栈被恢复时触发该事件

# document.resources

属性名称自定义

  • values
    • 自定义样式包含的属性
  • extend
    • 继承其他的自定义的属性, 要避免环状继承关系
"resources": [{
    "description": "Stock color for the light theme",
    "colors": {
      "colorTextPrimary": "#151920"
    }
  },
  {
    "description": "Stock color for the dark theme",
    "colors": {
      "colorText": "#f0f1ef"
    }
  },
  {
    "description": "Standard font sizes",
    "dimensions": {
      "textSizeBody": 48,
      "textSizePrimary": 27,
      "textSizeSecondary": 23,
      "textSizeSecondaryHint": 25
    }
  }
]

# document.styles

样式对象属性引用,注意:如果在组件内部同时声明了相同的样式属性,该外部样式属性值会被覆盖掉

  • values
    • 自定义样式包含的属性
  • extend
    • 继承其他的自定义的属性, 要避免环状继承关系
"styles": {
  "textStylePrimary": {
    "extend": [
      "textStyleBase1",
      "textStyleBase0"
    ],
    "values": {
      "width": 80
    }
  },
  "textStyleBase0": {
    "description": "This version of basic font",
    "extend": "textStyleBase",
    "values": {
      "height": 100
    }
  },
  "textStyleBase": {
    "description": "Base font description set color",
    "values": {
      "color": "@colorTextPrimary"
    }
  }
}

# document.dataSource

  • 内部自定义数据源,会在组件中引用

  • 参数的层级关系和名称需要在引用的时候一一对应

"dataSource": {
  "backgroundImage": {
    "url": "image-url"
  },
  "mylayout1": {
    "text": "This is mylayout1 text"
  },
  "data": {
    "title": {
      "text": "title text"
    },
    "image": {
      "url": "data-image-url"
    },
    "content": {
      "text": "This is a customs text!"
    }
  }
}

# document.layouts

自定义布局, 支持嵌套

  • parameters
    • 组件的参数名称,引用的时候需要对应上
  • item
    • 基础组件的数组
"layouts": {
  "mylayout1": {
    "parameters": [
      "dataLayout"
    ],
    "item": [{
      "type": "Container",
      "styles": {
        "width": "100dp",
        "height": "100dp"
      },
      "items": [{
        "type": "Text",
        "styles": {
          "color": "@colorTextPrimary"
        },
        "props": {
          "text": "${dataLayout.text}"
        },
        "style": "textStylePrimary"
      }]
    }]
  }
}

# document 完整样例

{
  "type": "DPL",
  "version": "2.0",
  "duration": 120000,
  "renderConfig": {
    "viewport": {
      "width": 960
    }
  },
  "events": {
    "onLoaded": [{
      "type": "SendEvent",
      "componentId": "DPL"
    }]
  },
  "dataSource": {
    "text": "示例文案"
  },
  "abilities": [{
      "type": "Form",
      "componentId": "demo_form",
      "events": {
        "onSubmit": [{
          "type": "SendEvent",
          "componentId": "demo_form",
          "arguments": ["demo_form_submit"]
        }]
      }
    },
    {
      "type": "Gesture",
      "componentId": "demo_gesture",
      "props": {
        "enable": true
      },
      "events": {
        "onOk": [{
          "type": "SendEvent",
          "componentId": "demo_gesture_ok"
        }],
        "onPalm": [{
          "type": "SendEvent",
          "componentId": "demo_gesture_palm"
        }]
      }
    }
  ],
  "mainTemplate": {
    "parameters": [
      "payload"
    ],
    "items": [{
      "type": "Container",
      "style": {
        "flex": 1,
        "background-color": "#222"
      },
      "items": [{
        "type": "Image",
        "props": {
          "src": "https://duerstatic.cdn.bcebos.com/swan/square/square_bg.webp"
        },
        "styles": {
          "width": "100%",
          "height": "100%",
          "scale-type": "centerCrop"
        }
      }, {
        "type": "Text",
        "props": {
          "text": "${payload.text}"
        },
        "styles": {
          "margin-bottom": "10dp",
          "font-size": "28dp",
          "color": "#fff"
        }
      }]
    }]
  }
}