fix(loops): resolve custom media fields to URLs in loops - #300
Open
shadysamir wants to merge 1 commit into
Open
Conversation
A loop over a data table exposed only the built-in `featuredMedia` and
`firstImage` fields as resolved media URLs. Any user-defined `media`
field (e.g. a Client `logo`) was spread through raw, so a
`{currentEntry.<field>}` binding on an `img src` emitted the stored
media id instead of a URL. The browser then resolved that bare id
against the current path, so the image never loaded, on the canvas and
on the published site.
The loop source now resolves every `type:"media"` cell to its public
path generically, replacing the `featuredMedia`-only special case:
- Both page-slice queries select `data_tables.fields_json` to identify
which fields are media-typed.
- `collectMediaIds` gathers featured + all custom media ids into the
existing single batched resolve (no extra queries).
- `resolvedMediaOverlay` overwrites each media cell with its resolved
path in both row projections, applied right after the raw cells.
- Multi-value media fields (`allowMultiple`) flatten to the first
element for a scalar binding; a dangling id resolves to null instead
of the raw id.
Resolving media in the loop source runs before both token paths, so the
binding and string-token resolvers need no changes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
shadysamir
force-pushed
the
fix/loop-media-field-resolution
branch
from
July 28, 2026 18:26
9170a2a to
5a1dba6
Compare
There was a problem hiding this comment.
Pull request overview
This PR fixes data.rows loop rendering so all media-typed table fields (not just the built-in featuredMedia / firstImage) are resolved from stored media asset IDs to public URLs before bindings are evaluated. This aligns loop output with the authoring-time format: "media" hint so {currentEntry.<field>} can be used directly in img src on both the editor canvas and published output.
Changes:
- Fetch
data_tables.fields_jsonin both post-type and data-kind row queries to identify which fields aretype: "media". - Batch-resolve media IDs for featured media + all custom media fields, then overlay resolved URLs onto the row’s
fieldsmap. - Add
readMediaCellIdshelper and new tests covering single, multi-value (flatten-first), empty, and dangling-ID behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/core/loops/sources/dataRows.ts | Generalizes loop-source media resolution by discovering media fields from fields_json, batch-resolving IDs, and overlaying URLs into LoopItem.fields. |
| src/core/data/cells.ts | Adds readMediaCellIds to tolerate both single-id and multi-id media cell shapes (string vs string[]). |
| src/tests/loops/dataRowsFetch.test.ts | Adds coverage to lock in URL resolution for custom media fields across both loop projections (data-kind + post-type). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
shadysamir
marked this pull request as ready for review
July 28, 2026 18:39
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A loop over a data table only exposed the built-in
featuredMediaandfirstImagefields as resolved media URLs. Any user-definedmediafield (for example a Clientlogo) was spread through raw, so a{currentEntry.<field>}binding on animgsrcemitted the stored media id instead of a URL. The browser then resolved that bare id against the current path, so the image never loaded, both on the editor canvas and on the published site.The
format:"media"hint written into the binding at authoring time had no consumer at render time: id → URL dereferencing ran only for the two hardcoded built-in fields in the loop source.This fix makes the loop source resolve every
type:"media"cell to its public path generically, replacing thefeaturedMedia-only special case:data_tables.fields_jsonto learn which fields are media-typed.collectMediaIdsgathers the featured id plus every custom media id into the existing single batched resolve, so no extra queries are issued.resolvedMediaOverlayoverwrites each media cell with its resolved public path in both row projections, spread right after the raw cells.allowMultiple) flatten to the first element for a scalar binding; a dangling id resolves tonullrather than leaking the raw id.Resolving media in the loop source runs before both token paths, so
resolveBindingValueandinterpolateTokensneed no changes: by the time they read the field, it is already a URL. A new shared readerreadMediaCellIds(insrc/core/data/cells.ts) tolerates both cell shapes (single id string, orstring[]).Scope is single-value resolution plus first-element flatten for multi-value. Rendering every element of a multi-value field is a separate nested-loop concern and is intentionally out of scope here.
Relates to #224 (same root limitation from the plugin-API side:
resolveMediaIdsToPathswas hardcoded to built-in media fields).Verification
bun run buildbun test(6302 pass, 0 fail; includes 5 new tests indataRowsFetch.test.ts)bun run lintChecklist
format:"media"contract.)🤖 Generated with Claude Code