Skip to content

Commit e1f57b6

Browse files
committed
Mirror the template sources clause.
Re-mirror the specification and changelog for new Section 6.3, re-copy the schema with its updated TemplateURL description, and regenerate the schema page embeds and its TemplateURL type reference.
1 parent 5edbd59 commit e1f57b6

4 files changed

Lines changed: 26 additions & 8 deletions

File tree

docs/changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
1414

1515
### Changed
1616

17+
- 2026-07-21 — New Section 6.3 (Template Sources) makes explicit that a template URL is an identifier first and a fetchable location only secondarily: clients MAY satisfy template URLs from any source — an application bundle, templates shipped with the page, a BFF-local store or template service, or a network fetch — all equally conforming, with the absolute URL (Section 5.4) as the template's identity and cache key. The Section 2 Template URL definition, Section 8 algorithm ("obtain" rather than "fetch" templates), Section 10 (its requirements now explicitly scoped to network retrieval), Section 15.2 client conformance, and the schema's TemplateURL description were aligned accordingly.
1718
- 2026-07-21 — All example template URLs consolidated onto a single host: `https://example.com/templates/...` replaces the `templates.example.com` subdomain throughout the specification and examples. Template URLs are identifiers first; a dedicated template host in every example suggested a deployment choice (a separate template server) that the protocol does not make.
1819
- 2026-07-21 — JSON Schemas upgraded from draft-07 to the [JSON Schema 2020-12](https://json-schema.org/specification-links#2020-12) dialect (`$schema` is now `https://json-schema.org/draft/2020-12/schema`). The schemas already used the post-draft-07 `$defs` keyword, so the declared dialect now matches the keywords in use; no other schema changes were needed. CI and local validation pass `--spec=draft2020` to ajv. The archived RVST schemas remain draft-07.
1920
- 2026-07-20 — Optional template metadata on view descriptors (new Section 3.6): an advisory `type` member (media type hint for the template resource) and an `integrity` member (W3C Subresource Integrity); an integrity mismatch is treated as a template fetch failure.

docs/schema.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ Because the schemas are hosted at their `$id` URLs, they can be referenced direc
6767
"TemplateURL": {
6868
"type": "string",
6969
"format": "uri",
70-
"description": "A URL identifying a template resource. MUST use HTTPS (loopback addresses excepted for local development)."
70+
"description": "A URL identifying a template. The URL is an identifier first — which source supplies the template (app bundle, page, BFF-local store, network fetch) is deployment-specific and outside the protocol. Network retrieval MUST use HTTPS (loopback addresses excepted for local development)."
7171
},
7272

7373
"Slots": {
@@ -193,7 +193,7 @@ The core type. Identifies a root template and optionally declares slot assignmen
193193

194194
### TemplateURL
195195

196-
A URI string (`format: "uri"`) identifying a template resource. MUST use HTTPS in production.
196+
A URI string (`format: "uri"`) identifying a template. The URL is an identifier first — which source supplies the template (app bundle, page-shipped templates, BFF-local store, network fetch) is deployment-specific and outside the protocol (Specification Section 6.3). Network retrieval MUST use HTTPS in production.
197197

198198
### Slots
199199

docs/schemas/vdp.v0-1.schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"TemplateURL": {
5454
"type": "string",
5555
"format": "uri",
56-
"description": "A URL identifying a template resource. MUST use HTTPS (loopback addresses excepted for local development)."
56+
"description": "A URL identifying a template. The URL is an identifier first — which source supplies the template (app bundle, page, BFF-local store, network fetch) is deployment-specific and outside the protocol. Network retrieval MUST use HTTPS (loopback addresses excepted for local development)."
5757
},
5858

5959
"Slots": {

docs/specification.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ REST APIs return structured data (JSON, XML) that carries no presentation inform
2525
## 2. Terminology
2626

2727
- **View Descriptor**: A JSON object that describes a template tree — a root template URL and its slot assignments.
28-
- **Template URL**: A URL identifying a template resource. The URL MUST resolve to a renderable template in the client's rendering framework.
28+
- **Template URL**: A URL identifying a template. The URL is an *identifier* first — a stable name and namespace for the template, and the key under which the client caches it — and a fetchable location only secondarily (Section 6.3). Through whatever source the deployment uses, it MUST resolve to a renderable template in the client's rendering framework.
2929
- **Slot**: A named insertion point in a template where a sub-template can be composed. Slot names correspond to the template's own insertion point identifiers (e.g., Qute's `{#insert slotName}`).
3030
- **View Descriptor Resource**: A standalone JSON document containing a view descriptor, addressable by its own URL, cacheable independently of the data it describes.
3131
- **Static Composition**: Composition written directly into a template's source — for example, a layout that always includes its `_head` partial. VDP does not describe static composition; it is internal to the template.
@@ -438,6 +438,21 @@ VDP is agnostic to the template language. However, a template used with VDP MUST
438438

439439
Not every insertion point in a template needs to appear in the view descriptor. Templates commonly include partials that never change — a shared `_head`, a footer — and those stay hardcoded in the template (static composition, Section 2). Only slots whose content varies per API response belong in the view descriptor (dynamic composition).
440440

441+
### 6.3 Template Sources
442+
443+
A template URL names *which* template renders a slot. Deliberately, VDP does not define where the template's source text comes from: the URL is an identifier first — a stable name and namespace for the template, much like a package import path — and the key under which the client caches it. How a client turns that identifier into template source text is a deployment decision, outside the protocol.
444+
445+
A client MAY satisfy a template URL from any source, including:
446+
447+
- templates bundled into the application package (typical for mobile and desktop clients);
448+
- templates shipped with the page itself (for browsers — e.g., `<template>` elements delivered with the initial HTML);
449+
- a store local to the BFF, or a dedicated template service;
450+
- a network fetch of the template URL itself.
451+
452+
All of these are equally conforming. Whatever the source, the client MUST select templates by the absolute URL produced by the Section 5.4 resolution rules — the URL is the template's identity, so a template satisfied from a local source is indistinguishable, to the rest of the resolution algorithm, from a fetch whose cache was already warm (Section 5.2). Fetching the URL over the network is the interoperable default when no local source provides the template, and every network retrieval is subject to Section 10.
453+
454+
The `integrity` member (Section 3.6) authenticates template content obtained from outside the client's trust boundary. A client MAY skip integrity verification for templates satisfied from its own bundle; when integrity metadata is present, it MUST verify any template it fetches over the network (Section 3.6).
455+
441456
## 7. Examples
442457

443458
### 7.1 Login Page (Simple, No Slots)
@@ -573,11 +588,11 @@ This is the pattern used by **quarkus-pha**: Quarkus acts as the BFF, fetching d
573588

574589
1. **Extract view descriptor** from the response (check `_view`/`_views` body key, then `Link` header, then `View-Template` header).
575590
2. **Fetch the view descriptor** if it is a URL reference (cache as appropriate).
576-
3. **Fetch the root template** from the `template` URL, verifying `integrity` when present (Section 3.6).
591+
3. **Obtain the root template** identified by the `template` URL, from any Section 6.3 source, verifying `integrity` when present (Section 3.6).
577592
4. **Identify slot insertion points** in the template.
578593
5. **For each slot** declared in the view descriptor:
579594
a. If the slot value is a descriptor reference (Section 3.7), fetch the referenced view descriptor resource and substitute the result; on failure or cycle, handle per Section 9.1.
580-
b. Fetch the sub-template from its `template` URL, verifying `integrity` when present.
595+
b. Obtain the sub-template identified by its `template` URL, verifying `integrity` when present.
581596
c. If the slot's view descriptor itself declares `slots`, repeat steps 3–5 for that descriptor.
582597
d. Insert the resolved sub-template into the slot.
583598
6. **Render** the composed template tree with the API response data.
@@ -629,6 +644,8 @@ Error handling follows the principle that a failure stays as local as possible:
629644

630645
## 10. Security Considerations
631646

647+
The requirements in this section govern templates and descriptors **retrieved over a network**. A client that satisfies template URLs from a source inside its own trust boundary (Section 6.3) — an application bundle, templates shipped with the page, a BFF-local store — need not apply them to those templates; any retrieval that does cross the network remains subject to them in full.
648+
632649
- **Template URL validation**: Clients MUST validate template URLs against an allowlist of trusted URL prefixes. Rendering arbitrary templates from untrusted sources is a code injection risk. The allowlist is determined by the first available source below:
633650
1. **Local configuration** — an allowlist configured in the client or its deployment. When present, it takes precedence over anything the server advertises.
634651
2. **Discovery document** — the `trustedTemplateUrls` member of the API's discovery document (Section 13.2), when one is available.
@@ -640,7 +657,7 @@ Error handling follows the principle that a failure stays as local as possible:
640657
- **CORS**: Template resources served cross-origin MUST include appropriate CORS headers.
641658
- **Content Security Policy**: Browser clients fetching templates at runtime SHOULD include template origins in the `connect-src` CSP directive. `script-src` or `style-src` apply only where templates are loaded as executable scripts or stylesheets.
642659
- **Template sandboxing**: Clients SHOULD render templates in a sandboxed context to prevent template injection attacks.
643-
- **HTTPS**: Template URLs MUST use HTTPS. Clients SHOULD reject `http:` template URLs, with an exception permitted for loopback addresses during local development.
660+
- **HTTPS**: Templates retrieved over a network MUST be retrieved via HTTPS. Clients SHOULD reject fetching `http:` template URLs, with an exception permitted for loopback addresses during local development.
644661

645662
## 11. Relationship to Existing Standards
646663

@@ -875,7 +892,7 @@ Software that consumes view descriptors and resolves template trees. A conformin
875892
- MUST extract view descriptors using the precedence order of Section 4.4.
876893
- MUST implement the resolution algorithm of Section 8, including a recursion depth limit and reference cycle handling.
877894
- MUST implement the error handling behavior of Section 9 — in particular, preferring partial rendering over total failure.
878-
- MUST validate template URLs against the allowlist source chain of Section 10 and reject non-HTTPS template URLs outside local development.
895+
- MUST apply the Section 10 requirements — the allowlist source chain, HTTPS — to every template it retrieves over a network; templates satisfied from a source inside its own trust boundary (Section 6.3) are exempt.
879896
- MUST reject invalid view descriptors (Section 9.3) rather than attempting partial interpretation of them.
880897
- SHOULD verify template `integrity` metadata when present (Section 3.6).
881898
- MUST ignore unrecognized members of the discovery document (Section 13.2).

0 commit comments

Comments
 (0)