Skip to content

Allow Link fields to link to elements matched in the feed - #1789

Open
jrrdnx wants to merge 3 commits into
craftcms:6.xfrom
reusserdesign:feature/link-element-matching
Open

jrrdnx wants to merge 3 commits into
craftcms:6.xfrom
reusserdesign:feature/link-element-matching

Conversation

@jrrdnx

@jrrdnx jrrdnx commented Nov 9, 2026

Copy link
Copy Markdown

Description

Feed Me can import a Link field's type, value and label, but when a link points to an element (an entry, asset, category, etc.) the value has to be that element's ID on the destination site. When migrating content between sites, the feed only has the source site's IDs, so element links can't be imported.

This PR adds per-link-type element matching to the Link field mapping, the same way Entries, Assets and Categories fields already work:

  • For each element link type the field allows, choose which attribute or field the feed's value is matched against: ID, Title, Slug (for element types with URIs), Filename (assets), or any custom field that can be used as a unique identifier (e.g. an "Imported ID" field).
  • Matching respects the link type's allowed sources (volumes, sections, category groups) and the feed's site.
  • For assets, linked files that don't exist yet can optionally be uploaded:
    • URL to upload from: a feed node holding the file's URL
    • Volume to upload to: defaults to the first volume the link type allows
    • Folder path: created if it doesn't exist. It can be dynamic like an Assets field's upload location (e.g. Downloads/{slug}), rendered against the element being imported
    • After uploading, the matched field (e.g. Imported ID) is set on the new asset, so later imports match it instead of uploading again
  • If no element is matched (and nothing is uploaded), the link falls back to a URL link when the feed value is an absolute URL and the field allows URL links. Otherwise the link is left empty.

Link fields inside Matrix fields are supported. The element and upload URL nodes are passed through to the Link sub-field along with its other nodes.

Example

A source site exports a link like:

"buttonLink": {
  "type": "asset",
  "value": "12345",
  "label": "Download the program",
  "element": {
    "id": 12345,
    "url": "https://example.com/uploads/program.pdf",
    "filename": "program.pdf"
  }
}

Mapping:

Setting Value
Type buttonLink/type
Label buttonLink/label
Asset buttonLink/element/id, matched by Imported ID
Upload the asset if it doesn't exist ✓
URL to upload from buttonLink/element/url
Folder path Downloads/{slug}

On the first import, the PDF is uploaded to Downloads/<entry-slug>/, given Imported ID 12345, and linked. On later imports, it's matched by its Imported ID and not uploaded again.

Changes

  • src/fields/Link.php: element matching per link type, optional asset upload with a dynamic folder path, and URL fallback
  • src/templates/_includes/fields/link.html: per-link-type mapping UI (match by, upload, URL node, volume, folder path)
  • src/web/twig/variables/FeedMeVariable.php: getLinkElementTypes() for the mapping UI
  • src/fields/Matrix.php: pass a Link sub-field's element and upload URL nodes through to it

Testing

Tested with a content migration of ~8,000 entries using Link fields inside nested Matrix fields:

  • Entry and asset links matched by an Imported ID field
  • Missing assets uploaded once to a dynamic per-entry folder, then matched on re-import with no duplicate uploads
  • Email, phone and URL links unchanged
  • Unmatched element links fall back to URL links

🤖 Generated with Claude Code

Jarrod D Nix and others added 3 commits October 29, 2026 12:23
Element link types (e.g. Asset, Entry, Category) could only be imported by
the element's ID on the site being imported into. Each element link type
the field allows can now be mapped to a node identifying the element, with
the attribute or custom field to match it by (e.g. an "Imported ID" field),
the same as relation fields. The element is searched for in the sources the
link type allows.

For assets, there's also the option to upload the asset from a mapped URL
when there isn't a match, into a chosen folder. The uploaded asset's match
field is set, so later imports find it.

If no element is found, the link falls back to its value as a URL, when it is
one and the field allows URLs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The URL was saved as an option (options.urlNode), so a Link field nested
in a Matrix or CKEditor field never received it: nested fields only pass on
the feed data for mapped nodes. Map it as a node (url.node) like any other.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jrrdnx
jrrdnx requested a review from angrybrad as a code owner November 9, 2026 19:27
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.

1 participant