Smart Page API
基本逻辑
1. 应用
一篇 Markdown 文档需要成为一个 SmartPage,必须要在 metadata 的声明中,使用app: page
,这样系统最终才会使用 Smart Page 的逻辑完成全文的渲染。
当然,如果直接使用可视化的界面生成的 SmartPage,最终也是一个内部声明了 app: page
的 Markdown 文档。
2. 声明与匹配
Smart Page 实际上由多个片段组成的,不同片段可以呈现不同的模板。
// cover
或 // cover(layout="lr", more_links_label="Download")
作为单独一行,作为一个 Smart Page 一部分的头部声明。
比如 cover
这个意思是使用 /template/cover.jade
来渲染当前的片段,layout="lr", more_links_label="Download"
则是作为额外的参数传递给/template/cover.jade
完成渲染。
3. 样式微调
// cover
```css
p {line-height: 3.5 !important}
```
紧跟一个片段的头部声明之后,可以是一个css
的代码片段,这个是对当前片段最终的 HTML 页面样式的微调。
模板将处理的参数
dom_id
这是一个随机生成的 id,一般可以作为 Dom 的 id,以方便 javascript 的调用 (如果有需要)。
parts_count
类型为整数
,表示当前页面是由几个 Layout 共同的组成的。
humech (核心数据参数)
在后面的文档具体说明,是 SmartPage 中承载页面结构后的数据对象。
其它额外参数
额外参数是使用者使用时额外指定的,比如上行这样的声明,就会额外传递layout
、more_links_label
这两个参数,以供模板调用。
humech的构建逻辑
这是将 Markdown 内容重新解析,从而获得的结构化数据,再通过模板的逻辑,渲染为新的 HTML 片段。
humech 分割的依据是层级标题。
举例
hello world, head
## title 1
content1
## title2
content2
### I am a sub title
sub content
如上,大抵最终会分解为<head>, <children:[title1, title2]>
子属性
head: dict 型, 是 head 的原始内容解析后的结果。
children: list型,每个 child 和 head 一样,都是 dict 型,是内容的解构后相应的信息。
humech 对象
humech 对象是指一个具体的内容片段,进行分析后,形成的描述性信息数据。它本身是一个 dict 类型的数据。
content
形成 humech 对象的原始内容,默认为 HTML 格式。
words
content 的总字数,英文单词计为1,中日韩一字计为1,类型为整数
。
title
以 h1-h6 的标题层级分割时,标题的文本,(如果是 head 对象时,也可能为空)。
links
当前片段内包含的超级链接,类型为一个列表。
每个 link 都是 dict 类型,一般有以下属性:
text: 相当于 link的 innerHTML
href: 跳转的 URL
title: A类型 DOM元素的 title 属性
alt: A类型 DOM元素的 alt 属性
class: A类型 DOM元素的 class 属性
.etc
links_count
整数,即 links 包含几个元素。
images
当前片段内包含的图片,类型为一个列表。
每个 image 都是 dict 类型,一般有以下属性:
src: 图片的实际 URL 地址
title: IMG 类型 DOM元素的 title 属性
alt: IMG 类型 DOM元素的 alt 属性
class: IMG 类型 DOM元素的 class 属性
.etc
images_count
整数,即 images 包含几个元素。
lazy_list
如果内容片段内每一行都是key: value
的形式,可以提取到 lazy_list。是一个ListItem
对象,该对象的数据类型为 dict。
lists
内容片段内,有序、无序列表分析得到的结构,类型为 list
, 每个子元素本身是一个 dict 类型数据,也是一个ListItem
对象。
head
当前内容片段分解后,仍然是 head+children 的结构,本身也是一个 humech 对象,相当于递归。不会出现 head.head
的情况,仅会出现 child.head
的情况。
children
当前内容片段分解后,仍然是 head+children 的结构,children 的组成 child本身也是一个 humech 对象,相当于递归。也可能是空列表。
ListItem 对象
这是 ul/ol 分解获得的信息对象,也可能是 lazylist 自动推断获取的。
ListItem 是一个 dict 类型,有两个属性,elements
与 meta
。
elements
elements
是一个 list, 每个element
是一个 dict 类型,视为 ListElement对象
meta
meta
是一个 dict 类型,是描述 elements 中的属性,有以下属性:
key_is_number: 每个 element 的 key 都是 float or int 类型
value_is_number: 每个 element 的 value 都是 float or int 类型
has_values: 每个 element 的 sub_values 这个属性不为空
ListElement 对象
key
比如一个 element 的原始文本是key: value
,那么 key 的值就是 key
。
value
比如一个 element 的原始文本是key: value
,那么 value 的值就是 value
。
sub_values
这是一个 list 类型,可能为空。
比如一个 element 的原始文本是key: value @sub_value1 @sub_value2
,那么 sub_values 就是['sub_value1', 'sub_value2']
。
extra
一个 dict 类型,是对当前 element 的特别属性补充。比如key(extra1=1, extra2=2): value
, 就可以获得两个额外的参数 extra1 & extra2。
content
这个是 ul/ol 分解后特有的属性,lazy_list内的一个 element 并不会有这个属性,是一个 li 的原始内容,相当于 li 的 innerTEXT。
如果是 ul/ol 分解后的 element,也可能没有 key、value、sub_values、extra 四个属性。
其它解构属性
images
、images_count
、links
、links_count
是 ul/ol 分解的信息中可能存在的字段,跟humech 对象
中的同名的类型、子属性一致。
限制
Smart Page 在解构 humech 对象的行为,会消耗比较多的计算资源,同时也会产生冗余几倍的存储空间,为了保证的基础性能,会有些限制:
- 单个片段不能超过 5000 字符;
- 如果完整文章作为一个 humech 的全生成 (比如fullpage/slide),全文不超过20000字符。
- 由于 Smart Page 本身会在一个完整的页面内会揉和很多不同的片段,引入当前片段的样式(scss、css)文件时,务必保证namespace 上的相对唯一性,避免产生对其它片段的干扰。
附件 Demo
Smart Page,或者说 humech,看起来比较复杂,也需要一点时间理解它的运作机制。但实际上的一个模板代码量一般都比较小……
点击下载附件smartpage.zip,可以下载得到系统内置的几个 Smart Page 模板 (样式文件是特别分离的),再放到自己的 template 内再尝试,或许就更容易理解了。