Skip to content

feat: support RootNanopubPlaceholder in templates#453

Merged
tkuhn merged 5 commits intomasterfrom
add-root-nanopub-placeholder
Apr 24, 2026
Merged

feat: support RootNanopubPlaceholder in templates#453
tkuhn merged 5 commits intomasterfrom
add-root-nanopub-placeholder

Conversation

@tkuhn
Copy link
Copy Markdown
Contributor

@tkuhn tkuhn commented Apr 24, 2026

Summary

  • Adds handling for nt:RootNanopubPlaceholder (shipped in nanopub-java 1.87.0, vocab PR Nanopublication/nanopub-java#67)
  • Renders as read-only; preserves the prior root value across supersede/derive (leveraging the existing ValueFiller sentinel path in ReadonlyItem.unifyWith), and defaults to the nanopub being published otherwise
  • ReadonlyItem label now renders the local:nanopub/local:assertion sentinels as "this nanopublication"/"this assertion" (previously showed raw local:… strings)

Closes #452

Test plan

  • mvn compile clean
  • mvn test — all 666 tests pass
  • Manual: create a template with a RootNanopubPlaceholder and check fresh publish shows "this nanopublication"
  • Manual: supersede a nanopub whose assertion points the placeholder at itself — new nanopub's assertion should point at the old one
  • Manual: supersede a nanopub whose placeholder points at a third nanopub — value should be preserved verbatim

🤖 Generated with Claude Code

tkuhn and others added 5 commits April 24, 2026 09:41
Renders as a read-only value that preserves the prior root on
supersede/derive (via the existing ValueFiller sentinel path in
ReadonlyItem.unifyWith) and defaults to the nanopub being published
otherwise.

Closes #452

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Templates declare the slot with a custom IRI typed as
nt:RootNanopubPlaceholder (e.g. sub:rootNanopub a nt:RootNanopubPlaceholder),
so the placeholder identity is the slot IRI, not the class IRI.
Switch the ValueItem dispatch and TemplateContext.processValue resolution
to template.isRootNanopubPlaceholder(iri), and seed the sentinel default
in ReadonlyItem where the slot IRI is known.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
In PublishForm, the TemplateContexts for assertion/provenance/pubinfo
are created without an existingNanopub, since the form is editable
(isReadOnly = existingNanopub != null). But ReadonlyItem relied on
context.getExistingNanopub() to resolve the local:nanopub sentinel to
the filled-from nanopub's URI, so superseding a nanopub whose
RootNanopubPlaceholder pointed at itself failed unification — the
validator rejected the unresolved "local:nanopub" string.

Add TemplateContext.fillSource (and getReferenceNanopub() which prefers
existingNanopub and falls back to fillSource). PublishForm sets it
from fillNp/improveNp before initStatements so ReadonlyItem's sentinel
resolution, the RootNanopubPlaceholder default-seed skip, and the
processValue resolution all see the actual nanopub.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
In supersede/derive mode, a ReadonlyItem resolves the local:nanopub
sentinel to the fillSource's URI during unification — but the display
label was then reading that URI back and calling it "this
nanopublication", even though the fillSource is a *prior* nanopub, not
the one being published.

Tighten isNanopubValue/isAssertionValue to only treat matches against
context.getExistingNanopub() as "this" (the nanopub being viewed).
Fresh-publish's sentinel label is unaffected. Supersede/derive now
falls through to the regular label/URI rendering so the prior
nanopub's identity is visible.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
TemplateTest: verify isRootNanopubPlaceholder/isPlaceholder for a
template that types a slot as nt:RootNanopubPlaceholder, and confirm
unrelated slots are not matched.

TemplateContextTest (new): cover the fillSource accessors and
getReferenceNanopub fallback, and exercise processValue for the
placeholder in the three resolution paths — fresh publish (sentinel ->
targetNamespace), supersede with fillSource (sentinel -> existing np
URI), explicit prior value preserved, and empty-model default.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tkuhn tkuhn merged commit 16678cc into master Apr 24, 2026
8 checks passed
@tkuhn tkuhn deleted the add-root-nanopub-placeholder branch April 24, 2026 08:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support RootNanopubPlaceholder

1 participant