Skip to content

feat(rest): add /api/v1/page/_render-sources endpoint to locate a page's render sources #36082

@fmontes

Description

@fmontes

Problem

No single call maps a rendered page to its source files. An agent fixing a page (a11y, content, layout) has to guess across folder/theme/container endpoints — a real session burned multiple calls on 404/500 just to list theme files — and can't tell which container/VTL produced a given part of the page.

Endpoint

GET /api/v1/page/_render-sources — references only (path + identifier), no content. Client reads sources via existing endpoints. Auth: any authenticated user (same as /page/render).

Params

Param Req Notes
path yes //host/.../index or plain /index
host_id no Default-host fallback
language_id no Default language
persona_id no Maps to WebKeys.CMS_PERSONA_PARAMETER. Applied to the projection
variantName no Applied to the projection
mode no WebKeys.PAGE_MODE_PARAMETER

Host: qualified pathhost_id → default. (No request-context host — agents have none.)

Response

{
  "page": { "identifier": "a9f3…", "uri": "/index", "languageId": 1 },
  "theme": {
    "id": "d7b0…", "name": "travel",
    "folderPath": "//demo.dotcms.com/application/themes/travel/",
    "vtls": [ { "path": "//…/header.vtl", "identifier": "a56e…" } ]
  },
  "containers": [
    { "containerId": "d71d…", "source": "DB",
      "contentTypes": [ { "contentTypeVar": "Activity", "onPage": true } ] },
    { "containerId": "//…/default/", "source": "FILE", "path": "//…/default/",
      "contentTypeVtls": [ { "contentTypeVar": "YouTube", "onPage": true,
        "path": "//…/YouTube.vtl", "identifier": "" } ] }
  ],
  "widgets": [ { "contentTypeVar": "VtlInclude", "title": "Recommended Events",
    "path": "//…/recommended-events.vtl", "identifier": "" } ]
}
  • source: DB → read code via GET /api/v1/containers/working?containerId=<id>&includeContentType=true
  • source: FILE → read VTL via GET /api/v2/assets
  • onPage = placed on page (from MultiTree under persona/variant) vs. merely renderable

Acceptance Criteria

  • Returns references only (path + identifier) — no file content, no container code
  • Params: path, host_id, language_id, persona_id, variantName, mode
  • Host resolution: qualified pathhost_id → default host
  • theme = { id, name, folderPath, vtls[] }
  • containers routed by source: DB{ containerId, contentTypes[] }; FILE{ containerId, path, contentTypeVtls[] }
  • onPage resolved from MultiTree under applied persona + variant (not a naive container list)
  • No duplicated logic — projects existing PageView/ContainerAPI/WebAsset.source/FileAssetContainer.getContainerStructuresAssets(); embeds no code, no file tree
  • OpenAPI description names the folder-listing endpoint for nested theme files: GET /api/v1/folder/sitename/{site}/uri/{uri}

Errors

  • Page not found / wrong language / unknown host → 404
  • No READ permission → 403
  • Missing/invalid path → 400

Tests

  • Integration: DB vs FILE container shapes; onPage under persona/variant; host resolution; error statuses
  • OpenAPI + Postman (happy + error paths)

Context

LOCATE step of the agent loop: SCAN → LOCATE (this) → READ/WRITE (#35928) → RE-SCAN.

Metadata

Metadata

Assignees

No one assigned
    No fields configured for Feature.

    Projects

    Status
    New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions