Skip to content

Inline Creation in Views

Martynas Jusevičius edited this page Jan 20, 2026 · 4 revisions

This document proposes a feature for enabling users to create related items inline within resource views, eliminating the need to navigate away from context.

Problem Statement

Currently, when viewing a resource with related items (e.g., a SKOS Concept with "Narrower Concepts" view), users must:

  1. Leave the current page
  2. Navigate to a container to create a new item
  3. Manually establish the relationship back to the parent resource
  4. Return to the original resource

This breaks user context and creates a poor user experience.

Solution Overview

Enable inline creation directly within ldh:View resources that are attached to properties via ldh:view or ldh:inverseView. When a view displays related items, users can create new items directly in that view with automatic relationship establishment.

Architecture

Property-Driven Views

LinkedDataHub uses a property-driven view architecture where:

  • ldh:view: Attaches views to properties for forward relationships ($about property ?value)
  • ldh:inverseView: Attaches views to properties for inverse relationships (?value property $about)
  • Views are ldh:View resources containing SPARQL queries that render related data

Example from SKOS package:

skos:narrower ldh:view :NarrowerConcepts .

:NarrowerConcepts a ldh:View ;
    dct:title "Narrower concepts" ;
    spin:query :SelectNarrowerConcepts .

:SelectNarrowerConcepts a sp:Select ;
    sp:text """
    SELECT DISTINCT ?narrower
    WHERE { GRAPH ?graph { $about skos:narrower ?narrower } }
    ORDER BY ?narrower
    """ .

Inline Creation Metadata

To enable inline creation within views, add the following properties to ldh:View resources:

Required Properties

  • ldh:property: Specifies the RDF property that links the parent resource to newly created items

    • For ldh:view: The property the view is attached to (forward relationship)
    • For ldh:inverseView: The property the view is attached to (inverse relationship)
  • ldh:container: The container URI where new items will be created via HTTP PUT

Optional Properties

  • ldh:showWhenEmpty: Controls whether the view displays when the query returns no results (defaults to true)

Type Inference

The RDF class of created items is automatically inferred from the property's ontology definition:

  • Forward relationships (ldh:view): Use the property's rdfs:range
  • Inverse relationships (ldh:inverseView): Use the property's rdfs:domain

Example:

# skos:narrower has rdfs:range skos:Concept
skos:narrower ldh:view :NarrowerConcepts .

# Inline creation in :NarrowerConcepts will create skos:Concept instances
# skos:inScheme has rdfs:domain skos:Concept
skos:inScheme ldh:inverseView :ConceptsInScheme .

# Inline creation in :ConceptsInScheme will create skos:Concept instances

Implementation Strategy

1. Pattern Inference (Primary Approach)

For ~80% of common cases, automatically extract metadata from the view definition:

  1. Infer ldh:property: Detect the property from the view's attachment point (the property that has ldh:view or ldh:inverseView pointing to this view)
  2. Infer target class:
    • For ldh:view: Look up rdfs:range of the property in the ontology
    • For ldh:inverseView: Look up rdfs:domain of the property in the ontology
  3. Infer ldh:container: Use application conventions or configuration

This works for straightforward patterns like:

SELECT ?narrower
WHERE { GRAPH ?graph { $about skos:narrower ?narrower } }

2. Explicit Metadata (Fallback)

For complex scenarios, developers specify metadata explicitly:

  • Property paths: skos:broader+
  • UNION queries with multiple properties
  • Missing rdfs:range or rdfs:domain definitions
  • Complex JOINs or filters

Example with explicit metadata:

:NarrowerConcepts a ldh:View ;
    dct:title "Narrower concepts" ;
    spin:query :SelectNarrowerConcepts ;
    ldh:property skos:narrower ;
    ldh:container <concepts/> ;
    ldh:showWhenEmpty true .

User Flow

Forward Relationship Example (ldh:view)

Viewing a skos:Concept resource:

  1. User sees "Narrower Concepts" view displaying existing narrower concepts
  2. View includes an [Add New] button
  3. Clicking opens a modal form for creating a new concept
  4. User enters concept details (slug, label, definition, etc.)
  5. System infers type from rdfs:range of skos:narrowerskos:Concept
  6. System issues HTTP PUT to create the new concept
  7. System automatically adds parent skos:narrower newConcept triple
  8. View refreshes to show the new concept

Inverse Relationship Example (ldh:inverseView)

Viewing a skos:ConceptScheme resource:

  1. User sees "Concepts in Scheme" view displaying concepts that reference this scheme
  2. View includes an [Add New] button
  3. Clicking opens a modal form for creating a new concept
  4. User enters concept details
  5. System infers type from rdfs:domain of skos:inSchemeskos:Concept
  6. System issues HTTP PUT to create the new concept
  7. System automatically adds newConcept skos:inScheme scheme triple
  8. View refreshes to show the new concept

Enterprise Applications

This feature enables building functional enterprise CRUD applications declaratively:

  • Schema.org Vocabularies: Use standard vocabularies (Organization, Person, Event, Product, etc.)
  • XSLT Components: Build interactive UI patterns (tabs, sortable tables, bulk operations)
  • Property-Driven Views: Attach views to vocabulary properties for automatic rendering
  • Inline Creation: Enable contextual data entry without navigation

Example: Building a CRM using Schema.org:

schema:employee ldh:view :EmployeeList ;
    ldh:inverseView :EmployerView .

:EmployeeList a ldh:View ;
    dct:title "Employees" ;
    spin:query :SelectEmployees ;
    ldh:property schema:employee ;
    ldh:container <employees/> .

# Type is automatically inferred from rdfs:range of schema:employee

Implementation Checklist

Vocabulary

  • Add ldh:property to ldh.ttl
  • Add ldh:container to ldh.ttl
  • Add ldh:showWhenEmpty to ldh.ttl

XSLT

  • Pattern inference logic to extract property from view attachment
  • Type inference via rdfs:range (forward) or rdfs:domain (inverse) lookup
  • [Add New] button rendering in view templates
  • Modal form with auto-populated linking property and inferred type
  • Client-side PUT request handling with Saxon-JS

Java Backend

  • Detect inline creation requests (via header or parameter)
  • Extract parent URI and property URI from request
  • Query ontology for rdfs:range/rdfs:domain to infer type
  • Add type triple to new resource
  • Automatically add linking triple on successful creation
  • Handle both forward (ldh:view) and inverse (ldh:inverseView) cases

Testing

  • HTTP tests for inline creation with forward relationships
  • HTTP tests for inline creation with inverse relationships
  • UI tests for modal form behavior
  • Edge cases: missing domain/range, inference failures
  • Property inheritance via rdfs:subPropertyOf

Related Documentation

Version

This feature proposal is for LinkedDataHub 5.2.1+, which introduced the property-driven view architecture with ldh:view and ldh:inverseView.

Clone this wiki locally