Skip to content

SHACL Configuration

The SHACL (Shapes Constraint Language) file is a cornerstone of HERITRACE, serving two primary functions:

  • Automatic Form Generation: The application reads your SHACL schema to dynamically generate forms for creating and editing entities. It uses property definitions to create the appropriate input fields, labels, and validation hints.
  • Data Validation: It enforces the constraints defined in the schema—such as data types, cardinality, and value ranges—to ensure the integrity of all data entered into the system.

In short, your SHACL file acts as a single source of truth that dictates both the data entry interface and the validation rules.

For a complete understanding of SHACL and its advanced features, refer to the official W3C documentation:

The SHACL schema is located at resources/shacl.ttl. You can configure the path in config.py:

SHACL_PATH = 'resources/shacl.ttl'

Define the ontologies and vocabularies you’ll use at the top of your file.

@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix schema: <http://schema.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
# Domain-specific vocabularies
@prefix datacite: <http://purl.org/spar/datacite/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix fabio: <http://purl.org/spar/fabio/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix pro: <http://purl.org/spar/pro/> .
@prefix prism: <http://prismstandard.org/namespaces/basic/2.0/> .

Each shape targets a specific class and defines its properties.

schema:JournalArticleShape
a sh:NodeShape ;
sh:targetClass fabio:JournalArticle ;
sh:property [
# Property constraints go here
] .

SHACL constraints define the validation rules for properties on a targeted class.

Control how many values a property can have.

  • sh:minCount: The minimum number of values. A value of 1 or more makes the property required.
  • sh:maxCount: The maximum number of values. A value of 1 restricts it to a single value.
# A required, single-value property
sh:property [
sh:path dcterms:title ;
sh:minCount 1 ;
sh:maxCount 1 ;
] .
# An optional, multi-value property
sh:property [
sh:path prism:keyword ;
sh:minCount 0 ; # Not required
# No maxCount means unlimited values
] .

Specify the expected data type for a literal value. You can provide alternatives using sh:or.

# String value
sh:property [
sh:path dcterms:title ;
sh:datatype xsd:string ;
] .
# Date value with multiple allowed formats
sh:property [
sh:path prism:publicationDate ;
sh:or (
[ sh:datatype xsd:date ] # 2024-01-15
[ sh:datatype xsd:gYearMonth ] # 2024-01
[ sh:datatype xsd:gYear ] # 2024
) ;
] .

Restrict property values to a specific set of options.

  • sh:hasValue: The property must have at least one value that equals the specified node.
  • sh:in: The property value must be one of the members of a provided list.
# The value must be exactly pro:author
sh:property [
sh:path pro:withRole ;
sh:hasValue pro:author ;
] .
# The value must be one of the specified identifier schemes
sh:property [
sh:path datacite:usesIdentifierScheme ;
sh:in ( datacite:doi datacite:pmid datacite:pmcid ) ;
] .

Specify that a property’s value must conform to another shape. This is used to validate complex objects or relationships.

# The value for 'hasIdentifier' must be an entity that validates
# against the 'JournalArticleIdentifierShape'.
sh:property [
sh:path datacite:hasIdentifier ;
sh:node schema:JournalArticleIdentifierShape ;
] .

Apply a constraint only when a specific condition is met. This is useful for creating validation rules that depend on the value of another property.

In the example below, the sh:pattern is only checked if the identifier’s scheme (datacite:usesIdentifierScheme) is datacite:doi.

schema:JournalArticleIdentifierShape
a sh:NodeShape;
sh:targetClass datacite:Identifier;
sh:property [
sh:path literal:hasLiteralValue;
sh:datatype xsd:string;
# This constraint only applies if the condition below is met
sh:condition [
sh:path datacite:usesIdentifierScheme;
sh:hasValue datacite:doi;
];
# The pattern to validate against
sh:pattern "^10\\..+/.+";
sh:message "DOI is not valid.";
].

Pattern Matching (sh:pattern & sh:message)

Section titled “Pattern Matching (sh:pattern & sh:message)”

Use regular expressions to validate the format of string literals. You can provide a custom sh:message to guide users.

# Validate ISSN format
sh:property [
sh:path literal:hasLiteralValue ;
sh:condition [
sh:path datacite:usesIdentifierScheme ;
sh:hasValue datacite:issn ;
] ;
sh:pattern "^[0-9]{4}-[0-9]{3}[0-9X]$" ;
sh:message "ISSN must be in the format NNNN-NNNC." ;
] .

HERITRACE is data-model-agnostic. To handle complex relationships that require their own properties (for instance, defining a person’s role in a project or the time frame of a collaboration), you can implement a “proxy pattern.” This involves using an intermediate entity to link two other entities, where the intermediate entity holds the attributes of the relationship.

You can define this entire structure using SHACL. The application will interpret it to generate the appropriate forms and validation. The example below shows how to model an author’s role, but the same pattern can be applied to any similar scenario in your data model.

Here is how the pattern is implemented:

  1. Link to the Proxy Shape: From your primary entity’s shape (e.g., a JournalArticleShape), use sh:node to point to a shape that defines the proxy entity (e.g., AuthorShape).

    sh:property [
    sh:path pro:isDocumentContextFor ;
    sh:node schema:AuthorShape ;
    ] .
  2. Define the Proxy Shape: Create the shape for the intermediate entity (e.g., AuthorShape). This shape should:

    • Target the class of the intermediate entity (e.g., pro:RoleInTime).
    • Define constraints for the relationship’s attributes (e.g., sh:hasValue pro:author).
    • Link to the final target entity’s shape (e.g., sh:node schema:ResponsibleAgentShape).
    schema:AuthorShape
    a sh:NodeShape ;
    sh:targetClass pro:RoleInTime ;
    sh:property [
    sh:path pro:withRole ;
    sh:hasValue pro:author ;
    ] ;
    sh:property [
    sh:path pro:isHeldBy ;
    sh:node schema:ResponsibleAgentShape ;
    ] .

Understanding how SHACL and Display Rules work together is crucial for effective HERITRACE configuration. While both components are individually optional, their interaction follows specific rules that determine data validation, form generation, and user interface behavior.

ScenarioSHACL SchemaDisplay RulesEntity Creation MethodProperty ConstraintsForm GenerationDisplay Names
Full Configuration✅ Present✅ PresentSHACL-based forms (predefined entity types)✅ SHACL constraints enforced✅ Generated from SHACL + Display Rules styling✅ From Display Rules with URI fallback
SHACL Only✅ Present❌ AbsentSHACL-based forms (predefined entity types)✅ SHACL constraints enforced✅ Generated from SHACL only✅ Auto-generated from URI
Display Rules Only❌ Absent✅ PresentCustom properties form (free-form)❌ No validation✅ Custom properties form✅ From Display Rules (if class matches) or URI
Neither Present❌ Absent❌ AbsentCustom properties form (free-form)❌ No validation✅ Custom properties form✅ Auto-generated from URI
  • Rule: When a SHACL shape exists for an entity class, only properties defined in that shape are available for entity creation and editing.
  • Implication: You cannot add arbitrary properties through Display Rules if they’re not defined in the corresponding SHACL shape.
  • Example: If JournalArticleShape only defines dcterms:title and dcterms:abstract, you cannot create display rules for prism:keyword unless you first add it to the SHACL shape.
  • Rule: The presence of SHACL determines the entity creation method available to users.
  • With SHACL: Users get structured forms with predefined entity types and properties, limited to what’s defined in SHACL shapes.
  • Without SHACL: Users get a flexible custom properties form where they can define any property URI and value.
  • Example: With SHACL, you select “Journal Article” from a dropdown and fill predefined fields. Without SHACL, you manually enter property URIs like dcterms:title and their values.
  • Rule: Display names for properties follow this priority order:
    1. Display Rules: displayName from matching display rule
    2. Auto-generated from URI: Automatic formatting of property URI using format_uri_as_readable()
  • Note: The system always provides readable names by converting URIs like dcterms:title to title or hasPublicationDate to has publication date.
  • Rule: When multiple SHACL shapes target the same class, Display Rules priority determines which shape to use.
  • Implication: Lower priority numbers (higher priority) in Display Rules affect SHACL shape selection.
  • Example: Both RegularIssueShape and SpecialIssueShape target fabio:JournalIssue, but the Display Rule with priority: 1 determines which shape applies.
  • Rule: Data validation constraints come exclusively from SHACL shapes, never from Display Rules.
  • Implication: Display Rules control presentation and behavior, but cannot override or add validation constraints.
  1. Define SHACL First: Always start by defining your SHACL shapes before creating Display Rules.

  2. Align Properties: Ensure Display Rules only reference properties that exist in the corresponding SHACL shapes.

  3. Test Iteratively: When modifying SHACL shapes, verify that existing Display Rules still function correctly.

  4. Use Consistent Priorities: Align Display Rules priorities with your intended SHACL shape precedence.

  • Reloading: When running in development mode, the application will automatically restart when it detects changes to shacl.ttl, applying your updates instantly.
  • Update Display Rules: If you modify properties, remember to update resources/display_rules.yaml to reflect those changes in the user interface.
  • Validation Testing: After SHACL changes, test form generation and validation to ensure all constraints work as expected.