@128technology/ply 中文文档教程
PLY
PLY(Presentation Language for Yinz)是一个用于管理 JSON 文件的库,该文件模拟用于配置 YANG 的 GUI(RFC 6020)数据存储。 它直接与 Yinz 库集成,该库管理数据模型和与该数据模型关联的实例数据。
PLY 打算提供以下功能:
- Ingest a presentation model described by one or more JSON files.
- Ingest a datamodel and associate it with the presentation model. The datamodel will be used to look up information from fields.
- Injest an instance of the model and associate the values from the instance with presentation fields.
- Serialize this presentation instance to JSON that can be sent to a client to draw a GUI.
- Validate that a presentation model is both syntactically and semantically valid.
- Given a datamodel, ensure that all aspects of the datamodel have a corresponding entry in the presentation model.
Model Format
Pages
一个页面通常被分解成它自己的 JSON 文件。 页面通常表示列表项的容器和实例。 例如,如果模型有一个路由器列表,可能会有一个名为 router.json
的页面,它描述了路由器实例的外观。 页面的架构非常简单,它包含一个 title
、一个 id
和一个 sections
数组。 最基本的页面如下所示:
{
"id": "my-new-page",
"title": "My New Page",
"sections": []
}
通常,页面 id
与文件名相匹配是个好主意。 例如,router.json
将具有 router
的 id
。
Sections
leaf-section
如果您有一个基本字段部分(例如,没有容器、列表或叶列表),那么这就是您要使用的部分类型。 此部分类型有一个 id
、一个 title
和一个 fields
数组。 通常,该部分的 id
格式为 page-id.section-id
,所以如果它在 router
页面上,它可能看起来像像 router.settings
。 如果你没有为一个部分指定类型,它将默认为此类型。一个基本的 leaf-section
如下所示:
{
"id": "my-new-page.my-new-section",
"title": "My New Section",
"fields": []
}
如果你选择明确指定类型,它看起来像:
{
"id": "my-new-page.my-leaf-section",
"title": "My Leaf Section",
"type": "leaf-section",
"fields": []
}
list-section
所有列表都需要包含在它们自己的 list-section
中。 list-section
将只有一个引用列表本身的字段。 list-section
的 title
字段被显式设置为 null
并且列表字段的 label
位于部分被使用。 字段部分概述了单个列表字段的细节,包括 link
和 columns
属性的描述。 基本的 list-section
如下所示:
{
"id": "my-new-page.my-list-section",
"title": null,
"type": "list-section",
"fields": [{
"link": "dog",
"id": "id.to.a.list",
"label": "Dogs"
}]
}
list-table
所有叶列表都需要包含在它们自己的 list-table
部分中。 与 list-section
类似,list-table
部分只有一个字段描述叶列表。 它还有一个 title
明确设置为 null
。 list-table
部分的示例如下所示:
{
"id": "my-new-page.my-list-table-section",
"title": null,
"type": "list-table",
"fields": [{
"id": "id.to.a.leaf-list",
"label": "Cats",
"columnLabels": [{
"id": "name",
"label": "Cat"
}]
}]
}
container-list-section
如果您希望链接深入到一个部分中的一个或多个容器/页面,您将需要使用 container-list-section< /代码>。 示例如下所示:
{
"id": "my-new-page.my-link-section",
"title": "Example Container Links",
"type": "container-list-section",
"fields": [{
"id": "id.to.a.container",
"link": "container-1",
"label": "Container 1"
}]
}
Fields
leaf
{
"id": "id.to.a.leaf",
"label": "My Leaf Field"
}
choice
虽然从技术上讲,选择字段在 running
配置中没有值,但它将填充模型中的案例,并在运行时推断出所选案例。
{
"id": "id.to.a.choice",
"label": "My Choice Field"
}
container
容器不必在表示模型中表示。 在需要指向代表容器的页面的链接的情况下,应该使用它们。 链接
必须对应于另一个页面的id
。
{
"id": "id.to.a.container",
"label": "My Container Field",
"link": "page-for-container"
}
leaf-list
columnLabels
属性用于描述显示 leaf-list
的表的列的标签。 在这种情况下,因为 leaf-list
只有一列,所以这个数组应该只包含一个项目。 leaf-list
字段只能包含在 list-table
部分中。 列表
{
"id": "id.to.a.leaf-list",
"label": "My Leaf List Field",
"columnLabels": [{
"id": "thing",
"label": "thing"
}]
}
list
的 columns
属性字段是可选的。 它旨在表示如果列表显示在表格中,应显示哪些列(叶)。 否则通常只有关键字段会出现在表格中。 链接
必须对应于列表实例页面的id
。 例如,如果列表字段描述了所有路由器的列表,那么链接必须对应于描述单个路由器的 router
页面。 list
字段只能包含在 list-section
中。
{
"id": "id.to.a.leaf-list",
"label": "My List Field",
"link": "my-list-instance",
"columns": ["name", "description"]
}
PLY
PLY (Presentation Language for Yinz) is a library to manage JSON files that model a GUI for configuring a YANG (RFC 6020) datastore. It directly integrates with the Yinz library which manages both the datamodel and instance data associated with that datamodel.
PLY intends to provide the following functionality:
- Ingest a presentation model described by one or more JSON files.
- Ingest a datamodel and associate it with the presentation model. The datamodel will be used to look up information from fields.
- Injest an instance of the model and associate the values from the instance with presentation fields.
- Serialize this presentation instance to JSON that can be sent to a client to draw a GUI.
- Validate that a presentation model is both syntactically and semantically valid.
- Given a datamodel, ensure that all aspects of the datamodel have a corresponding entry in the presentation model.
Model Format
Pages
A page is typically broken out into it's own JSON file. Pages generally represent containers and instances of list items. For example, if the model has a list of routers, there would probably be a page named router.json
which describes what an instance of a router would look like. The schema of a page is pretty simple, it contains a title
, an id
, and an array of sections
. The most basic page would like like the following:
{
"id": "my-new-page",
"title": "My New Page",
"sections": []
}
Generally it is a good idea for the page id
to match the name of the file. For example, router.json
would have an id
of router
.
Sections
leaf-section
If you have a section of basic fields (e.g. no containers, lists, or leaf-lists), then this is the section type you would want to use. This section type has an id
, a title
, and an array of fields
. Generally the id
for the section has the format page-id.section-id
, so if it was on the router
page it might look something like router.settings
. If you do not specify a type for a section it will default to this type. A basic leaf-section
looks like the following:
{
"id": "my-new-page.my-new-section",
"title": "My New Section",
"fields": []
}
If you chose to specify the type explicitly it would look like:
{
"id": "my-new-page.my-leaf-section",
"title": "My Leaf Section",
"type": "leaf-section",
"fields": []
}
list-section
All lists need to be contained in their own list-section
. A list-section
will have exactly one field which references the list itself. A list-section
's title
field is explicitly set to null
and the label
of the list field inside the section is used instead. The specifics of the single list field are outlined in the Fields section, including descriptions of the link
and columns
properties. A basic list-section
looks like the following:
{
"id": "my-new-page.my-list-section",
"title": null,
"type": "list-section",
"fields": [{
"link": "dog",
"id": "id.to.a.list",
"label": "Dogs"
}]
}
list-table
All leaf-lists need to be contained in their own list-table
section. Similarly to the list-section
a list-table
section has exactly one field describing the leaf-list. It also has a title
explicitly set to null
. An example list-table
section looks like the following:
{
"id": "my-new-page.my-list-table-section",
"title": null,
"type": "list-table",
"fields": [{
"id": "id.to.a.leaf-list",
"label": "Cats",
"columnLabels": [{
"id": "name",
"label": "Cat"
}]
}]
}
container-list-section
If you want links that dive into one or more containers/pages in a section, you will want to use the container-list-section
. An example looks like the following:
{
"id": "my-new-page.my-link-section",
"title": "Example Container Links",
"type": "container-list-section",
"fields": [{
"id": "id.to.a.container",
"link": "container-1",
"label": "Container 1"
}]
}
Fields
leaf
{
"id": "id.to.a.leaf",
"label": "My Leaf Field"
}
choice
While a choice field technically has no value in the running
config, it will be populated with the cases in the model and the selected case is inferred at runtime.
{
"id": "id.to.a.choice",
"label": "My Choice Field"
}
container
Containers do not have to be represented in the presentation model. They should be used in cases where a link to a page representing the container is desired. The link
MUST correspond to an id
of another page.
{
"id": "id.to.a.container",
"label": "My Container Field",
"link": "page-for-container"
}
leaf-list
The columnLabels
property is used to describe a label for the columns of a table displaying the leaf-list
. In this case since a leaf-list
only has one column, this array should only contain one item. A leaf-list
field can only by contained in a list-table
section.
{
"id": "id.to.a.leaf-list",
"label": "My Leaf List Field",
"columnLabels": [{
"id": "thing",
"label": "thing"
}]
}
list
The columns
property of a list field is optional. It is intended to denote which columns (leafs) should be displayed if the list if presented in a table. Otherwise typically only the key fields would be presented in a table. The link
MUST correspond to an id
of the page for the list instance. For example if the list field describes the list of all routers, then the link must correspond to the router
page describing an individual router. A list
field can only by contained in a list-section
.
{
"id": "id.to.a.leaf-list",
"label": "My List Field",
"link": "my-list-instance",
"columns": ["name", "description"]
}