UI data binding is a recognised software design pattern for GUI development. This specification defines high level processing and rendering rules to bind an RDF graph to HTML elements. The UI data binding is specified using HTML attributes, which when hydrated provides valid RDFa. This process synthesises pages of data into a new document with content that can be read and edited by both humans and machines.

Introduction

RDF provides a framework for representing information in the Web, and RDFa specifications provide a means to add structured data to HTML pages directly. This specification tackles the use case of binding an external RDF data source within a HTML page - bringing pages of data together within a single document. It is inspired by mavo.io, which allows creating complex, reactive, persistent web applications by just writing HTML & CSS, without a single line of JavaScript and no server backend. With this type of application in mind, this specification aims to define the high level processing and rendering rules for HTML attributes.

The UI data binding behaviour of HTML attributes is specified in a way that is independent of the name of the elements on which they are used. It is intended that the specification could be implemented with web components, through JavaScript processing on client or server side, or native browser support.

The specification is intended to align with an implementation of this specification by PodOS. Within PodOS, components implementing this specification provide a low level, HTML-only interface for dashboards and composable panes. This low level interface is complemented by higher level modules that abstract out the specific terms used for any particular domain .

Processing model

A renderer processes instructions in HTML attributes using a `source graph` to produce a hydrated DOM. Rendering follows an evaluation context, with a shifting `current subject` similar to the RDFa processing model.

Before hydration, attributes commonly implicitly define missing variables that will be queried from the `source graph` and hydrated. These variables can be named using the attributes bind-subject and bind-object. If present, implementations MAY use these binding names as part of their processing.

A source graph is used to hydrate the DOM. The source graph MUST use a quad model, i.e. distinguishing between "documents" in which triples are defined. Architecturally, the source graph is generally a global store, accessed by all components. The store SHOULD provide reactive rendering of UI components when data changes. The store SHOULD define getters and mutations to manage changes to state. The store MAY provide compatibility with the RDF/JS data model and dataset specification. A store SHOULD define accessors to atomically `set` or `select` the values of a predicate.

The store MAY provide features for synchronisation of data with a server. Authentication and authorization are out of scope of this specification, but implementations are encouraged to consider compatibility with Solid and Linked Web Storage Working Group specifications.

Attributes

The specification reuses a set of common HTML attributes across use cases. Their basic meaning is introduced here.

RDFa attributes

Before hydration, the meaning of attributes depends on the type of component.

When hydrated, the DOM should be valid RDFa: `property, rev, rel, about, typeof`

Document each attribute with reference to their RDFa definition

Query attributes

This specification defines a set of HTML-attributes that provide a query interface for listing matching resources. Their basic meaning is to test the existence or value of a specific graph link.

if-property
Tests if a forward link exists with the given predicate. May be modified by other attributes.
if-rev
Tests if a backward link exists with the given predicate. May be modified by other attributes.
eq-value
Extends other conditions by requiring that not only does a link exist, but there is also match for the specified object
if-typeof
By analogy to `typeof`, tests if the subject inherits the given type. May be modified by other attributes. Shorthand for `<if-property="rdf:type" eq-value="http://uri/of/class">`
not
Provides scoped negation as failure - matches if the other provided attributes do not have a match based on the `source graph`

It seems likely that attributes other than `eq-value` will eventually be needed.

Prefixes and CURIEs

Implementations MUST support URIs and SHOULD support CURIEs where RDFa allows it.

Documentation to conform with RDFa

Document additional default prefixes, beyond those provided by RDFa, for Solid support.

Implementations MAY support the `vocab` attribute, notably to allow the use of terms without prefixes.

Single element UI data binding

The basic use case binds one or more values to a single HTML element.

Single subject, single value binding

A single subject, single value binding uses the attributes `property`, `rel` or `rev`.

Processing involves following from the current subject to either the subject or object. The attributes `property` and `rel` are treated as synonyms. If the attribute `rev` is used, the value MUST be a URI, not a literal.

Before hydration, the component defines an incomplete triple with a missing term, which is treated as a variable and its value is looked up. The value MUST be rendered in such a way that the hydrated element provides a valid RDFa version of the source triple.

For editable components, the value can be modified using a set operation, removing the existing triple and adding a new one. If there is no value, the component can offer to set it. If multiple values are found, an error MUST be thrown.

Single subject, multiple value binding

A single subject, multiple value binding uses the attributes `property`, `rel` or `rev`. It binds multiple values to a single HTML element, in contrast to binding a single value to an element, or multiple values to a list. Prototypical examples include tag inputs and select element allowing multiple values.

Before hydration, the component defines an incomplete triple with a missing term, which is treated as a variable which will have either multiple matches or be an RDF collection. The value MUST be rendered in such a way that the hydrated element provides a valid RDFa version of the source triples. A multiple value binding usually also uses further information about each matched item, as well as other available selections. The renderer MAY display the bound data as RDFa. If it does not, then the machine representation diverges from the data displayed to the user.

The data may include unexpected values, e.g. that are not defined in a select element. The renderer SHOULD provide an indication to the user that the data is not supported.

When editing, the renderer MUST replace the entire set of values to maintain consistency of the data. If the existing data includes values not available in the UI, the renderer MUST throw an error noting the incompatibility.

Add example

List

List components can start from a subject or enumerate a store or document. Generally both functionalities would be provided by the same HTML element.

Subject-connected list

A Subject-connected list uses the RDFa attributes rel and/or rev. A list with a single item allows for changing the current subject by following a predicate.

Processing begins from the current subject. A list of items is constructed by following predicates either forward or backward for rel or rev respectively. If both are specified, the items are concatenated. No default order is specified.

Before hydration, a subject-oriented list yields an incomplete triple. The missing term is considered a variable that is looked up and hydrated.

The rel and rev attributes induce chaining, i.e. they change the current subject. For each item, the renderer MUST create a new descendant element with the attribute about referring to that item. The renderer MUST set the item as the new current subject.

Enumerating list

An enumerating list uses the query attributes defined above, notably if-property, if-rev, if-typeof and possible modifiers.

A list of items is constructed that matches the query. By default, the query is scoped to the entire graph. The graph can be restricted using the attribute doc. If doc is provided with no query parameter, then all subjects in the graph are used.

Before hydration, the attributes of an enumerating list are considered to define variables for the subject.

Processing ignores any current subject. For each item matching the query, the renderer MUST create a new descendant element with the attribute about matching the item. The renderer MUST set the current subject to the item and rendering continues.

Lists of literals

Sorting

sort, sort-order, sort-n3path

List mutations

adding items

Conditional rendering

- Ask component, e.g. for conditional rendering evaluates whether triples with the variable exist

Forms

Creator component, e.g. forms: missing variables will be created. After hydration and before execution, they are implied blank nodes used in additional triples that will be created.

Source control

- Hydrated RDF comes from different documents but possibly also different websites. The source graph keeps track of the graph of each triple (it stores quads)

By default, read-only components draw on any loaded triples

The `doc` attribute is used to limit results to a particular document/graph

Editing existing statements can modify existing documents

To help follow your nose, statements about a resource are commonly stored with it

An annotation store can be explicitly defined in data

Template paths can provide control, particularly with user created UIs.

N3 resource paths

The source graph can be traversed by nesting multiple subject-connected lists/predicate following components. N3 resource paths can provide a shortcut

N3 resource paths can use built-in functions.

Implementation profile: PodOS-compatible web components

Access to current subject

To receive a reference to the current subject, a pod-os:resource event is emitted by a HTML element. The element that defines the current subject acts as a resource provider. The resource provider MUST listen for the event and respond by calling the callback function provided in event.detail, passing the current subject through a callback, in the form of a resource object. The resource provider MAY render the URI of the current subject using the `about` attribute in the process of providing valid RDFa.

Reactive rendering

Security

Authenticated access to resources.

Triple injection

Data exfiltration