Skip to main content

WordPress "What's New" Feed Integration

How to embed the latest product release notes from the Docusaurus documentation site into a WordPress website using the existing RSS feeds.

How it works

Docusaurus generates a per-product RSS feed for every blog (release notes) plugin instance. No changes to the docs site are needed — the feeds are already available at:

ProductRSS feed URL
contentACCESS/release/contentaccess/rss.xml
officeGATE/release/officegate/rss.xml
Storage Optimizer/release/storageoptimizer/rss.xml
contentACCESS Mobile/release/camobile/rss.xml
mailApp/release/mailapp/rss.xml

On the WordPress side, a small plugin fetches these feeds using the built-in fetch_feed() function (SimplePie with automatic 12-hour caching) and exposes a [whats_new] shortcode that can be placed anywhere — pages, widgets, or Gutenberg shortcode blocks.

WordPress plugin

Create the file wp-content/plugins/techarrow-whats-new/techarrow-whats-new.php:

<?php
/**
* Plugin Name: TECH-ARROW What's New Feed
* Description: Displays latest product releases from the documentation site.
* Version: 1.0.0
*/

if ( ! defined( 'ABSPATH' ) ) exit;

define( 'WHATS_NEW_BASE_URL', 'https://YOUR-DOCS-SITE.com' );

const WHATS_NEW_FEEDS = [
'contentaccess' => WHATS_NEW_BASE_URL . '/release/contentaccess/rss.xml',
'officegate' => WHATS_NEW_BASE_URL . '/release/officegate/rss.xml',
'storageoptimizer' => WHATS_NEW_BASE_URL . '/release/storageoptimizer/rss.xml',
'camobile' => WHATS_NEW_BASE_URL . '/release/camobile/rss.xml',
'mailapp' => WHATS_NEW_BASE_URL . '/release/mailapp/rss.xml',
];

const WHATS_NEW_LABELS = [
'contentaccess' => 'contentACCESS',
'officegate' => 'officeGATE',
'storageoptimizer' => 'Storage Optimizer',
'camobile' => 'contentACCESS Mobile',
'mailapp' => 'mailApp',
];

/**
* [whats_new] shortcode
*
* Attributes:
* product – comma-separated product IDs, or "all" (default)
* days – only posts from the last N days (default: 60)
* limit – max items to show (default: 10)
*
* Examples:
* [whats_new]
* [whats_new product="contentaccess" limit="5"]
* [whats_new product="contentaccess,officegate" days="90"]
*/
function whats_new_shortcode( $atts ) {
$atts = shortcode_atts( [
'product' => 'all',
'days' => 60,
'limit' => 10,
], $atts, 'whats_new' );

$days = max( 1, intval( $atts['days'] ) );
$limit = max( 1, intval( $atts['limit'] ) );
$cutoff = time() - $days * DAY_IN_SECONDS;

// Resolve product list
$feed_ids = ( $atts['product'] === 'all' )
? array_keys( WHATS_NEW_FEEDS )
: array_filter(
array_map( 'trim', explode( ',', $atts['product'] ) ),
fn( $id ) => isset( WHATS_NEW_FEEDS[ $id ] )
);

// Fetch and collect items from each feed
$items = [];
foreach ( $feed_ids as $product_id ) {
$feed = fetch_feed( WHATS_NEW_FEEDS[ $product_id ] );
if ( is_wp_error( $feed ) ) continue;

foreach ( $feed->get_items() as $item ) {
if ( $item->get_date( 'U' ) < $cutoff ) continue;
$items[] = [
'title' => $item->get_title(),
'link' => esc_url( $item->get_permalink() ),
'date' => $item->get_date( 'U' ),
'date_str' => $item->get_date( 'M j, Y' ),
'product' => $product_id,
'label' => WHATS_NEW_LABELS[ $product_id ] ?? $product_id,
];
}
}

if ( empty( $items ) ) {
return '<p class="whats-new-empty">No recent releases found.</p>';
}

// Sort newest first, apply limit
usort( $items, fn( $a, $b ) => $b['date'] - $a['date'] );
$items = array_slice( $items, 0, $limit );

ob_start(); ?>
<ul class="whats-new-list">
<?php foreach ( $items as $item ) : ?>
<li class="whats-new-item whats-new-product-<?php echo esc_attr( $item['product'] ); ?>">
<span class="whats-new-badge"><?php echo esc_html( $item['label'] ); ?></span>
<a class="whats-new-title"
href="<?php echo $item['link']; ?>"
target="_blank" rel="noopener noreferrer">
<?php echo esc_html( $item['title'] ); ?>
</a>
<time class="whats-new-date"><?php echo esc_html( $item['date_str'] ); ?></time>
</li>
<?php endforeach; ?>
</ul>
<?php
return ob_get_clean();
}
add_shortcode( 'whats_new', 'whats_new_shortcode' );

CSS

Add to Appearance → Customize → Additional CSS in WordPress, or to the active theme's stylesheet:

.whats-new-list { list-style: none; padding: 0; margin: 0; }
.whats-new-item { display: flex; align-items: baseline; gap: 10px;
padding: 8px 0; border-bottom: 1px solid #eee; }
.whats-new-badge { background: #1a4692; color: #fff; font-size: 11px;
font-weight: 600; padding: 2px 10px; border-radius: 999px;
white-space: nowrap; }
.whats-new-title { flex: 1; font-weight: 500; }
.whats-new-date { font-size: 12px; color: #888; white-space: nowrap; }

/* Per-product badge colours */
.whats-new-product-officegate .whats-new-badge { background: #e67e22; }
.whats-new-product-storageoptimizer .whats-new-badge { background: #27ae60; }
.whats-new-product-camobile .whats-new-badge { background: #8e44ad; }
.whats-new-product-mailapp .whats-new-badge { background: #c0392b; }

Shortcode usage

ShortcodeResult
[whats_new]All products, last 60 days, up to 10 items
[whats_new product="contentaccess"]contentACCESS only
[whats_new product="contentaccess,officegate"]Two products combined
[whats_new product="all" days="90" limit="5"]All products, last 90 days, max 5 items

Notes

  • Caching: WordPress caches each RSS feed for 12 hours automatically via transients — no extra configuration needed.
  • Date filtering: The days filter is applied after the feed is fetched (RSS does not support date-range queries). This is fine given the low volume of release posts.
  • CORS: Fetching is done server-side in PHP, so there are no cross-origin restrictions even if the docs site is on a different domain.
  • Adding a new product: Add the new product's feed URL to WHATS_NEW_FEEDS and its display label to WHATS_NEW_LABELS.