Good practice: CIDOC-CRM data properties and classes

i am trying to understand what would be the best practice in Omeka-S to describe objects, which according to CIDOC-CRM, would have a nested structure.

For instance if i create an item with the E24 Class ( Physical man made thing), i can then insert a field with the P1 Property ( is identified by), and then i can add a literal as text to fill the field.

Nevertheless, according to CIDOC-CRM, ideally i should connect a class E42 for the identifier, which then contains my literal.

I have the feeling that applying this practice in Omeka-S it would lead me to an overload of Omeka resources that i would then have to create for each objects to get a similar output. It would easily get out of hand.

As mentioned here i could just stick to the data properties. Though, if i would later set up a script to convert the JSON-LD Omeka-S provides to RDF, i would have to do quite some hard coding into converting the fields to a proper structure.

Wouldn’t it be possible to define classes in the resource template as data type? Or something similar, where i could at least add a key to our json-ld objects to make the later conversion just a bit easier?

How should i proceed?


You could use Omeka’s rep.resource.json event to modify cidoc-crm:P1 value nodes to include a CIDOC-CRM type of cidoc-crm:E42. Something like this:

    "cidoc-crm:P1": [
            "@value": "M_186_555",
            "cidoc_crm_type": "E42"

This is still valid JSON-LD since parsers are supposed to ignore non-prefixed keys in value nodes. Then, your script could make the conversion based on the cidoc_crm_type.

However, I sense that it would take a comparable amount of effort just to do all this in your script. Simply detect CIDOC-CRM properties and map them to their respective classes, all at runtime.

Okay, thanks for the suggestion.
I’ll try to discover how to detect the properties with certain libraries such as rdflib or easyrdf.
If you have some more advices, i’m all ears.

You won’t need to use a RDF parser to discover the properties. Just iterate the JSON object provided by the Omeka API, and any key that begins with cidoc-crm: (or however you prefix the vocabulary) is a CIDOC-CRM property that will need further processing.

Yes, i meant using the library to iterate the properties i export from Omeka, so that i can automatise the proper structure and hierarchies.
E.g. if P1 always has a child class which is E42, i will automatically parse the proper rdf.

At the end I decided to create an Omeka-S module to deal with multi-input fields. (I am now extending my question, to a module specific one).
This became necessary as certain instances in CIDOC-CRM, such as the dimension class usually end up having 3 properties, e.g:

crm:P43_has_dimension [ a crm:E54_Dimension ;
            crm:P2_has_type  “width” ;
            crm:P90_has_value "82" ;
            crm:P91_has_unit <> ], 

Therefore I found necessary to design something like a multi input field:

I therefore created a custom data type to parse all the existing classes installed in Omeka S and to create specific labels in the resource template.

I am now thinking of creating an array which contains the properties I select in the dropdown(s) and the string attached next to it.

I am planning to create a json-ld like this one:

         "type": "nesteddatatype#cidoc-crm:E54_Dimension",
         "property_label": "P43 has dimension",
         "@value": "value, value", <- all the @values of the resource, flattened and splitted by a comma
         "entity": "E54_Dimension" <- defined through the getJsonLd()
         "properties": [ 
                 "P2_has_type" : “value”,
                 "P90_has_value" : “value”,


My question would then be how can I select, perhaps through the hydrate function, a custom data-value-key I specify in my html, so that i can add it in my json and it will be maintained, when re-freshing/editing the item?

   <div class="repeat-property">
        <select name="property-dropdown" data-value-key="property"> // this one 
            <?php foreach($properties as $property): ?>
                <option value="<?= $property->term() ?>"><?= $property->label() ?></option>
            <?php endforeach; ?>
        <textarea name="property-value" data-value-key="@value"></textarea>

For the repeatable property/value pairs, you’ll need to somehow index your data-value-keys so Omeka’s client-side processing doesn’t overwrite duplicate keys. Something like:

<select data-value-key="property-1">
    <option value="P2_has_type">Has type</option>
    <option value="P90_has_value">Has value</option>
<textarea data-value-key="value-1"></textarea>
<select data-value-key="property-2">
    <option value="P2_has_type">Has type</option>
    <option value="P90_has_value">Has value</option>
<textarea data-value-key="value-2"></textarea>

In hydrate() you’ll need to package this data however you see fit and save it using $value->setValue($data). Then you’ll need to use the o:prepare-value JS event to prepare the fields as they are rendered. There are a lot of moving parts here, but I believe it is possible. It’ll just take trial and error.

Thank you! i managed to create the basic of my module, i now have json-ld as i want:

            "type": "nesteddatatype#cidoc-crm:E54_Dimension",
            "property_id": 1262,
            "property_label": "P43 has dimension",
            "is_public": true,
            "@value": "1 2 3",
            "entity_label": "cidoc-crm:E54_Dimension",
            "properties": {
                "cidoc-crm:P1_is_identified_by": "1",
                "cidoc-crm:P2_has_type": "2",
                "cidoc-crm:P3_has_note": "3"

and a rough visual structure of it, where i use the valueObj to populate the frontend:

I still have to add language and uri filters in my module, but one step at a time.

1 Like