-
Notifications
You must be signed in to change notification settings - Fork 150
Inline Creation in Views
This document proposes a feature for enabling users to create related items inline within resource views, eliminating the need to navigate away from context.
Currently, when viewing a resource with related items (e.g., a SKOS Concept with "Narrower Concepts" view), users must:
- Leave the current page
- Navigate to a container to create a new item
- Manually establish the relationship back to the parent resource
- Return to the original resource
This breaks user context and creates a poor user experience.
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.
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:Viewresources 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
""" .To enable inline creation within views, add the following properties to ldh:View resources:
-
ldh:container: The container URI where new items will be created via HTTP PUT
-
ldh:showWhenEmpty: Controls whether the view displays when the query returns no results (defaults totrue)
The property-driven architecture enables automatic inference of:
Property - Implicit from the view's attachment point:
- The property that has
ldh:vieworldh:inverseViewpointing to this view - For
ldh:view: Forward relationship (parent → child) - For
ldh:inverseView: Inverse relationship (child → parent)
Type - Inferred from the property's ontology definition:
-
Forward relationships (
ldh:view): Use the property'srdfs:range -
Inverse relationships (
ldh:inverseView): Use the property'srdfs:domain
Example:
# skos:narrower has rdfs:range skos:Concept
skos:narrower ldh:view :NarrowerConcepts .
# Property is implicit: skos:narrower (from attachment)
# Type is inferred: skos:Concept (from rdfs:range)
# Direction: forward (ldh:view)# skos:inScheme has rdfs:domain skos:Concept
skos:inScheme ldh:inverseView :ConceptsInScheme .
# Property is implicit: skos:inScheme (from attachment)
# Type is inferred: skos:Concept (from rdfs:domain)
# Direction: inverse (ldh:inverseView)For ~80% of common cases, everything is automatically inferred:
-
Infer property: Query ontology for
?property ldh:view <thisView>or?property ldh:inverseView <thisView> -
Infer type:
- For
ldh:view: Query?property rdfs:range ?type - For
ldh:inverseView: Query?property rdfs:domain ?type
- For
-
Use configured container: From
ldh:containeron the view
Example (no explicit metadata needed):
skos:narrower ldh:view :NarrowerConcepts .
:NarrowerConcepts a ldh:View ;
dct:title "Narrower concepts" ;
spin:query :SelectNarrowerConcepts ;
ldh:container <concepts/> .
# Everything else is automatic!The only metadata that MUST be specified is the container:
:NarrowerConcepts a ldh:View ;
dct:title "Narrower concepts" ;
spin:query :SelectNarrowerConcepts ;
ldh:container <concepts/> . # Required: where to create itemsFor complex scenarios where inference might fail:
- Property paths:
skos:broader+ - UNION queries with multiple properties
- Missing
rdfs:rangeorrdfs:domaindefinitions - Transitive properties
In these cases, inline creation may need to be disabled or handled with custom logic.
Viewing a skos:Concept resource:
- User sees "Narrower Concepts" view displaying existing narrower concepts
- View includes an [Add New] button
- Clicking opens a modal form for creating a new concept
- System infers property from attachment:
skos:narrower - System infers type from
rdfs:rangeofskos:narrower→skos:Concept - User enters concept details (slug, label, definition, etc.)
- System issues HTTP PUT to
ldh:containerto create the new concept - System automatically adds
parent skos:narrower newConcepttriple - View refreshes to show the new concept
Viewing a skos:ConceptScheme resource:
- User sees "Concepts in Scheme" view displaying concepts that reference this scheme
- View includes an [Add New] button
- Clicking opens a modal form for creating a new concept
- System infers property from attachment:
skos:inScheme - System infers type from
rdfs:domainofskos:inScheme→skos:Concept - User enters concept details
- System issues HTTP PUT to
ldh:containerto create the new concept - System automatically adds
newConcept skos:inScheme schemetriple - View refreshes to show the new concept
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 .
:EmployeeList a ldh:View ;
dct:title "Employees" ;
spin:query :SelectEmployees ;
ldh:container <employees/> .
# Property: inferred from attachment (schema:employee)
# Type: inferred from rdfs:range of schema:employee
# Direction: forward relationship (ldh:view)- Add
ldh:containertoldh.ttl - Add
ldh:showWhenEmptytoldh.ttl
- SPARQL SELECT on ontology: Find property from view attachment (
SELECT ?property WHERE { ?property ldh:view <thisView> }orldh:inverseView) - SPARQL SELECT on ontology: Determine direction (check if result came from
ldh:vieworldh:inverseViewquery) - SPARQL SELECT on ontology: Infer type via
rdfs:range(forward) orrdfs:domain(inverse) - Render [Add New] button in view templates (only when
ldh:containeris present) - Show modal form with inferred type (standard LinkedDataHub form, but modal)
- On form save: Issue PUT to
ldh:containerto create new instance (standard LinkedDataHub behavior) - After PUT succeeds: Issue PATCH to add linking triple:
-
Forward (
ldh:view): PATCH parent document withINSERT DATA { <parent> <property> <newInstance> } -
Inverse (
ldh:inverseView): PATCH new document withINSERT DATA { <newInstance> <property> <parent> }
-
Forward (
- 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
- Packages Reference - Property-driven view architecture
-
SKOS Package - Example implementation with
ldh:viewandldh:inverseView - Stylesheets Reference - XSLT customization patterns
This feature proposal is for LinkedDataHub 5.2.1+, which introduced the property-driven view architecture with ldh:view and ldh:inverseView.