This document introduces how SHACL shape definitions can be used to drive user interfaces, esp display and edit forms. The document shows examples of recommended form layouts that mirror the definitions of properties in data shapes, and introduces extensions to the SHACL vocabulary from the DASH namespace that further assist in such form definitions.

This document uses the prefix dash which represents the DASH Data Shapes namespace http://datashapes.org/dash# which is accessible via its URL http://datashapes.org/dash.

Overview

The Shapes Constraint Language [[shacl]] includes well-defined constraint properties such as sh:datatype and sh:maxCount that have been originally designed for data validation yet are also instrumental in building user input forms that reflect a certain viewpoint of an RDF-based data model. Furthermore, in addition to being a constraint definition language, SHACL includes vocabulary terms such as sh:order and sh:group that can aid in the construction of form layouts, for example to state that a street address field should be showing up in an Address section and above the city and postal code, while contact phone numbers should show up in a different section.

Shape definitions are represented and shared in RDF. The flexible RDF data model makes it possible for other namespaces to contribute further vocabulary terms. Tools that agree on the semantics of these terms can establish best practices on how RDF data should be presented and edited by users. Data entry forms invariably must support data validation. This makes SHACL a natural choice for providing both, the UI presentation instructions as well as data validity constraints. RDF supports extensibility and SHACL includes a standard extension mechanism for extensions.

The DASH namespace introduces a number of properties, classes and instances that are particularly useful for form building, yet potentially also for other use cases such as data validation. Among others, we introduce dash:defaultViewForRole, dash:editor, dash:viewer and dash:singleLine. The DASH namespace also defines several generally useful constraint components. Description of these components is outside of the scope of this document.

This document provides an introduction on the use of SHACL and some DASH extensions, with recommendations on how user interfaces should interpret them. These recommendations are based on several years of experience with implementations in the TopBraid platform.

The DASH Property Roles vocabulary provides complementary capabilities for user interface building.

Example: Postal Addresses

Getting started, we will introduce typical design patterns of SHACL to define the layout of an input form for postal addresses stored using classes and properties from the schema.org namespace. Our starting point is an instance such as the following:

aussies:HolgersAddress
	a schema:PostalAddress ;
	schema:streetAddress "3 Teewah Close" ;
	schema:addressLocality "Kewarra Beach" ;
	schema:addressRegion "QLD" ;
	schema:postalCode "4879" ;
	schema:email "holger@knublauch.com" ;
	schema:email "holger@topquadrant.com" ;
	rdfs:label "Holger's Address" .

Let's say that the context of our data is an application that only needs to store addresses in Australia. While schema.org can represent world-wide addresses, we want to localize the presentation of the data for users down under. Shapes are well suited for defining such data profiles, essentially dialects of namespaces in the context of specific application areas.

In our application, Australian addresses shall be presented to the user as shown below. The screenshot and all other screenshots in this document show user interfaces generated by TopBraid EDG.

We have made some adjustments over how schema.org data would be rendered by default. The form shall display the term "postal code" instead of "zip code", and "state" instead of "address region". Furthermore, the choice of states shall be limited to the abbreviations of the 8 states and territories of Australia (e.g. "QLD" is Queensland). Note that the street address may consist of multiple rows, and is therefore edited in a text area. The form layout arranges the properties in two so-called property groups (Address and Contact), and within each group the properties are enumerated in a certain order, typically expected by Australian users.

The following SHACL shape definitions (in Turtle notation) demonstrate how such form layouts can be defined.

Node Shape

The node shape aushapes:AustralianAddressShape serves as the container of the various property definitions.

aushapes:AustralianAddressShape
	a sh:NodeShape ;
	rdfs:label "Australian address shape" ;
	rdfs:comment "Defines the structure of addresses in Australia, stored using schema.org." ;
	sh:targetClass schema:PostalAddress ;
	dash:defaultViewForRole dash:all ;
	sh:property aushapes:AustralianAddressShape-streetAddress ;
	sh:property aushapes:AustralianAddressShape-addressLocality ;
	sh:property aushapes:AustralianAddressShape-addressRegion ;
	sh:property aushapes:AustralianAddressShape-postalCode ;
	sh:property aushapes:AustralianAddressShape-email ;
	sh:property aushapes:AustralianAddressShape-telephone .

The sh:targetClass statement tells a system that this shape applies to all instances of the target class schema:PostalAddress that are managed by this data graph and application. This means that all instances of that class (and its subclasses) must fulfill the constraints defined for the shape. Applications can use this information to present different views to different users. Sometimes it also makes sense to offer users alternative views to select from. For example, aushapes:AustralianAddressShape can be selected by a user as one of the possible view points (or forms) on a given PostalAddress instance. In the upper right corner of the screenshot above, the user has a drop down list letting them switch between such views. The property dash:defaultViewForRole can be used to state which view shape should be used for which type of users. In TopBraid EDG, the values of this property can be governance roles enabling people with different background and technical depth to see different subsets of available information. In this case, we use dash:all to indicate that this view shape shall be used to render all addresses for all users.

The values of sh:property in this case are URIs and we are following a naming convention so that the URIs of the property shapes are the node shape (or class) followed by a dash and then the local name of the property (sh:path). Alternatively, some people prefer using blank nodes for property shapes. Blank nodes are sometimes more compact but make it harder for other shape definitions to reference the property declarations, for example to add more statements to them, e.g. sh:deactivated. If you want to prevent exactly that and stay in relative control over how your shape is used, use blank nodes.

Property Shapes

Let's look at the property definitions. The street address is showing on the top of the form, within the property group called "Address".

aushapes:AustralianAddressShape-streetAddress
	a sh:PropertyShape ;
	sh:path schema:streetAddress ;
	dash:editor dash:TextAreaEditor ;
	dash:singleLine false ;
	sh:datatype xsd:string ;
	sh:group aushapes:AddressPropertyGroup ;
	sh:maxCount 1 ;
	sh:name "street address" ;
	sh:order "0"^^xsd:decimal .

The sh:datatype constraint states that the values of this property must be literals with datatype xsd:string. All of our example fields are strings, yet typical other choices are xsd:boolean, xsd:integer, xsd:decimal (for floating point values), rdf:langString for language-tagged strings and rdf:HTML for rich text fields. Or use sh:class or sh:node to state that values can be resources with certain types and structures.

In order to state that street addresses can cover multiple rows, we use two properties from the DASH namespace. dash:editor links a property shape with an instance of dash:Editor such as dash:TextAreaEditor. A list of possible editors can be found in a section below. dash:editor is basically an annotation that can be interpreted by form builders that support this property, but may simply be ignored by other applications and all constraint validators. (Note that current TopBraid versions also support an alternative property tosh:editWidget that plays a similar role but will be phased out over time).

An alternative to dash:editor in this case is to declare a constraint dash:singleLine false. Although it's not part of the SHACL Core standard, dash:singleLine is a SHACL constraint component that is backed by SPARQL and JavaScript validators and can therefore be understood automatically by all SHACL engines that implement the SHACL-SPARQL or SHACL-JS standards. A constraint violation would be reported if a property is marked dash:singleLine true yet has line breaks. In the case of false, a form builder can infer that the values are explicitly allowed to have multiple rows, and therefore a text area should be preferred over a text field.

In general, form builders can learn a lot about the display of data by looking at the constraint definitions. An obvious example is sh:maxCount 1 which states that only one value is permitted, and therefore the UI should not offer a button to add more rows to a property.

The next property is the address locality, and shall appear right under the street address, as indicated by the sh:order value of 1. sh:order is interpreted such that properties and groups with lower values show up on top of those with higher values. Properties that have no sh:order should be placed at the bottom, and then sorted alphabetically for consistency. Note that sh:order values are xsd:decimal literals, and fraction digits can be used to squeeze entries in between existing properties. This makes it possible for other shape graphs to insert additional fields into a shape definition.

aushapes:AustralianAddressShape-addressLocality
	a sh:PropertyShape ;
	sh:path schema:addressLocality ;
	sh:datatype xsd:string ;
	sh:group aushapes:AddressPropertyGroup ;
	sh:maxCount 1 ;
	sh:name "suburb" ;
	sh:order "1"^^xsd:decimal .

The next property is the state, stored using schema:addressRegion. Here we use sh:in to enumerate all permitted values. The presence of sh:in can be used by a form builder to display a selection box with exactly those options.

aushapes:AustralianAddressShape-addressRegion
	a sh:PropertyShape ;
	sh:path schema:addressRegion ;
	sh:datatype xsd:string ;
	sh:description "The abbreviation of the state or territory." ;
	sh:group aushapes:AddressPropertyGroup ;
	sh:in ( "ACT" "NSW" "NT" "QLD" "SA" "TAS" "VIC" "WA" ) ;
	sh:minCount 1 ;
	sh:maxCount 1 ;
	sh:name "state" ;
	sh:order "2"^^xsd:decimal .

The sh:description field can be used to display instructions to users, as shown in the following screenshot (which happens to displays the address instance in view mode, not edit mode).

The last property in the Address group is the postal code.

aushapes:AustralianAddressShape-postalCode
	a sh:PropertyShape ;
	sh:path schema:postalCode ;
	sh:datatype xsd:string ;
	sh:description "An Australian postal code, between 0000 and 9999." ;
	sh:group aushapes:AddressPropertyGroup ;
	sh:minCount 1 ;
	sh:maxCount 1 ;
	sh:minLength 4 ;
	sh:maxLength 4 ;
	sh:name "postal code" ;
	sh:order "3"^^xsd:decimal ;
	sh:pattern "[0-9][0-9][0-9][0-9]" .

This defines various semantic constraints including a regular expression (sh:pattern), sh:minLength and sh:maxLength. Such constraints could be used to limit what the user can enter. In this case the UI displays a constraint violation if the user goes beyond the maximum character length, including suggestions on how to fix it, using the DASH Suggestions Vocabulary.

The remaining fields for emails and phone numbers appear in the Contact property group and take string values. Note that these fields do no include a sh:maxCount constraint and users therefore have a button to add more rows.

aushapes:AustralianAddressShape-email
	a sh:PropertyShape ;
	sh:path schema:email ;
	sh:datatype xsd:string ;
	sh:group aushapes:ContactPropertyGroup ;
	sh:name "email" ;
	sh:nodeKind sh:Literal ;
	sh:order "1"^^xsd:decimal .
aushapes:AustralianAddressShape-telephone
	a sh:PropertyShape ;
	sh:path schema:telephone ;
	sh:datatype xsd:string ;
	sh:group aushapes:ContactPropertyGroup ;
	sh:name "phone number" ;
	sh:order "2"^^xsd:decimal .

Property Groups

Finally, here are the definitions of the property groups themselves. Property groups are simple stand-alone objects that primarily define display label and possibly a description (rdfs:comment) helping users what needs to be entered in the contained properties. The sh:order field is used to determine the relative order of property groups.

			
aushapes:AddressPropertyGroup
	a sh:PropertyGroup ;
	rdfs:label "Address" ;
	sh:order "0"^^xsd:decimal .

aushapes:ContactPropertyGroup
	a sh:PropertyGroup ;
	rdfs:label "Contact" ;
	sh:order "1"^^xsd:decimal .

Advanced Topics

Multiple Datatypes or Classes

It sometimes make sense to have properties that may take literals of different datatypes, or instances of different classes, as their values. In SHACL, if a property carries multiple sh:datatype or sh:class constraints, then these are interpreted as intersection ("and"). Thus, as no RDF literal can have multiple datatypes, it never makes sense to have multiple sh:datatype statements in the same property shape. Instead, use the following syntax:

skos:Concept-prefLabel
	a sh:PropertyShape ;
	sh:path skos:prefLabel ;
	sh:or (
		[
			sh:datatype xsd:string ;
		]
		[
			sh:datatype rdf:langString ;
		]
	) ;
	sh:uniqueLang true .

The values of sh:or are lists of shape definitions. The DASH namespace defines some reusable lists for frequently needed combinations:

Using these constants, the property definition from above can be shortened to:

skos:Concept-prefLabel
	a sh:PropertyShape ;
	sh:path skos:prefLabel ;
	sh:or dash:StringOrLangString ;
	sh:uniqueLang true .

User interfaces such as TopBraid should allow users to switch between suitable input widgets for properties that allow multiple types.

Nested Forms

Sometimes data that shall be displayed for a resource is not stored in direct property values of that resource, but one or more "hops" away. Consider the following example, where the person's address record is stored in a separate object from the person itself:

aussies:HolgerKnublauch
	a schema:Person ;
	rdfs:label "Holger Knublauch" ;
	schema:givenName "Holger" ;
	schema:familyName "Knublauch" ;
	schema:gender "male" ;
	schema:address aussies:HolgersAddress .

aussies:HolgersAddress
	a schema:PostalAddress ;
	schema:addressLocality "Kewarra Beach" ;
	schema:addressRegion "QLD" ;
	schema:email "holger@knublauch.com" ;
	schema:email "holger@topquadrant.com" ;
	schema:postalCode "4879" ;
	schema:streetAddress "3 Teewah Close" ;
	rdfs:label "Holger's Address" .

In order to display all details of this person, a "nested" display such as the following may be suitable:

The above can be achieved using dash:viewer and sh:node:

aushapes:PersonViewShape-address
	a sh:PropertyShape ;
	sh:path schema:address ;
	sh:name "address" ;
	dash:viewer dash:DetailsViewer ;
	sh:node aushapes:AustralianAddressShape ;
	sh:class schema:PostalAddress ;
	sh:group aushapes:AddressPropertyGroup ;
	sh:maxCount 1 ;
	sh:nodeKind sh:IRI .

Using dash:DetailsViewer as the dash:viewer (or dash:DetailsEditor as the dash:editor - not yet supported by TopBraid) instructs a form engine to recursively "walk" into the linked resource and show its values as a sub-form of the surrounding form. The value of sh:node tells the form engine which selection of properties to display, and in which order. (In the case above, no property groups are shown for nested forms, to reduce the complexity to users).

Path Expressions

SHACL property shapes are not limited to simple direct property values, but may also use complex path expressions. This is an extremely powerful capability of SHACL distinguishing it from similar modeling languages.

Inverse Properties

A common use of path expressions is to walk a property in the inverse direction. Consider the schema:address property, which is modeled to point from a person (as subject) to an address (as object). There might be multiple persons with the same address, and in some use cases such incoming references should be rendered as follows:

To achieve this, a property shape using an sh:inversePath expression can be used:

aushapes:AustralianAddressShape-address-inverse
	a sh:PropertyShape ;
	sh:path [
		sh:inversePath schema:address ;
	] ;
	sh:class schema:Person ;
	sh:group aushapes:ResidentsPropertyGroup ;
	sh:name "persons" .

With this solution, the values of schema:address can appear on different forms, supporting viewing and editing from multiple directions.

(Note that in older TopBraid versions such as 6.2, all property shapes that use a path expression also require a graphql:name field before they become visible on forms).

Flattened Forms

SHACL path expressions make it possible to define the characteristics of values that may be one or more steps away from the focus node. In the following example, the data from the person and the address resource are combined into a single, "flattened" form:

For the sake of brevity, we only included street address and suburb, and dropped postal address and state for now. The definition of such a form is as follows:

aushapes:FlattenedPersonShape
	a sh:NodeShape ;
	rdfs:label "Flattened Person Shape" ;
	sh:targetClass schema:Person ;
	sh:property aushapes:PersonViewShape-familyName ;
	sh:property aushapes:PersonViewShape-givenName ;
	sh:property [
		a sh:PropertyShape ;
		sh:path (
			schema:address
			schema:streetAddress
		) ;
		graphql:name "streetAddress" ;   # Required by current TopBraid
		sh:datatype xsd:string ;
		sh:group aushapes:AddressPropertyGroup ;
		sh:maxCount 1 ;
		sh:name "street address" ;
		sh:order "0"^^xsd:decimal ;
	] ;
	sh:property [
		a sh:PropertyShape ;
		sh:path (
			schema:address
			schema:addressLocality
		) ;
		graphql:name "suburb" ;   # Required by current TopBraid
		sh:datatype xsd:string ;
		sh:group aushapes:AddressPropertyGroup ;
		sh:maxCount 1 ;
		sh:name "suburb" ;
		sh:order "1"^^xsd:decimal ;
	] .

In the shape declarations above we are using blank nodes for some of the property shapes, just to show how that syntax would look like. However, the example also illustrates the benefits of using URIs for such property shapes, because we were able to reuse the very definitions of family name and given name from another shape. This modularity makes it possible to quickly assemble properties into different configurations and forms.

Note that such path expressions work best if there is only a single value, e.g. only one schema:address, because otherwise it would become impossible to distinguish which values belong together. For the same reason, it is non-trivial to support editing of such values, as the system will need to produce intermediate triples, possibly based on blank nodes, even if just a single value is entered by a user. The current generation of TopBraid does not support editing such values, yet future versions may.

Inferred Values

We have seen above that SHACL path expressions can be employed to collect values that may not be stored as "direct" values of a focus node. The concept of inferred values takes this one step further, and provides means to dynamically compute values and then render them on forms. The inferencing aspects of SHACL are covered by the document SHACL Advanced Features.

In the example below, a new form field labeled "number of residents" has been introduced. The values of this are dynamically computed by counting the number of incoming references via schema:address.

The definition of this includes a so-called property values rule using the property sh:values:

aushapes:AustralianAddressShape
	...
	sh:property [
		a sh:PropertyShape ;
		sh:path aushapes:numberOfResidents ;
		sh:datatype xsd:integer ;
		sh:group aushapes:ResidentsPropertyGroup ;
		sh:name "number of residents" ;
		sh:values [
			sh:count [
				sh:path [
					sh:inversePath schema:address ;
				] ;
			] ;
		] ;
    ] .

Details and many examples of such property value rules can be found in the article Inferring Data with SHACL Property Value Rules. It describes how to define inferred or calculated values in general as well is how to define inferred default values. A common requirement for a form is to display some kind of a default as a value of a property if the value does not exist. The default could be a pre-set constant or an inferred value. For example, if person’s address is not available, show the address of their parents.

DASH Widgets

The DASH namespace defines two properties that can inform a UI generation code what widgets to use to render and edit values of a property: dash:editor and dash:viewer. Both can link a property shape with resources from the DASH or other namespaces. The DASH namespace defines a set of user interface components that we found to be frequently needed when working with data in TopBraid EDG. We hope that other applications will also find them useful and will see value in interpreting their URIs consistently. Having said this, different or additional URIs can be declared by other namespaces and used by the corresponding applications. Further, we always look for feedback. If you have specific suggestions for extending or adjusting these definitions, please let us know.

The following two sections enumerate the currently defined DASH widgets. If dash:editor and/or dash:viewer have no values, TopBraid EDG will automatically identify the most suitable widget or widgets. To support selection of the most suitable widget for a given value and property path, each widget comes with a score:

Such scores may produce multiple suitable widgets. For example, a property may either allow xsd:date or xsd:dateTime values. In such cases, the user interface should provide means to select one out of the suitable widgets:

The following sections introduce the currently supported DASH editor and viewer widgets. At the time of writing (June 2019) these should be considered work-in-progress, in particular the details of the scoring algorithms may change. The maximum score of those is 50, allowing plenty of space for extensions to introduce higher values.

Editors

The following sub-sections enumerate the currently defined instances of dash:Editor from the DASH namespace. This will evolve further and may be different in the TopBraid version that you are using. Property shapes can explicitly specify the preferred editor for its values using dash:editor. If no such value has been specified, the system should pick a suitable default viewer based on the scoring system outlined for each widget.

dash:AutoCompleteEditor

Score: 1 if the value is an IRI. 0 otherwise

Rendering: an auto-complete field to enter the label of instances of the class specified for the property. For example if the sh:class of the property is ex:Country and the user starts typing "Nig" then "Niger" and "Nigeria" would show up as possible choices.

ex:Person-bornIn
	a sh:PropertyShape ;
	sh:path ex:bornIn ;
	sh:class ex:Country ;
	...

Implementations may also want to support the combination of sh:class with additional sh:node constraints to further narrow down the set of valid values. In this case the component would filter out any instances of the class that do not conform to the specified node shape. In the following example, the auto-complete would only show countries that are have true as their value for ex:sovereign. (This pattern is supported with TopBraid 7.0 onwards)

ex:Person-bornIn
	a sh:PropertyShape ;
	sh:path ex:bornIn ;
	sh:class ex:Country ;
	sh:node [
		sh:property [
			sh:path ex:sovereign ;
			sh:hasValue true ;
		]
	] ; ...

dash:BlankNodeEditor

Score: 1 for blank nodes. 0 otherwise.

Rendering: a read-only editor that displays the blank node similar to dash:BlankNodeViewer yet allows the surrounding user interface to at least provide a delete button.

dash:BooleanSelectEditor

Score: 10 for xsd:boolean literals. 0 for non-literals or if there is a sh:datatype constraint. null for properties allowing literals without specifying a particular datatype.

Rendering: a select box with values true and false. Also displays the current value (such as "1"^^xsd:boolean), but only allows to switch to true or false.

ex:Person-married
	a sh:PropertyShape ;
	sh:path ex:married ;
	sh:datatype xsd:boolean ;
	...

dash:DatePickerEditor

Score: 10 for xsd:date literals. 5 if the property has sh:datatype xsd:date. 0 otherwise.

Rendering: a calendar-like date picker.

ex:Person-dateOfBirth
	a sh:PropertyShape ;
	sh:path ex:dateOfBirth ;
	sh:datatype xsd:date ;
	...

dash:DateTimePickerEditor

Score: 10 for xsd:dateTime literals. 5 if the property has sh:datatype xsd:dateTime. 0 otherwise.

Rendering: a calendar-like date picker including a time selector.

ex:Customer-lastVisitTime
	a sh:PropertyShape ;
	sh:path ex:lastVisitTime ;
	sh:datatype xsd:dateTime ;
	...

dash:DetailsEditor

Score: null for non-literals, i.e. it can be selected manually via dash:editor. 0 otherwise.

Rendering: typically rendering as a nested form, using the properties defined by the sh:node or sh:class (in that order) of the property as fields. Alternative renderings are possible, such as opening the resource in a separate dialog.

This is particularly useful for some types of blank nodes that only make sense to be edited in the context of their parent resource.

ex:Product
	a owl:Class ;
	a sh:NodeShape ;
	rdfs:label "Product" ;
	rdfs:subClassOf owl:Thing ;
	sh:property ex:Product-weight .

ex:Product-weight
	a sh:PropertyShape ;
	sh:path ex:weight ;
	dash:editor dash:DetailsEditor ;
	dash:viewer dash:DetailsViewer ;
	sh:description "A blank node with a numeric field and a unit which is one of the QUDT mass units." ;
	sh:maxCount 1 ;
	sh:name "weight" ;
	sh:node ex:ValueWithWeight ;
	sh:nodeKind sh:BlankNode .

ex:ValueWithWeight
	a sh:NodeShape ;
	rdfs:label "Value with weight" ;
	sh:property ex:ValueWithWeight-numericValue ;
	sh:property ex:ValueWithWeight-unit .

ex:ValueWithWeight-numericValue
	a sh:PropertyShape ;
	sh:path ex:numericValue ;
	sh:datatype xsd:decimal ;
	sh:maxCount 1 ;
	sh:minCount 1 ;
	sh:name "numeric value" .

ex:ValueWithWeight-unit
	a sh:PropertyShape ;
	sh:path ex:unit ;
	sh:class <http://qudt.org/schema/qudt/Unit> ;
	sh:maxCount 1 ;
	sh:minCount 1 ;
	sh:name "unit" ;
	sh:node [
		rdfs:label "Permissible values must have quantity kind Mass." ;
		sh:property [
			sh:path <http://qudt.org/schema/qudt/hasQuantityKind> ;
			sh:hasValue <http://qudt.org/vocab/quantitykind/Mass> ;
		] ;
	] .

As of TopBraid EDG 7.5, this widget requires that the surrounding property (ex:weight above) declares sh:nodeKind sh:BlankNode and also has a sh:node constraint that points at a node shape that declares the properties that shall be editable.

dash:EnumSelectEditor

Score: 10 if there exists a sh:in constraint for the same property at the current focus node. 0 otherwise.

Rendering: a drop-down editor for enum fields (based on the sh:in list, in that order).

ex:AustralianAddressShape-addressRegion
	a sh:PropertyShape ;
	sh:path schema:addressRegion ;
	sh:in ( "ACT" "NSW" "NT" "QLD" "SA" "TAS" "VIC" "WA" ) ;
	...

dash:InstancesSelectEditor

Score: null if there exists a sh:class for the property. 0 otherwise.

Rendering: a drop-down editor for all instances of the target class (based on sh:class of the property). Typically only used for classes that have few instances.

ex:Person-homeCountry
	a sh:PropertyShape ;
	sh:path ex:homeCountry ;
	sh:class ex:Country ;
	dash:editor dash:InstancesSelectEditor ;
	...

dash:RichTextEditor

Score: 10 for rdf:HTML literals. 0 otherwise.

Rendering: a rich text editor to enter the lexical value of a literal and a drop down to select language. The selected language is stored in the HTML lang attribute of the root node in the HTML DOM tree.

ex:Concept-definition
	a sh:PropertyShape ;
	sh:path skos:definition ;
	sh:datatype rdf:HTML ;
	...

dash:SubClassEditor

Score: null i.e. this should be selected explicitly through a dash:editor statement. However, this widget is typically only used if the property has a dash:rootClass constraint, or (at minimum) only allows classes as values.

Rendering: This may be an auto-complete widget to select a class or a class hierarchy widget, or a combination thereof. In TopBraid, this is an auto-complete widget with a button to open a class tree dialog. The permissible values are a given class or its subclasses, defaulting to rdfs:Resource. This is typically used with dash:rootClass to allow the user to select a subclass of the given root class.

ex:Drug-impactedCell
	a sh:PropertyShape ;
	sh:path ex:impactedCell ;
	dash:rootClass obo:CL_0000000 ;
	dash:editor dash:SubClassEditor ;
	...

dash:TextAreaEditor

Score: 0 if the property is marked dash:singleLine true. 20 if the value is an xsd:string literal and dash:singleLine false. 5 if the value is an xsd:string literal. 2 if the property has xsd:string among the permissible datatypes. null if the property has a custom datatype (not from xsd or rdf namespaces but for example geo:wktLiteral). 0 otherwise.

Rendering: a multi-line text area to enter the value of a literal.

ex:Country-description
	a sh:PropertyShape ;
	sh:path ex:description ;
	sh:datatype xsd:string ;
	dash:singleLine false ;
	...

dash:TextAreaWithLangEditor

Score: 0 if the property is marked dash:singleLine true. 15 if the value is an rdf:langString literal and dash:singleLine false. 5 if the value is an rdf:langString literal or the property permits such values. 0 otherwise.

Rendering: a multi-line text area to enter the value of a literal and a drop down to select a language.

ex:Country-description
	a sh:PropertyShape ;
	sh:path ex:description ;
	sh:datatype rdf:langString ;
	dash:singleLine false ;
	...

dash:TextFieldEditor

Score: 10 if the value is a literal that is neither rdf:langString nor xsd:boolean. 0 otherwise.

Rendering: an input field to enter the value of a literal, without the ability to change language or datatype.

ex:Country-code
	a sh:PropertyShape ;
	sh:path ex:code ;
	sh:datatype xsd:string ;
	...

dash:TextFieldWithLangEditor

Score: 11 if the value is an rdf:langString literal or the property permits either (both) rdf:langString or xsd:string. 5 if the property is not dash:singleLine false and permits rdf:langString values. 0 otherwise.

Rendering: a single-line input field to enter the value of a literal and a drop down to select language, which is mandatory unless xsd:string is among the permissible datatypes.

ex:Concept-prefLabel
	a sh:PropertyShape ;
	sh:path skos:prefLabel ;
	sh:datatype rdf:langString ;
	...

dash:URIEditor

Score: 10 if the value is a IRI node and the property has sh:nodeKind sh:IRI and no sh:class constraint. null if the value is a IRI node. 0 otherwise.

Rendering: an input field to enter the URI of a resource, e.g. as value of rdfs:seeAlso or to enter the URL of an image on the web.

ex:Thing-seeAlso
	a sh:PropertyShape ;
	sh:path rdfs:seeAlso ;
	sh:nodeKind sh:IRI ;
	dash:editor dash:URIEditor ;
	...

Viewers

The following sub-sections enumerate the currently defined instances of dash:Viewer from the DASH namespace. This will evolve further and may be different in the TopBraid version that you are using. Property shapes can explicitly specify the preferred viewer for its values using dash:viewer. If no such value has been specified, the system should pick a suitable default viewer based on the scoring system outlined for each widget.

Most viewers render a single RDF value, typically as a single widget, on the screen. Form editors such as TopBraid then offer buttons to edit individual values and add or delete values. However, some viewers need to take more complete control over how multiple values of a property at a focus node are rendered. The only example of such viewer in DASH is dash:ValueTableViewer, which displays all values of a property as a HTML table. In those cases, the notions of generic add and delete buttons do not apply. Such viewers are called Multi Viewers and are declared instance of dash:MultiViewer instead of dash:SingleViewer. The equivalent classes for editors are dash:MultiEditor and dash:SingleEditor.

dash:BlankNodeViewer

Score: 1 for blank nodes. 0 for all other nodes.

Rendering: a human-readable label of the blank node. For example, if the blank node is an OWL restriction, then Manchester Syntax could be used. If the blank node is a SPIN RDF expression, then a SPARQL string could be produced. This rendering may include hyperlinks to other resources that can be reached from the blank node.

dash:DetailsViewer

Score: 0 for literals. null for IRIs and blank nodes.

Rendering: shows the details of the value using its default view shape or the shape specified using sh:node, as a nested form-like display. An example of this can be found in the Nested Forms section.

dash:HTMLViewer

Score: 50 for literals with datatype rdf:HTML. 0 for all other values.

Rendering: the literal parsed into HTML DOM elements. Hyperlinks in the HTML may get redirected to select resources within the same application. Also displays the language if the HTML has a lang attribute on its root DOM element.

dash:HyperlinkViewer

Score: 50 for literals with datatype xsd:anyURI. null for xsd:string literals. 0 for all other values.

Rendering: a clickable hyperlink to the specified URI/URL.

dash:ImageViewer

Score: 50 for IRI nodes or literals that have a case-insensitive recognized image ending such as .png, .jpg, .jpeg, .gif and .svg.

Rendering: the image at the given URL, using <img> in HTML.

dash:LabelViewer

Score: 5 if the value is a IRI. 0 otherwise.

Rendering: as a hyperlink to that URI based on the display label of the resource. The display label is typically based on the must suitable rdfs:label or skos:prefLabel for the current user, based on her language preferences. Also includes other ways of interacting with the URI such as opening a nested summary display.

dash:LangStringViewer

Score: 10 if the value is a literal of type rdf:langString. 0 otherwise.

Rendering: as the text plus a language indicator (flag or language tag).

dash:LiteralViewer

Score: 1 if the value is a literal. 0 otherwise.

Rendering: the lexical form of the value.

dash:URIViewer

Score: 1 if the value is a IRI. 0 otherwise.

Rendering: as a hyperlink to that URI. Also includes other ways of interacting with the URI such as opening a nested summary display.

dash:ValueTableViewer

This is a Multi Viewer.

Score: null

Rendering: all values of the property at the focus node are rendered into a single (HTML) table that can be scrolled and paged independently from the rest of the form. Each value becomes one row. The columns of the table are derived from the node shape specified using sh:node for the property, in the order specified using sh:order.

In this example we have used a sh:values rule to infer the values of the first column. In this case, the values are simply pointing back to the focus node of each row, using sh:this. Note that dash:applicableToClass or sh:targetClass are needed to get this inference correctly.

skos:Concept
    sh:property ex:Concept-broader-inverse .

ex:Concept-broader-inverse
    a sh:PropertyShape ;
    sh:path [ sh:inversePath skos:broader ] ;
    sh:group skos:HierarchicalRelationships ;
    sh:name "narrower (table)" ;
    dash:viewer dash:ValueTableViewer ;
    sh:node ex:ConceptTableShape .

ex:ConceptTableShape
    a sh:NodeShape ;
    dash:applicableToClass skos:Concept ;
    rdfs:comment "A node shape defining the columns for a dash:ValueTableViewer." ;
    rdfs:label "Concept table shape" ;
    sh:property ex:ConceptTableShape-self ;
    sh:property ex:ConceptTableShape-type ;
    sh:property ex:ConceptTableShape-altLabel .

ex:ConceptTableShape-self
    a sh:PropertyShape ;
    sh:path ex:self ;
    sh:description "This column is used to render the (narrower) concept itself." ;
    sh:name "narrower concept" ;
    sh:nodeKind sh:IRI ;
    sh:order "0"^^xsd:decimal ;
    sh:values sh:this .

ex:ConceptTableShape-type
    a sh:PropertyShape ;
    sh:path rdf:type ;
    sh:description "The second column shows the type of each value." ;
    sh:name "type" ;
    sh:nodeKind sh:IRI ;
    sh:order "1"^^xsd:decimal .

ex:ConceptTableShape-altLabel
    a sh:PropertyShape ;
    sh:path skos:altLabel ;
    sh:description "The third column shows the alternative labels." ;
    sh:name "alt labels" ;
    sh:or dash:StringOrLangString ;
    sh:order "2"^^xsd:decimal .