Plugin
Freshet Feeds
The gripe
Every feed plugin tries to own the markup: a styling panel, an iframe, somebody else's JavaScript on my pages.
The plugin
Should fetch the feed, hand me the items, and let my theme render them.
Freshet Feeds shows external feeds inside WordPress: RSS and Atom, YouTube channels and Bluesky profiles. Every provider is normalised into one item model and rendered through one template chain, and that chain is overridable from your theme.
It is for people who build themes and want the feed to look like the rest of the site, not like the plugin. If you have ever copied a WooCommerce template into your theme to change it, you already know how this one works.
Free, and the whole plugin
Every provider, every template, every hook, unlimited feeds. Nothing in the download is locked, limited or time-barred.
Your theme owns the markup
templates/ folder. Copy item.php into
{your-theme}/freshet-feeds/ and edit it; you copy only what you
change and everything else falls through. Items have their own hierarchy on top
of that, most specific first: item-{feed-slug}.php for one feed,
item-{provider}.php for every feed of that type, then
item.php for the rest. So an RSS feed and a YouTube channel on the
same page each get markup that fits, and two YouTube channels can look different
from each other. A custom layout is a file you drop in, not something you
register: add layout-carousel.php and pass carousel.
The override chain and the item hierarchy are in the docs.
Three live providers, no API keys
content:encoded, media thumbnails and image
enclosures are handled. YouTube channels through the public channel feed, no API
key and no quota, with a video-shaped default template that links to YouTube
rather than embedding an iframe. Bluesky profiles through the public API, no
authentication; reposts, replies and pins are filtered out, embedded images keep
their alt text. There is no X provider, because X has no free read API and no
RSS, and the plugin does not build on scraping. A provider of your own is one
PHP class and one hook, and inherits the cache, the templates and the block.
Each provider's settings are in the docs.
A Mock provider for building before the feed exists
production environment type, and
refuses to fetch there even for a feed created earlier, so fixture posts cannot
end up on a live site. It is also the fastest way to evaluate the plugin.
Pages never wait on a remote API
A Feed block for the editor
A loop API of four functions
freshet_feeds( 'my-feed' ) returns the cached items as an iterable,
countable collection of item objects, never blocking on the remote API; an unknown
slug gives an empty collection, not an error. Each item exposes getters for title,
date, excerpt, image and the rest, returning raw values so escaping happens in
your template, where WordPress developers expect to do it.
freshet_feeds_render( 'my-feed' ) runs the full template chain, with
layout and count as arguments; freshet_feeds_item() renders one item
through the hierarchy and freshet_feeds_template() is
get_template_part() for your own partials. WP-CLI gets
wp freshet-feeds status and fetch.
The four functions and every item getter are in the docs.
Needs WordPress 6.5 and PHP 8.2 or newer. Download it from wordpress.org, or read the source on GitHub. Or Try it in WordPress Playground first: a throwaway site in your browser, the plugin active and a feed already on the front page. The template chain, the item API, the providers and every hook are in the Feeds docs.
Something not covered here? The FAQ has a Feeds section.