HTML Rendering

Two classes turn a Viper document into HTML. DocumentNode walks a document as a typed tree, carrying the metadata a renderer needs — component name, value, editability, and the concrete type behind each leaf. Html renders, either the whole tree in one call or one piece at a time.

When to use: reach for Html when the default rendering will do, and for DocumentNode directly when the markup is yours — a form, a custom layout, a template engine’s data. Nothing here is browser-specific: the same tree feeds a server-rendered page, and the Qt widgets do the same thing with it.

Quick Start

An Express route rendering one document as a collapsible tree:

const express = require('express');
const { CommitDatabase, CommitStateBuilder, DocumentNode, Html, ValueKey } =
    require('@digitalsubstrate/dsviper');

const app = express();

app.get('/document/:instanceId', (req, res) => {
    const db = CommitDatabase.open('model.cdb');
    try {
        const key = ValueKey.create(concept, ValueUUId.create(req.params.instanceId));
        const getting = CommitStateBuilder.state(db, db.lastCommitId()).attachmentGetting();

        // Build the document tree for every attachment on that key.
        const nodes = DocumentNode.createDocuments(key, getting);

        res.send(Html.document('Document', Html.style(),
                               Html.body(Html.documentsDetails(nodes, true))));
    } finally { db.close(); }
});

Html.style() returns the stylesheet the other helpers assume, Html.body() wraps content, and Html.document() assembles a standalone page — so a working page needs no CSS of its own.

Walking the tree yourself

DocumentNode answers what a renderer needs to decide, so a custom renderer is a recursion over predicates:

function renderNode(node, level = 0) {
    if (node.isExpandable()) {
        const children = node.children().map((c) => renderNode(c, level + 1)).join('');
        return `<details open><summary>${node.stringComponent()}</summary>${children}</details>`;
    }
    if (node.isEditable()) {
        if (node.isBoolean()) return checkbox(node);
        if (node.isEnumeration()) return select(node);
        if (node.isString()) return textInput(node);
    }
    return `<div>${node.stringComponent()} = ${node.stringValue()}</div>`;
}

The predicate family is wide — isPrimitive, isCollection, isKey, isNumeric and the exact-width isInt32 / isUint64 / isFloat … — so a renderer can be as coarse or as precise as it needs. Html.type(node.value().type()) renders the type itself when a column should show it.

See also

dsviper-node-web-cdbe is a complete worked example: an Express Commit Database Editor, pure HTML5 with no client JavaScript, built on exactly these two classes. Its Python twin dsviper-web-cdbe renders the same tree through Flask.

Key classes

Class

Purpose

Example

DocumentNode

One node of a document seen as a tree

Html

Renders Viper data as HTML

The mirror of this page for the Python binding is HTML Rendering.

Classes

Class

Description

DocumentNode

One node of a document seen as a tree

Html

Renders Viper data as HTML

Reference

class DocumentNode()

One node of a document seen as a tree.

Carries its component name, its value, its type, and what a renderer needs to decide: editable, expandable, and which concrete type it holds.

Note: Not directly instantiable.

exported from index.d

DocumentNode.attachment()

Return the attachment the document belongs to.

Returns:

Attachment

DocumentNode.children()

Return the nodes one level below this one.

Returns:

DocumentNode[]

DocumentNode.document()

Return the whole document this node is part of.

Returns:

Value

DocumentNode.isBlobId()

Return true if the node holds a blobId.

Returns:

boolean

DocumentNode.isBoolean()

Return true if the node holds a boolean.

Returns:

boolean

DocumentNode.isCollection()

Return true if the node holds a collection.

Returns:

boolean

DocumentNode.isContainer()

Return true if the node holds other nodes rather than a value.

Returns:

boolean

DocumentNode.isDouble()

Return true if the node holds a double.

Returns:

boolean

DocumentNode.isEditable()
Return true if the node carries a value a UI may write — not a container, and not

read-only.

Returns:

boolean

DocumentNode.isEnumeration()

Return true if the node holds an enumeration.

Returns:

boolean

DocumentNode.isExpandable()

Return true if the node has children to unfold.

Returns:

boolean

DocumentNode.isFloat()

Return true if the node holds a float.

Returns:

boolean

DocumentNode.isInt16()

Return true if the node holds an int16.

Returns:

boolean

DocumentNode.isInt32()

Return true if the node holds an int32.

Returns:

boolean

DocumentNode.isInt64()

Return true if the node holds an int64.

Returns:

boolean

DocumentNode.isInt8()

Return true if the node holds an int8.

Returns:

boolean

DocumentNode.isInteger()

Return true if the node holds an integer.

Returns:

boolean

DocumentNode.isKey()

Return true if the node holds a key.

Returns:

boolean

DocumentNode.isNumeric()

Return true if the node holds a number.

Returns:

boolean

DocumentNode.isPrimitive()

Return true if the node holds a primitive.

Returns:

boolean

DocumentNode.isReadonly()

Return true if the node was marked as not writable.

Returns:

boolean

DocumentNode.isReal()

Return true if the node holds a real.

Returns:

boolean

DocumentNode.isString()

Return true if the node holds a string.

Returns:

boolean

DocumentNode.isUint16()

Return true if the node holds a uint16.

Returns:

boolean

DocumentNode.isUint32()

Return true if the node holds a uint32.

Returns:

boolean

DocumentNode.isUint64()

Return true if the node holds a uint64.

Returns:

boolean

DocumentNode.isUint8()

Return true if the node holds a uint8.

Returns:

boolean

DocumentNode.isUuid()

Return true if the node holds an uuid.

Returns:

boolean

DocumentNode.key()

Return the key of the document this node is part of.

Returns:

ValueKey

DocumentNode.parent()

Return the parent or undefined.

Returns:

DocumentNode | undefined

DocumentNode.path()

Return the Path from the document root down to this node.

Returns:

PathConst

DocumentNode.stringComponent()
Return the label for the node itself — a field name, an index, a key — or ‘-’ at the

root.

Returns:

string

DocumentNode.stringComponentTooltip()

Return the tooltip for the component label: the type representation.

Returns:

string

DocumentNode.stringPath()

Return the path, rendered for display.

Returns:

string

DocumentNode.stringType()

Return the type of the value, rendered for display.

Returns:

string

DocumentNode.stringValue()

Return the value rendered for display, or ‘-’ for a container.

Returns:

string

DocumentNode.stringValueTooltip()

Return the tooltip for the value label: the rendered path.

Returns:

string

DocumentNode.type()

Return the type of node.

Returns:

string

DocumentNode.uuid()

Return the uuid identifying this node in the tree.

Returns:

ValueUUId

DocumentNode.value()

Return the Value this node stands for.

Returns:

Value

static DocumentNode.createDocuments(key, attachmentGetting)

Return a list of documents as a hierarchy of DocumentNode.

Arguments:
  • key (ValueKey)

  • attachmentGetting (AttachmentGetting)

Returns:

DocumentNode[]

class Html()

Renders Viper data as HTML.

A value, a type, a document tree, or a whole styled page. Every method is static.

Note: Not directly instantiable.

exported from index.d

static Html.body(content)

Embed the content in a body.

Arguments:
  • content (string)

Returns:

string

static Html.document(title, style, body)

Return an HTML document.

Arguments:
  • title (string)

  • style (string)

  • body (string)

Returns:

string

static Html.documentsDetails(documents, showType)
Return the HTML representation of the documents as a hierarchy of

details.

Arguments:
  • documents (DocumentNode[])

  • showType (boolean)

Returns:

string

static Html.dsmDefinitions(definitions, showDocumentation, showRuntimeId)

Return the HTML representation of the DSM Definitions.

Arguments:
  • definitions (DSMDefinitions)

  • showDocumentation (boolean)

  • showRuntimeId (boolean)

Returns:

string

static Html.style()

Return the default style.

Returns:

string

static Html.type(type)

Return the representation of the type in HTML.

Arguments:
  • type (Type)

Returns:

string

static Html.value(value, useDescription)

Return the representation of the value in HTML.

Arguments:
  • value (Value)

  • useDescription (boolean)

Returns:

string

static Html.valuePretty(value, showType)

Return the representation of the value like the HTML pretty printer.

Arguments:
  • value (Value)

  • showType (boolean)

Returns:

string