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 ;
    ] .
  • 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.