WP Manifestindependent plugin directory
manifest / editor / feedwright

Feedwright WP Registry grade A. No security issues foundWP RegistryNo security issues foundOpen the reportA

[WordPress Plugin] Compose custom RSS / Atom / XML feeds in the WordPress block editor — namespaces, queries, dynamic bindings.

★ 0stars
34release downloads
0.2.1latest · 6mo ago

Install

Download feedwright.zip From the 0.2.1 release on GitHub, Apr 28, 2026

Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/mt8/feedwright/releases/download/0.2.1/feedwright.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Feedwright

Feedwright

Edit custom RSS / Atom / XML feeds visually in the WordPress block editor.

Try Feedwright in WordPress Playground

Try it live • Features • How It Works • Bindings • Installation • Development • FAQ • Contributing • License


Try it live

Click ▶ Try it live above (or open the demo). WordPress Playground boots a full WordPress entirely in your browser with Feedwright pre-installed and a SmartNews-shaped sample feed already seeded — four sample posts with featured images, a <channel> carrying snf:logo, and item-level media:thumbnail / media:content / dc:creator / category / media:status (mapped from post status). It lands you straight in the block editor for that feed; visit /feedwright/smartnews/ to see the rendered XML.

The Problem

WordPress ships exactly one RSS feed shape. Anything else — Atom 1.0, Media RSS, namespaced extensions, conditional elements, alternate query orderings — means writing PHP templates and shipping a bespoke endpoint per feed.

There's no GUI for "I want this tag here, that namespace declared, this query running, this field bound to that element". Editors who own the feeds can't touch them without engineering involvement.

Feedwright fixes this. Feeds are post objects you compose with the block editor: nest XML elements as blocks, declare namespaces on the root, configure a query, bind dynamic values via {{post.post_title}} expressions. The plugin renders the resulting tree as XML and serves it at a public URL.

Features

  • Block-tree editor for XML — <rss> / <channel> / <item> and arbitrary element blocks compose the feed structure visually.
  • Namespaced tags — declare xmlns: prefixes on the root block; use them anywhere as prefix:tagname on elements and attributes.
  • Query as a block — feedwright/item-query exposes WP_Query options (post types, ordering, post status, taxonomy filter, sticky toggle) and expands each result inside <channel> as an <item>.
  • Dynamic bindings — {{post.post_title}}, {{post.permalink}}, {{post.post_date:r}}, {{author.display_name}}, {{post_meta.x}}, {{post_term.category}}, {{option.blogname}} and more, with modifiers and processors (truncate, allow_tags, strip_tags, map).
  • Live XML preview — sidebar panel that renders the current feed by calling a REST endpoint, with auto-update on edit.
  • Object-cache–backed render — keyed by post_modified_gmt for natural invalidation; manual flush in settings.
  • Multisite-aware — each site stores and serves its own feeds.
  • Custom post type permissions — feeds are restricted to manage_options by default.
  • i18n — Japanese localization included.

How It Works

                  feedwright_feed (custom post type)
                            │
            block tree:  <rss> → <channel> → element*
                                         └── <item-query> → <item> → element*
                            │
                      parse_blocks
                            │
            ┌───────────────┴───────────────┐
            ▼                               ▼
        Renderer                     BindingResolver
   (DOMDocument)                  ({{ns.path:mod|proc}})
            │                               │
            └─────── XML string  ◀──────────┘
                            │
                  /{base}/{slug}/  ──▶  client
                            │
                      Render cache
                  (object cache, TTL)
  1. A feedwright_feed post stores the block tree.
  2. A custom rewrite rule maps /{base}/{slug}/ to that post.
  3. The renderer walks the block tree, resolves bindings against post / option / now / feed contexts, and builds a DOMDocument.
  4. Result is cached by post id + post_modified_gmt and served as application/xml.

Bindings

Bindings are inline expressions that resolve at render time. Inside an element block (or any static text-mode field), type {{ to insert one — the editor offers contextual suggestions for available providers, modifiers (date format, image size, term separator), and post-resolution processors.

{{namespace.path[:modifier][|processor[:arg]] [...]}}

Examples:

{{post.post_title}}                            → post title (filtered)
{{post.post_date:r}}                           → publish date in RFC 2822
{{post.thumbnail_url:large}}                   → featured image URL at the "large" size
{{post.post_excerpt|truncate:120}}             → excerpt, max 120 chars
{{post.post_content|allow_tags:p,br,strong}}   → content stripped to a few HTML tags
{{post_raw.post_status|map:publish=1,*=0}}     → 1 if published, 0 otherwise
{{post_term.category}}                         → joined term names
{{option.blogname}} / {{option.home_url}}
{{author.display_name}} / {{author.user_email}}
{{feed.last_build_date:r}} / {{now:r}}

Available namespaces: option, feed, now, post, post_raw, post_meta, post_term, author. Built-in processors: truncate, allow_tags, strip_tags, map. Both providers and processors are extensible from third-party code via feedwright/binding_providers and feedwright/binding_processors filters.

Installation

  1. Upload the plugin folder to wp-content/plugins/feedwright/, or install via the Plugins screen.
  2. Activate the plugin.
  3. Go to Feedwright → Add Feed and start composing in the block editor.
  4. Optionally adjust the URL prefix at Feedwright → Settings.

Development

Requires Docker Desktop, Node 20+, PHP 8.3+, and Composer.

git clone https://github.com/mt8/feedwright.git
cd feedwright
composer install
npm install

# Boot wp-env (dev: 9888, tests: 9889)
npx wp-env start

# Build editor assets
npm run build           # one-shot
npm run start           # watch mode

Tests

# Static analysis (WordPress Coding Standards)
composer run phpcs
composer run phpcbf      # auto-fix

# PHP unit (no WP, fast)
composer run test:unit

# PHP integration (inside wp-env tests-cli)
npx wp-env run tests-cli --env-cwd=wp-content/plugins/feedwright \
    vendor/bin/phpunit --testsuite integration --bootstrap=tests/bootstrap.php

# E2E (Playwright)
npx playwright install chromium
npm run test:e2e

husky + lint-staged runs phpcs against staged PHP files before each commit (enabled after npm install).

Translations

# Refresh the .pot template
npx wp-env run cli wp i18n make-pot wp-content/plugins/feedwright \
    wp-content/plugins/feedwright/languages/feedwright.pot \
    --domain=feedwright --slug=feedwright \
    --exclude=vendor,node_modules,build,tests,tmp

# After editing a .po (e.g. feedwright-ja.po), regenerate .mo + JSON
npx wp-env run cli wp i18n make-mo  wp-content/plugins/feedwright/languages
npx wp-env run cli wp i18n make-json wp-content/plugins/feedwright/languages \
    --no-purge --extensions=jsx

Directory layout

feedwright/
├── feedwright.php       Plugin main entry (bootstrap)
├── src/                 PHP (PSR-4: Feedwright\)
├── blocks/              Block source (block.json + edit / index / variations)
├── languages/           .pot / .po / .mo / per-script JED
├── assets/              Logos and icons
└── tests/
    ├── bootstrap.php    Integration bootstrap
    ├── Unit/            Unit tests
    └── Integration/     Integration tests

Full implementation spec: docs/requirements.md.

FAQ

How is this different from a custom feed template in a theme or plugin?

A theme template ties the feed shape to PHP and to the people who can deploy code. Feedwright stores feeds as posts, so editors with appropriate permissions can change the structure, add elements, or rewire bindings without touching files or shipping a release.

Where are feeds served?

At /{base}/{slug}/ where base is configurable (default feedwright) and slug comes from each feedwright_feed post's post_name. Default: /feedwright/{slug}/.

Does it cache?

Yes — the render is cached in the WordPress object cache, keyed by (blog_id, post_id, post_modified_gmt, url_base_hash). Updating the feed post invalidates naturally; settings provides a manual flush button. TTL defaults to one hour and is configurable.

Can I declare arbitrary XML namespaces?

Yes. Add prefix / uri pairs on the <rss> block's Inspector. Any element or attribute can then use prefix:localname.

Does it support Atom?

Yes — set the item element name on feedwright/item-query (item for RSS 2.0, entry for Atom, or any declared prefix:local), and choose tag names for the channel-level elements accordingly.

Multisite?

Yes — each site has independent feeds, settings, and cache.

Contributing

Issues and PRs are welcome. Please open an issue first to discuss non-trivial changes.

The project follows an issue/{ISSUE_NUMBER} branching convention. CI runs phpcs, PHPUnit (Unit + Integration on a matrix of WordPress 6.5 / latest × PHP 8.3 / 8.4), Plugin Check, and Playwright E2E.

License

GPL-2.0-or-later — see LICENSE for details.

Releases

7 releases. Each count is every asset in that release; expand a row for the breakdown.

Tag
Published
Assets
Downloads
0.2.1 latest
Apr 28, 2026 6mo ago
feedwright.zip +1 asset
12
feedwright.zip12
feedwright-0.2.1.zip0
Apr 28, 2026 6mo ago
feedwright.zip +1 asset
1
feedwright.zip1
feedwright-0.2.0.zip0
Apr 28, 2026 6mo ago
feedwright.zip +1 asset
4
feedwright.zip4
feedwright-0.1.4.zip0
Apr 28, 2026 6mo ago
feedwright.zip +1 asset
1
feedwright.zip1
feedwright-0.1.3.zip0
Apr 27, 2026 6mo ago
feedwright.zip +1 asset
1
feedwright.zip1
feedwright-0.1.2.zip0
Apr 27, 2026 6mo ago
feedwright.zip +1 asset
10
feedwright.zip10
feedwright-0.1.1.zip0
Apr 27, 2026 6mo ago
feedwright.zip +1 asset
5
feedwright.zip4
feedwright-0.1.0.zip1
A grade

Security

Feedwright 0.2.1 · audited by WP Registry

No security issues found.

Audited release
0.2.1
Findings
none
Worst severity
—
Content hash
bd71f14e17c39a411bf63f48…

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.