Make description accessible in the item selector #177

Open
opened 2025-08-23 18:23:26 +00:00 by mih · 10 comments
mih commented 2025-08-23 18:23:26 +00:00 (Migrated from github.com)

This issue touches upon other issues (like #168), hence I am not proposing a solution, just stating the issue itself.

Right now, the instance selection only shows item titles, and skos:note attributes. However, just a the description of a class slot is often essential (hence accessible in the forms via hover), the same is true for instances.

Making a longer form description show in the instance selector presently requires an explicit skos:note property. However, a description could come with other semantics (e.g., dcterms:description).

It would be good to be able to instruct shacl-vue what to present as a description for an item in the instance selection -- but not require data models, and records to be tailored towards a particular convention proposed/enforced by shacl-vue.

This issue touches upon other issues (like #168), hence I am not proposing a solution, just stating the issue itself. Right now, the instance selection only shows item titles, and `skos:note` attributes. However, just a the description of a class slot is often essential (hence accessible in the forms via hover), the same is true for instances. Making a longer form description show in the instance selector presently requires an explicit `skos:note` property. However, a description could come with other semantics (e.g., `dcterms:description`). It would be good to be able to instruct shacl-vue what to present as a `description` for an item in the instance selection -- but not require data models, and records to be tailored towards a particular convention proposed/enforced by shacl-vue.
jsheunis commented 2025-08-23 19:06:56 +00:00 (Migrated from github.com)

It sounds like being able to specify via config which slot values to use, and how to combine them, in order to generate a description for a given instance is what will be useful here. IOW, the same as what is currently supported for the display label. Deciding how general this feature should be is the difficulty here, as also alluded to in the comments of https://github.com/psychoinformatics-de/shacl-vue/issues/168. My feeling is that we should decide on a set of general record attributes that users would want to be able to see for any instance, and then support their generation via config-driven string serialization. The ones that we have already identified are: display label, description, note. I think these are different enough to warrant having distinct viewing options for them, per instance. And then each of them will have a config option to allow them to be generated from various slot values of that instance.

We could also allow the config to specify some logic, for priority decisions. E.g. for display label first use skos:prefLabel if available, otherwise use (hypothetically) {flatsocial:family_name}, {flatsocial:given_name}. For description use dlthings:description, otherwise (insert lower priority options here). Etc. In this way even the current process for using skos:prefLabel as the display label can be generlized more, since it is currently hardcoded in shacl-vue.

WDYT?

It sounds like being able to specify via config which slot values to use, and how to combine them, in order to generate a `description` for a given instance is what will be useful here. IOW, the same as what is currently supported for the `display label`. Deciding how general this feature should be is the difficulty here, as also alluded to in the comments of https://github.com/psychoinformatics-de/shacl-vue/issues/168. My feeling is that we should decide on a set of general record attributes that users would want to be able to see for any instance, and then support their generation via config-driven string serialization. The ones that we have already identified are: `display label`, `description`, `note`. I think these are different enough to warrant having distinct viewing options for them, per instance. And then each of them will have a config option to allow them to be generated from various slot values of that instance. We could also allow the config to specify some logic, for priority decisions. E.g. for `display label` first use `skos:prefLabel` if available, otherwise use (hypothetically) `{flatsocial:family_name}, {flatsocial:given_name}`. For `description` use `dlthings:description`, otherwise _(insert lower priority options here)_. Etc. In this way even the current process for using `skos:prefLabel` as the `display label` can be generlized more, since it is currently hardcoded in shacl-vue. WDYT?
mih commented 2025-08-24 05:48:14 +00:00 (Migrated from github.com)

Yes, I think, independent of an employed schema, there should be a definition of the structures that shacl-vue can display for an item (label, description, note). And for those structural elements it should be possible to define what information is used from any item for these elements.

Sensible defaults are what we have

  • label: skos:prefLabel
  • description: dcterms:description
  • note: skos:note

It would be good to have a simple syntax that can express both composition (sourcing from multiple properties) and fallback (when a preferred source is not present). Here are a few thoughts (not claiming originality or suitability).

Composition is always used, so using prefLabel would be

"{skos:prefLabel}"

and adding information is just about using more placeholders

"{skos:prefLabel} ({dcterms:title})"

Fallback could be implemented using nested placeholders

"{skos:prefLabel{{schema:name}}}"

and each nested placeholder is a fully featured declaration, just like the outermost string

"{skos:prefLabel{{schema:name} ({schema:legalName})}}"

fallback nesting could be arbitrarily deep

"{skos:prefLabel{{schema:name{{dcterms:title}}}}}"

(we could think about replacing the fallback parenthesis with something other thing what is used for placeholder wrapping, but probably something that could not occur unescaped in an IRI).

Yes, I think, independent of an employed schema, there should be a definition of the structures that shacl-vue can display for an item (label, description, note). And for those structural elements it should be possible to define what information is used from any item for these elements. Sensible defaults are what we have - label: `skos:prefLabel` - description: `dcterms:description` - note: `skos:note` It would be good to have a simple syntax that can express both composition (sourcing from multiple properties) and fallback (when a preferred source is not present). Here are a few thoughts (not claiming originality or suitability). Composition is always used, so using `prefLabel` would be ``` "{skos:prefLabel}" ``` and adding information is just about using more placeholders ``` "{skos:prefLabel} ({dcterms:title})" ``` Fallback could be implemented using nested placeholders ``` "{skos:prefLabel{{schema:name}}}" ``` and each nested placeholder is a fully featured declaration, just like the outermost string ``` "{skos:prefLabel{{schema:name} ({schema:legalName})}}" ``` fallback nesting could be arbitrarily deep ``` "{skos:prefLabel{{schema:name{{dcterms:title}}}}}" ``` (we could think about replacing the fallback parenthesis with something other thing what is used for placeholder wrapping, but probably something that could not occur unescaped in an IRI).
jsheunis commented 2025-08-25 12:26:10 +00:00 (Migrated from github.com)

I like this, and also in favor of changing the fallback symbol to something else to make it easier for humans to read/construct, e.g.

"{skos:prefLabel#{schema:name}#}"
"{skos:prefLabel#{schema:name#{dcterms:title}#}#}"

Actually, looking at this again I'm not sure if I find the second line easier to read than when curly brackets were used...

Something elsse: since github.com/psychoinformatics-de/shacl-vue@1bfcece41c introduced the editor_config option, which

allows component-specific parameters to be passed to name-identified components. Such parameters allow the customization of behavior or display in shacl-vue components. The object has the exact name of any editor component as its keys, and values are key-value parameter pairs that should feed into the associated editor components

it makes sense to me to move these new planned options into the editor_config, for example:

{
    ...
    "editor_config": {
        "W3CISO8601YearEditor": {
            "yearStart": 1925,
            "yearEnd": 2025
        },
        "W3CISO8601YearMonthEditor": {
            "yearStart": 1990,
            "yearEnd": 2025
        },
        "InstancesSelectEditor": {
            "autogenerate": {
                "trr379cps:City": {
                    "label": "{trr379cps:name}",
                    "description": "",
                    "note": ""
                },
            }
        }
    },
    ...
}

I am still debating whether the class IRIs should be the main keys of the autogenerate object, or whether to swap it around with label, description, and note (which would then each have class IRIs as keys).

I like this, and also in favor of changing the fallback symbol to something else to make it easier for humans to read/construct, e.g. ``` "{skos:prefLabel#{schema:name}#}" "{skos:prefLabel#{schema:name#{dcterms:title}#}#}" ``` Actually, looking at this again I'm not sure if I find the second line easier to read than when curly brackets were used... Something elsse: since https://github.com/psychoinformatics-de/shacl-vue/commit/1bfcece41c48b4e55673e0ad1f14f731dee20ba1 introduced the `editor_config` option, which > allows component-specific parameters to be passed to name-identified components. Such parameters allow the customization of behavior or display in `shacl-vue` components. The object has the exact name of any editor component as its keys, and values are key-value parameter pairs that should feed into the associated editor components it makes sense to me to move these new planned options into the `editor_config`, for example: ``` { ... "editor_config": { "W3CISO8601YearEditor": { "yearStart": 1925, "yearEnd": 2025 }, "W3CISO8601YearMonthEditor": { "yearStart": 1990, "yearEnd": 2025 }, "InstancesSelectEditor": { "autogenerate": { "trr379cps:City": { "label": "{trr379cps:name}", "description": "", "note": "" }, } } }, ... } ``` I am still debating whether the class IRIs should be the main keys of the `autogenerate` object, or whether to swap it around with `label`, `description`, and `note` (which would then each have class IRIs as keys).
jsheunis commented 2025-08-25 13:59:48 +00:00 (Migrated from github.com)

Another option would be to separate default/fallback options by using an array of options, ordered by priority, e.g.:

"{skos:prefLabel{{schema:name{{dcterms:title}}}}}"

would become:

    [
        "{skos:prefLabel}",
        "{schema:name}",
        "{dcterms:title}"
    ]

It's more lines, but I prefer the fact that it's cleaner and clearer.

And another way that can be used to configure defaults for all classes, in addition to the above per class, is to define a default config:

{
    ...
    "editor_config": {
        "W3CISO8601YearEditor": {
            "yearStart": 1925,
            "yearEnd": 2025
        },
        "W3CISO8601YearMonthEditor": {
            "yearStart": 1990,
            "yearEnd": 2025
        },
        "InstancesSelectEditor": {
            "autogenerate": {
                "trr379cps:City": {
                    "label": "{trr379cps:name}",
                    "description": "",
                    "note": ""
                },
                "default": {
                    "label": "{skos:prefLabel}",
                    "description": "{dcterms:description}",
                    "note": "{skos:note}"
                }
            }
        }
    },
    ...
}
Another option would be to separate default/fallback options by using an array of options, ordered by priority, e.g.: ``` "{skos:prefLabel{{schema:name{{dcterms:title}}}}}" ``` would become: ``` [ "{skos:prefLabel}", "{schema:name}", "{dcterms:title}" ] ``` It's more lines, but I prefer the fact that it's cleaner and clearer. And another way that can be used to configure defaults for all classes, in addition to the above per class, is to define a default config: ``` { ... "editor_config": { "W3CISO8601YearEditor": { "yearStart": 1925, "yearEnd": 2025 }, "W3CISO8601YearMonthEditor": { "yearStart": 1990, "yearEnd": 2025 }, "InstancesSelectEditor": { "autogenerate": { "trr379cps:City": { "label": "{trr379cps:name}", "description": "", "note": "" }, "default": { "label": "{skos:prefLabel}", "description": "{dcterms:description}", "note": "{skos:note}" } } } }, ... } ```
mih commented 2025-08-25 19:34:29 +00:00 (Migrated from github.com)

I think the list-based prioritization would work (well), if the pattern is simple (e.g., one property each) and not so much for compound strings.

Another syntax aspect that would be nice to have is a multivalue (ie. list) item property match. Use case: pick the one identifier from the set of available ones that is an ISSN (schema_agency)

I think the list-based prioritization would work (well), if the pattern is simple (e.g., one property each) and not so much for compound strings. Another syntax aspect that would be nice to have is a multivalue (ie. list) item property match. Use case: pick the one identifier from the set of available ones that is an ISSN (schema_agency)
jsheunis commented 2025-08-25 21:21:07 +00:00 (Migrated from github.com)

I can't currently see the challenge when using compound string patterns with the list-based approach. E.g. for the DFG survey application we could have have (after combining default templates and configured templates, which is something that the code will do):

{
    "autogenerate": {
        "trr379cps:City": {
            "label": [
                "{trr379cps:name}",
                "{skos:prefLabel}"
            ],
            "description": [
                "{dcterms:description}"
            ],
            "note": [
                "{skos:note}"
            ]
        },
        "trr379cps:ConsortiumParticipation": {
            "label": [
                "{trr379cps:participation_start_date}-{trr379cps:participation_end_date} ({trr379cps:status_group})",
                "{skos:prefLabel}"
            ],
            "description": [
                "{dcterms:description}"
            ],
            "note": [
                "{skos:note}"
            ]
        }
    }
}

One thing that still needs to be decided is how to handle missing values in a template. Two options that I can think of are:

  • skip the whole template if any value is missing, go on to the next template in the priority list
  • replace missing values with a placeholder e.g. ?

The problem with this: what do we do if the next (and the next) template in the priority list is skipped? We might want to go back to a higher priority template with a partial match. Perhaps it's better explained with the use case above: if a trr379cps:ConsortiumParticipation record does not have a trr379cps:participation_end_date we might say the label should be the skos:prefLabel. But if there is no skos:prefLabel, should the label then be {trr379cps:participation_start_date}-{trr379cps:participation_end_date} ({trr379cps:status_group}) with the trr379cps:participation_end_date replaced with a default missing value placeholder? I'm leaning towards this approach, i.e. "go down the priority list, unless nothing is found then go again from the top and use missing value placeholders".

I can't currently see the challenge when using compound string patterns with the list-based approach. E.g. for the DFG survey application we could have have (after combining default templates and configured templates, which is something that the code will do): ``` { "autogenerate": { "trr379cps:City": { "label": [ "{trr379cps:name}", "{skos:prefLabel}" ], "description": [ "{dcterms:description}" ], "note": [ "{skos:note}" ] }, "trr379cps:ConsortiumParticipation": { "label": [ "{trr379cps:participation_start_date}-{trr379cps:participation_end_date} ({trr379cps:status_group})", "{skos:prefLabel}" ], "description": [ "{dcterms:description}" ], "note": [ "{skos:note}" ] } } } ``` One thing that still needs to be decided is how to handle missing values in a template. Two options that I can think of are: - skip the whole template if any value is missing, go on to the next template in the priority list - replace missing values with a placeholder e.g. `?` The problem with this: what do we do if the next (and the next) template in the priority list is skipped? We might want to go back to a higher priority template with a partial match. Perhaps it's better explained with the use case above: if a `trr379cps:ConsortiumParticipation` record does not have a `trr379cps:participation_end_date` we might say the label should be the `skos:prefLabel`. But if there is no `skos:prefLabel`, should the label then be `{trr379cps:participation_start_date}-{trr379cps:participation_end_date} ({trr379cps:status_group})` with the `trr379cps:participation_end_date` replaced with a default missing value placeholder? I'm leaning towards this approach, i.e. "go down the priority list, unless nothing is found then go again from the top and use missing value placeholders".
mih commented 2025-08-26 08:29:31 +00:00 (Migrated from github.com)

I can't currently see the challenge when using compound string patterns

The challenge is what you state as the issue in the second part of your post. There is one series of alternatives that are considered "whole". In my original proposal it would be more like a tree of possibilities. That should lead to a leaner specification.

re how to handle missing values in a template

jq supports a syntax that makes it skip records when a key is not around: append ? to the keyname. Or when the value is null, set a default by appending // <defaultvalue>.

Adopting such an approach would allow for users making such decisions, rather than enforcing an approach wholesale.

> I can't currently see the challenge when using compound string patterns The challenge is what you state as the issue in the second part of your post. There is one series of alternatives that are considered "whole". In my original proposal it would be more like a tree of possibilities. That should lead to a leaner specification. re how to handle missing values in a template `jq` supports a syntax that makes it skip records when a key is not around: append `?` to the keyname. Or when the value is `null`, set a default by appending ` // <defaultvalue>`. Adopting such an approach would allow for users making such decisions, rather than enforcing an approach wholesale.
jsheunis commented 2025-08-26 08:48:34 +00:00 (Migrated from github.com)

The challenge is what you state as the issue in the second part of your post. There is one series of alternatives that are considered "whole". In my original proposal it would be more like a tree of possibilities. That should lead to a leaner specification.

I still don't get what exactly the difference is between "one series of alternatives that are considered whole" and "a tree of possibilities", apart from the fact that one is an array of strings and the other is a single string with nested elements. From my POV the code will handle them similarly. But I also feel we don't need to put more time into clarifying this unnecessarily.

Regarding missing values, I understand your suggestion (replacing with the ?-appended keyname, and/or using // <defaultvalue>) as saying that we replace missing values and use that "element" for the display (i.e. not going the route that I suggested of using a different "element").

> The challenge is what you state as the issue in the second part of your post. There is one series of alternatives that are considered "whole". In my original proposal it would be more like a tree of possibilities. That should lead to a leaner specification. I still don't get what exactly the difference is between "one series of alternatives that are considered whole" and "a tree of possibilities", apart from the fact that one is an array of strings and the other is a single string with nested elements. From my POV the code will handle them similarly. But I also feel we don't need to put more time into clarifying this unnecessarily. Regarding missing values, I understand your suggestion (replacing with the `?`-appended keyname, and/or using `// <defaultvalue>`) as saying that we replace missing values and use that "element" for the display (i.e. not going the route that I suggested of using a different "element").
mih commented 2025-08-26 09:28:21 +00:00 (Migrated from github.com)

Attempt to illustrate the difference:

One string, comprising two components, each with one fallback

"{a{b}} {c{d}}"

If a is not available, b will take its place. If c is not around, d is used.

In a "list" approach, a pattern must be rejected wholesale. To achieve the same, I'd have to use:

[
  "{a} {c}",
  "{b} {c}", # allowing for `a` to fail
  "{a} {d}", # but also allowing for `c` to fail
  "{b} {d}", # but also allowing for both to fail
]

With more fallbacks, the list becomes a lot longer in a combinatorial fashion.

Attempt to illustrate the difference: One string, comprising two components, each with one fallback ```json "{a{b}} {c{d}}" ``` If `a` is not available, `b` will take its place. If `c` is not around, `d` is used. In a "list" approach, a pattern must be rejected wholesale. To achieve the same, I'd have to use: ```json [ "{a} {c}", "{b} {c}", # allowing for `a` to fail "{a} {d}", # but also allowing for `c` to fail "{b} {d}", # but also allowing for both to fail ] ``` With more fallbacks, the list becomes a lot longer in a combinatorial fashion.
jsheunis commented 2025-08-27 20:54:36 +00:00 (Migrated from github.com)

I've come back to this after a day or so. I am still struggling to get the complete spec structured into my head in such a way that I can construct an algorithm that consistently parses a compliant template correctly.

This is mainly just a WIP comment from my strained brain... I'll get there...

I've come back to this after a day or so. I am still struggling to get the complete spec structured into my head in such a way that I can construct an algorithm that consistently parses a compliant template correctly. This is mainly just a WIP comment from my strained brain... I'll get there...
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
orinoco/shacl-vue#177
No description provided.