Skip to content

Show link previews for posts that link to an article - #712

Merged
akirk merged 2 commits into
mainfrom
feature/link-previews
Sep 4, 2026
Merged

akirk merged 2 commits into
mainfrom
feature/link-previews

Conversation

@akirk

@akirk akirk commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Fixes #708

Mastodon renders the preview card itself, per server — it is not part of the ActivityPub object, so nothing about it reaches us. A shared news article therefore arrives as text plus a bare link. This builds the card locally instead.

Changes

  • New Friends\Link_Preview class.
    • Which posts: post format status, link or aside (filter: friends_link_preview_post_formats), and only when the content carries no media of its own (<img>, <video>, <audio>, <iframe>, <embed>, <object>) — the same rule Mastodon uses, so an image post doesn't get a second image.
    • Which link: the first <a> that isn't a mention, hashtag, rel="tag"/rel="author", a link back to the poster's own host, or a direct file link (filter: friends_link_preview_url, return false to suppress).
    • Lookup: wp_safe_remote_get() in a wp_schedule_single_event(), capped at 300 KB via limit_response_size, 10s timeout, 3 redirects, HTML content types only. Extracts og:* with twitter:* / <title> / <meta name="description"> fallbacks; relative image URLs are resolved, non-http(s) image URLs dropped.
    • Storage: link_preview post meta (filter: friends_link_preview), plus link_preview_checked so a link that yields nothing isn't retried for a week.
    • When: new posts are queued from friends_retrieved_new_posts, so nothing is added to the latency of a feed refresh. Pre-existing posts are queued lazily on first display and show their card on the next page load.
  • New frontend/parts/link-preview template part, rendered from frontend/parts/entry-content (so all four PHP themes pick it up) and appended to the friends/post-content block for the block theme. Styled in friends.css, friends-blocks.css, mastodon.css, twitter.css and google-reader.css.
  • New setting under Settings → Link Previews: "Disable link previews for incoming posts" (friends_disable_link_previews). On by default; off means no card is shown and no outbound request is ever made.

Testing instructions

  • With the setting enabled (default), subscribe to a Mastodon account that posts news links, refresh the feed, and reload /friends/ — a card with the article's title, description and image appears under the status. Posts that already contain an image are unchanged.
  • Tick "Disable link previews for incoming posts" in Settings and reload: the cards are gone.
  • Metadata extraction was exercised against live pages (arstechnica.com, en.wikipedia.org, theguardian.com, example.com) and against fixtures covering hashtag/mention-only statuses, statuses that already show an image, links to the poster's own host, direct image links, relative og:image paths, data: image URLs, > inside quoted attribute values, and pages with no metadata at all.
  • Not verified end-to-end in a browser: the throwaway Playground fixture used for screenshots failed to render its synthetic subscription — the same truncation happens on unmodified main, so it's the fixture, not this branch.

Changelog entry

  • Automatically create a changelog entry from the details below.
Changelog Entry Details

Type

  • Added - for new features

Message

Show a link preview card for posts that link to an article, with a setting to turn it off.

https://claude.ai/code/session_01J7aozaEFaZ3vLaLXith1qm

Test this PR in WordPress Playground

You can test this pull request directly in WordPress Playground:

Launch WordPress Playground

This will install and activate the plugin with the changes from this PR.

Fediverse posts that point at a news article arrive as plain text plus a
link; the preview card Mastodon renders is generated by each server and
is not part of the ActivityPub object, so it never reaches us. Build it
locally instead.

A status/link/aside post that carries no media of its own gets its first
link (skipping mentions, hashtags, rel=tag, links back to the poster's
own host and direct file links) looked up in the background via cron.
The Open Graph/Twitter Card metadata of that page is stored in post meta
and rendered as a card below the post, in all five themes.

New posts are queued when a feed is retrieved; posts that predate this
are queued lazily the first time they are displayed and get their card
on the next page load. Lookups that turn up nothing are remembered for a
week so they aren't retried on every view.

Can be turned off with the "Disable link previews for incoming posts"
setting, for people who'd rather their site not contact the linked
websites.

Fixes #708

Claude-Session: https://claude.ai/code/session_01J7aozaEFaZ3vLaLXith1qm
@akirk
akirk merged commit 21815bd into main Sep 4, 2026
26 checks passed
@akirk
akirk deleted the feature/link-previews branch September 4, 2026 10:41
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.

Link Previews

1 participant