w3c / w3c/json-ld-syntax

New feature: `@template`

Open
#362 12 comments 6 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

defer-future-version
Dominant language
HTML
Stars
139
Forks
23
PR merge metrics
No merged PRs in 30d

Description

Here is a feature that I discussed with some colleagues, and that we really would like to see in a future version of JSON-LD.

Use cases

Consider the following example JSON, as would be produced by a Web API

{
    "id": 1234,
    "name": "Alice",
    "bday": "1987-04-01",
    "height": 168
}

We know from the API documentation that id is a unique local identifier for this entity, whose corresponding IRI is http://example.org/users/1234. Unfortunately, there are two problems with the current spec:

  • a property mapped to @id accepts only strings;
  • even if 1234 was replaced with "1234", it would be resolved against the @base of the context; setting the base to http://example.org/users/ for the sole purpose of this property would not always be appropriate.

We also know from the API documentation that height is expressed in centimetres. We would like to map it using the cdt:ucum datatype, i.e. into "168 cm"^^cdt:ucum".

Proposed solution

  • add a @template keyword that can appear in a term definition; the value is a string containing a single placeholder {}, for example http://example.org/users/{} or {} cm;
  • during expansion, and before any other step, the value of a property matching this term definition is replaced by the value of the template, replacing the placeholder with the canonical representation of the value;
  • during compaction, a term definition with a @template attribute is usable only if the @id or @value "matches" the template. Its value is then replaced by extracting the substring corresponding to the placeholder.

An example context for the use-case above would then look like

{"@context": {
    "id": {
        "@id": "@id",
        "@template": "http://example.org/users/{}"
    },
    "height": {
        "@id": "http://example.org/ont/height",
        "@type": "https://ci.mines-stetienne.fr/lindt/v3/custom_datatypes#ucum",
        "@template": "{} cm"
    }
}}

Remaining issues

  • Is {} the best choice for the placeholder?
  • Do we need a way to escape the placeholder in the template?
  • Do we want to allow some formatting options in the template (minimum number of digits, hexadecimal, ...) or more complex transformation (computation...)? I suggest we keep things simple.
  • Do we reserve the use of @template for number values, or do we also use it with strings? There would possibly be useful use-cases with strings as well, but then compaction would have to decide whether to produce a string or a number (at least when the value can be parsed as a number)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The issue does not name implementation files, tests, or an entry point. Start by reviewing the proposed @template behavior and the four remaining design questions, then identify where the JSON-LD specification defines expansion and compaction. Done means the design is resolved and the specification changes and corresponding tests clearly define the supported template behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
json
Domain
documentation
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.