Problem
Query results sometimes have fields that hold multiple values, typically as a single string of space-separated URIs (or a separator chosen by the query author via group_concat). For example, get-3pff-events returns Facilitators as one literal such as:
https://orcid.org/0009-0003-5409-652X https://orcid.org/0000-0003-1062-5576
Today the binding system in <nanopub-list>, <nanopub-table> (now also with <template> support via #3 / #4), and <nanopub-item> is strictly single-value: data-bind sets textContent, data-bind-[attr] sets one attribute, data-bind-html sets innerHTML. There's no way to say "render one <a> per token in this field" without the author either:
- reshaping the query to emit pre-built HTML (
<a href=…>…</a>) and binding with data-bind-html — leaks presentation into the query and depends on DOMPurify sanitisation to keep working; or
- post-processing the DOM with a custom script — one-off hack per page.
Proposal
Add a list-iteration binding that clones a template fragment once per token in a field. Two reasonable shapes:
(a) Nested-template form — most expressive:
<td>
<template data-bind-each="Facilitators" data-separator=" ">
<a data-bind-href="." data-bind="."></a>
</template>
</td>
data-bind-each="Field" on a <template> element iterates tokens of row[Field] split by data-separator (default a whitespace regex), clones the template content per token, and makes the current token available as "." to the existing data-bind* directives (so data-bind-href="." sets the href to the token and data-bind="." sets the text to the token). Other fields from the parent row remain accessible by name, allowing per-token markup to also reference row-level values.
(b) Shorthand form on a single element — cheaper but less flexible:
<td>
<a data-bind-each-href="Facilitators" data-bind-each="Facilitators"></a>
</td>
…where the element is cloned per token and the -each-* bindings take the token as the value. This covers the common case (a flat list of links) without a nested template, but can't express richer per-token markup.
(a) subsumes (b), so (a) is probably the right target. (b) could be added as syntactic sugar later if demand exists.
Bonus
Pairs nicely with the ?things_multi_iri / ?things_label_multi convention on the query side (paired whitespace-separated URIs and newline-separated labels): data-bind-each could accept a sibling label field so that each cloned token exposes both its IRI and its human label to bindings, e.g.
<template data-bind-each="things_multi_iri" data-bind-each-label="things_label_multi">
<a data-bind-href="." data-bind=".label"></a>
</template>
Workaround today
Variant queries that pre-emit HTML strings and bind via data-bind-html. Works (DOMPurify keeps it safe) but couples presentation to the query. Example of this workaround in the wild: https://w3id.org/np/RAGv30LZ_1y4y_yPpIjpheQiRAWlLFzYk2QuqQPOSN7ZQ (get-3pff-events-html), a variant of get-3pff-events where Organizers/Facilitators/More_Info are pre-rendered as comma-separated <a> strings.
Problem
Query results sometimes have fields that hold multiple values, typically as a single string of space-separated URIs (or a separator chosen by the query author via
group_concat). For example,get-3pff-eventsreturnsFacilitatorsas one literal such as:Today the binding system in
<nanopub-list>,<nanopub-table>(now also with<template>support via #3 / #4), and<nanopub-item>is strictly single-value:data-bindsetstextContent,data-bind-[attr]sets one attribute,data-bind-htmlsetsinnerHTML. There's no way to say "render one<a>per token in this field" without the author either:<a href=…>…</a>) and binding withdata-bind-html— leaks presentation into the query and depends onDOMPurifysanitisation to keep working; orProposal
Add a list-iteration binding that clones a template fragment once per token in a field. Two reasonable shapes:
(a) Nested-template form — most expressive:
data-bind-each="Field"on a<template>element iterates tokens ofrow[Field]split bydata-separator(default a whitespace regex), clones the template content per token, and makes the current token available as"."to the existingdata-bind*directives (sodata-bind-href="."sets the href to the token anddata-bind="."sets the text to the token). Other fields from the parent row remain accessible by name, allowing per-token markup to also reference row-level values.(b) Shorthand form on a single element — cheaper but less flexible:
…where the element is cloned per token and the
-each-*bindings take the token as the value. This covers the common case (a flat list of links) without a nested template, but can't express richer per-token markup.(a) subsumes (b), so (a) is probably the right target. (b) could be added as syntactic sugar later if demand exists.
Bonus
Pairs nicely with the
?things_multi_iri/?things_label_multiconvention on the query side (paired whitespace-separated URIs and newline-separated labels):data-bind-eachcould accept a sibling label field so that each cloned token exposes both its IRI and its human label to bindings, e.g.Workaround today
Variant queries that pre-emit HTML strings and bind via
data-bind-html. Works (DOMPurify keeps it safe) but couples presentation to the query. Example of this workaround in the wild:https://w3id.org/np/RAGv30LZ_1y4y_yPpIjpheQiRAWlLFzYk2QuqQPOSN7ZQ(get-3pff-events-html), a variant ofget-3pff-eventswhere Organizers/Facilitators/More_Info are pre-rendered as comma-separated<a>strings.