Skip to content

Commit

Permalink
Fix #666
Browse files Browse the repository at this point in the history
  • Loading branch information
tfrancart committed Nov 2, 2024
1 parent e64e964 commit 9ead238
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 66 deletions.
10 changes: 6 additions & 4 deletions docs/OWL-based-configuration-datasources.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
_[Home](index.html) > OWL-based configuration Datasources_
_[Home](index.html) > Datasources_

# Datasources

## Datasources basics

As indicated in the [[OWL-based configuration]] reference, lists and autocomplete properties in Sparnatural require a [`ds:datasource`](http://data.sparna.fr/ontologies/sparnatural-config-datasources#datasource) annotation to populate respectively the list of values or the values proposed by autocompletion. In its simplest and most common form a datasource is basically a SPARQL query that returns the expected columns to be used to populate the list/autocomplete values.
Lists and autocomplete properties in Sparnatural can be associated to a [`ds:datasource`](http://data.sparna.fr/ontologies/sparnatural-config-datasources#datasource) annotation to populate respectively the list of values or the values proposed by autocompletion. In its simplest and most common form a datasource is a SPARQL query that returns the expected columns to be used to populate the list/autocomplete values.

The datasource annotation configuration can be either:

Expand Down Expand Up @@ -120,7 +120,9 @@ To use the range as a criteria in the query and filter the list based on the typ

You can provide your own SPARQL queries to populate lists or autocomplete suggestions. To do so, attach a `queryString` data property assertion on your datasource object, holding the SPARQL query that should be used to populate the list/autocomplete.

**The SPARQL query MUST return 2 variables : `?uri` and `?label`, populated anyway you like.** Additionnally, since version 8.6.0, the query can return, optionnally, an extra `?group` variable, which will be used to generate `optgroup` sections in lists widgets, and will be used as hover tooltips in autocompletion lists. This is used to indicate the source endpoint of the result in cases of multiple endpoints.
**The SPARQL query MUST return 2 variables : `?uri` and `?label`, populated anyway you like.** Additionnally, the query can return, optionnally:
- an extra `?group` variable, which will be used to generate `optgroup` sections in lists widgets, and will be used as hover tooltips in autocompletion lists. This is used to indicate the source endpoint of the result in cases of multiple endpoints.
- an extra `?itemLabel` variable, which will be used, if present, as the label of the selected value; for exemple, `?label` can hold a count, like _"Italy (307)"_, while `?itemLabel` can be just _"Italy"_.

In this SPARQL query, the following replacements will happen:
- **`$domain`**, if present, will be replaced by the URI of the domain class;
Expand All @@ -136,7 +138,7 @@ Take a look at the preconfigured SPARQL queries in the [Sparnatural datasources
Here is an example of such a query: (note the use of the placeholder variables that will be replaced with the corresponding values):

```sparql
SELECT ?uri ?count (CONCAT(STR(?theLabel), ' (', STR(?count), ')') AS ?label)
SELECT ?uri ?count (CONCAT(STR(?theLabel), ' (', STR(?count), ')') AS ?label) (STR(?theLabel) AS ?itemLabel)
WHERE {
{
SELECT DISTINCT ?uri (COUNT(?domain) AS ?count)
Expand Down
22 changes: 11 additions & 11 deletions ontologies/sparnatural-config-datasources.owl
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ LIMIT 500</sparnatural-config-datasources:queryString>

<owl:NamedIndividual rdf:about="http://data.sparna.fr/ontologies/sparnatural-config-datasources#query_list_URI_count">
<rdf:type rdf:resource="http://data.sparna.fr/ontologies/sparnatural-config-datasources#SPARQLQuery"/>
<sparnatural-config-datasources:queryString>SELECT ?uri ?count (CONCAT(STR(?uri), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label)
<sparnatural-config-datasources:queryString>SELECT ?uri ?count (CONCAT(STR(?uri), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label) (STR(?uri) AS ?itemLabel)
WHERE {
{
SELECT DISTINCT ?uri (COUNT(?domain) AS ?count)
Expand Down Expand Up @@ -637,7 +637,7 @@ LIMIT 500</sparnatural-config-datasources:queryString>

<owl:NamedIndividual rdf:about="http://data.sparna.fr/ontologies/sparnatural-config-datasources#query_list_URI_or_literal_alpha_with_count">
<rdf:type rdf:resource="http://data.sparna.fr/ontologies/sparnatural-config-datasources#SPARQLQuery"/>
<sparnatural-config-datasources:queryString>SELECT DISTINCT ?value ?count (CONCAT(IF(isLiteral(?value) &amp;&amp; LANG(?value) != &apos;&apos; &amp;&amp; LANG(?value) != $lang,CONCAT(STR(?value), &quot; &lt;sup&gt;(&quot;,LANG(?value),&quot;)&lt;/sup&gt;&quot;),STR(?value)), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label)
<sparnatural-config-datasources:queryString>SELECT DISTINCT ?value ?count (CONCAT(IF(isLiteral(?value) &amp;&amp; LANG(?value) != &apos;&apos; &amp;&amp; LANG(?value) != $lang,CONCAT(STR(?value), &quot; &lt;sup&gt;(&quot;,LANG(?value),&quot;)&lt;/sup&gt;&quot;),STR(?value)), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label) (STR(?value) AS ?itemLabel)
WHERE {
{
SELECT DISTINCT ?value (COUNT(DISTINCT ?domain) AS ?count)
Expand Down Expand Up @@ -685,7 +685,7 @@ LIMIT 500</sparnatural-config-datasources:queryString>

<owl:NamedIndividual rdf:about="http://data.sparna.fr/ontologies/sparnatural-config-datasources#query_list_URI_or_literal_count">
<rdf:type rdf:resource="http://data.sparna.fr/ontologies/sparnatural-config-datasources#SPARQLQuery"/>
<sparnatural-config-datasources:queryString>SELECT ?value ?count (CONCAT(IF(isLiteral(?value) &amp;&amp; LANG(?value) != &apos;&apos; &amp;&amp; LANG(?value) != $lang,CONCAT(STR(?value), &quot; &lt;sup&gt;(&quot;,LANG(?value),&quot;)&lt;/sup&gt;&quot;),STR(?value)), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label)
<sparnatural-config-datasources:queryString>SELECT ?value ?count (CONCAT(IF(isLiteral(?value) &amp;&amp; LANG(?value) != &apos;&apos; &amp;&amp; LANG(?value) != $lang,CONCAT(STR(?value), &quot; &lt;sup&gt;(&quot;,LANG(?value),&quot;)&lt;/sup&gt;&quot;),STR(?value)), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label) (STR(?value) AS ?itemLabel)
WHERE {
{
SELECT DISTINCT ?value (COUNT(DISTINCT ?domain) AS ?count)
Expand Down Expand Up @@ -753,7 +753,7 @@ LIMIT 500</sparnatural-config-datasources:queryString>

<owl:NamedIndividual rdf:about="http://data.sparna.fr/ontologies/sparnatural-config-datasources#query_list_label_alpha_with_count">
<rdf:type rdf:resource="http://data.sparna.fr/ontologies/sparnatural-config-datasources#SPARQLQuery"/>
<sparnatural-config-datasources:queryString>SELECT ?uri ?count (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label)
<sparnatural-config-datasources:queryString>SELECT ?uri ?count (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label) (STR(?theLabel) AS ?itemLabel)
WHERE {
{
SELECT ?uri ?count ?theLabel
Expand Down Expand Up @@ -783,7 +783,7 @@ ORDER BY UCASE(?label)</sparnatural-config-datasources:queryString>

<owl:NamedIndividual rdf:about="http://data.sparna.fr/ontologies/sparnatural-config-datasources#query_list_label_count">
<rdf:type rdf:resource="http://data.sparna.fr/ontologies/sparnatural-config-datasources#SPARQLQuery"/>
<sparnatural-config-datasources:queryString>SELECT ?uri ?count (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label)
<sparnatural-config-datasources:queryString>SELECT ?uri ?count (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label) (STR(?theLabel) AS ?itemLabel)
WHERE {
{
SELECT ?uri ?count ?theLabel
Expand Down Expand Up @@ -833,7 +833,7 @@ LIMIT 500</sparnatural-config-datasources:queryString>

<owl:NamedIndividual rdf:about="http://data.sparna.fr/ontologies/sparnatural-config-datasources#query_list_label_with_range_alpha_with_count">
<rdf:type rdf:resource="http://data.sparna.fr/ontologies/sparnatural-config-datasources#SPARQLQuery"/>
<sparnatural-config-datasources:queryString>SELECT ?uri ?count (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label)
<sparnatural-config-datasources:queryString>SELECT ?uri ?count (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label) (STR(?theLabel) AS ?itemLabel)
WHERE {
{
SELECT ?uri ?count ?theLabel
Expand Down Expand Up @@ -865,7 +865,7 @@ ORDER BY UCASE(?label)</sparnatural-config-datasources:queryString>

<owl:NamedIndividual rdf:about="http://data.sparna.fr/ontologies/sparnatural-config-datasources#query_list_label_with_range_count">
<rdf:type rdf:resource="http://data.sparna.fr/ontologies/sparnatural-config-datasources#SPARQLQuery"/>
<sparnatural-config-datasources:queryString>SELECT ?uri ?count (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label)
<sparnatural-config-datasources:queryString>SELECT ?uri ?count (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label) (STR(?theLabel) AS ?itemLabel)
WHERE {
{
SELECT ?uri ?count ?theLabel
Expand Down Expand Up @@ -911,7 +911,7 @@ LIMIT 500</sparnatural-config-datasources:queryString>

<owl:NamedIndividual rdf:about="http://data.sparna.fr/ontologies/sparnatural-config-datasources#query_literal_list_alpha_with_count">
<rdf:type rdf:resource="http://data.sparna.fr/ontologies/sparnatural-config-datasources#SPARQLQuery"/>
<sparnatural-config-datasources:queryString>SELECT ?count (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label)
<sparnatural-config-datasources:queryString>SELECT ?count (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label) (STR(?theLabel) AS ?itemLabel)
WHERE {
{
SELECT DISTINCT ?count ?theLabel
Expand Down Expand Up @@ -939,7 +939,7 @@ ORDER BY UCASE(?label)</sparnatural-config-datasources:queryString>

<owl:NamedIndividual rdf:about="http://data.sparna.fr/ontologies/sparnatural-config-datasources#query_literal_list_count">
<rdf:type rdf:resource="http://data.sparna.fr/ontologies/sparnatural-config-datasources#SPARQLQuery"/>
<sparnatural-config-datasources:queryString>SELECT ?count (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label)
<sparnatural-config-datasources:queryString>SELECT ?count (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label) (STR(?theLabel) AS ?itemLabel)
WHERE {
{
SELECT DISTINCT ?count ?theLabel
Expand Down Expand Up @@ -1105,7 +1105,7 @@ ORDER BY UCASE(?label)</sparnatural-config-datasources:queryString>

<owl:NamedIndividual rdf:about="http://data.sparna.fr/ontologies/sparnatural-config-datasources#query_tree_children_with_count">
<rdf:type rdf:resource="http://data.sparna.fr/ontologies/sparnatural-config-datasources#SPARQLQuery"/>
<sparnatural-config-datasources:queryString>SELECT ?uri (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label) ?hasChildren ?count
<sparnatural-config-datasources:queryString>SELECT ?uri (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label) ?hasChildren ?count (STR(?theLabel) AS ?itemLabel)
WHERE {
{
SELECT DISTINCT ?uri ?theLabel ?hasChildren (COUNT(?x) AS ?count)
Expand Down Expand Up @@ -1166,7 +1166,7 @@ ORDER BY UCASE(?label)</sparnatural-config-datasources:queryString>

<owl:NamedIndividual rdf:about="http://data.sparna.fr/ontologies/sparnatural-config-datasources#query_tree_root_noparent_with_count">
<rdf:type rdf:resource="http://data.sparna.fr/ontologies/sparnatural-config-datasources#SPARQLQuery"/>
<sparnatural-config-datasources:queryString>SELECT ?uri (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label) ?hasChildren ?count
<sparnatural-config-datasources:queryString>SELECT ?uri (CONCAT(STR(?theLabel), &apos; (&apos;, STR(?count), &apos;)&apos;) AS ?label) ?hasChildren ?count (STR(?theLabel) AS ?itemLabel)
WHERE {
{
SELECT ?uri ?theLabel ?hasChildren (COUNT(?x) AS ?count)
Expand Down
16 changes: 11 additions & 5 deletions src/sparnatural/components/widgets/ListWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import "select2";
import "select2/dist/css/select2.css";
import SparqlFactory from "../../generators/sparql/SparqlFactory";
import EndClassGroup from "../builder-section/groupwrapper/criteriagroup/startendclassgroup/EndClassGroup";
import { ListDataProviderIfc, NoOpListDataProvider } from "./data/DataProviders";
import { ListDataProviderIfc, RdfTermDatasourceItem, NoOpListDataProvider } from "./data/DataProviders";
import { I18n } from "../../settings/I18n";
import { Term } from "@rdfjs/types/data-model";
import HTMLComponent from "../HtmlComponent";
Expand Down Expand Up @@ -69,7 +69,7 @@ export class ListWidget extends AbstractWidget {
${I18n.labels.ListWidgetNoItem}
</div>`);

let callback = (items:{term:RDFTerm;label:string;group?:string}[]) => {
let callback = (items:RdfTermDatasourceItem[]) => {

if (items.length > 0) {

Expand All @@ -79,16 +79,21 @@ export class ListWidget extends AbstractWidget {
if(groups.length == 1 && groups[0] == undefined) {
// no groups were defined at all
items.forEach(item => {
// select item label : either displayed label, or itemLabel if provided
let itemLabel = item.itemLabel?item.itemLabel:item.label;
this.selectHtml.append(
$("<option value='" + JSON.stringify(item.term) + "'>" + item.label + "</option>")
$("<option value='" + JSON.stringify(item.term) + "' data-itemLabel='"+itemLabel+"'>" + item.label + "</option>")
);
});
} else {
// we found some group, organise the list content with optgroup
groups.forEach(group => {
let html = "<optgroup label=\""+group+"\">";
items.filter(item => (item.group == group)).forEach(item => {
html += "<option value='" + JSON.stringify(item.term) + "'>" + item.label + "</option>";
// select item label : either displayed label, or itemLabel if provided
let itemLabel = item.itemLabel?item.itemLabel:item.label;

html += "<option value='" + JSON.stringify(item.term) + "' data-itemLabel='"+itemLabel+"'>" + item.label + "</option>";
});
html += "</optgroup>"
this.selectHtml.append($(html));
Expand All @@ -111,7 +116,8 @@ export class ListWidget extends AbstractWidget {
if (option.length > 1)
throw Error("List widget should allow only for one el to be selected!");

let listWidgetValue: WidgetValue = this.buildValue(option[0].value, option[0].label);
let itemLabel = option[0].getAttribute("data-itemLabel");
let listWidgetValue: WidgetValue = this.buildValue(option[0].value, itemLabel);
this.renderWidgetVal(listWidgetValue);
});

Expand Down
Loading

0 comments on commit 9ead238

Please sign in to comment.