WordPress Logo

How to Improve FeedWordpress

FeedWordPress is the best free plugin to syndicate posts from WordPress RSS feeds. Syndication is not the best practice, but it suits the needs of a client and their site network.

However, there is some minor issues. There is no built in duplicate post detection. This can create a mess when syndicating multiple feeds that may contain the same posts. Also, a default category is not assigned to posts if there is no matching category on your site. Place the below filter in your themes functions.php file to correct these issues.

/**
 * FeedWordPress - Detect duplicates and prepare the syndicated post.
 *
 * @param array $post
 * @param SyndicatedPost $syndicatedpost
 * @return array|null
 */
add_filter('syndicated_post', function (array $post, SyndicatedPost $syndicatedpost) {

    // --- Duplicate Detection

    if (!$syndicatedpost->fresh_content_is_update()) {
        global $wpdb;

        $duplicate_post = $wpdb->get_row($wpdb->prepare("
            SELECT ID FROM $wpdb->posts
            WHERE post_status = 'publish' AND post_type = 'post' AND post_title = %s
            AND ( post_date BETWEEN DATE_SUB( %s, INTERVAL 2 HOUR ) AND DATE_ADD( %s, INTERVAL 1 HOUR ) )
            LIMIT 1
        ", [
            $post[ 'post_title' ],
            $post[ 'post_date' ],
            $post[ 'post_date' ]
        ]));

        // Is it a duplicate post?
        if (!empty($duplicate_post)) {
            return null;
        }
    }

    // --- Prepare Syndicated Post

    // Assign the default category when a post has no categories.
    // No idea why FeedWordPress doesn't do this by default.
    if (empty($post[ 'tax_input' ][ 'category' ])) {
        $post[ 'tax_input' ][ 'category' ][] = intval(get_option('default_category'));
    }

    // Syndicated posts will include a 'read more' from the source site at the
    // end of their excerpts. Strip that out.
    $post[ 'post_excerpt' ] = preg_replace("/(&hellip;|&#8230;) <a href=.+<\/a>/", '', $post[ 'post_excerpt' ]);
    $post[ 'post_excerpt' ] = preg_replace("/\\[&hellip;\\]/", '', $post[ 'post_excerpt' ]);
    $post[ 'post_excerpt' ] = trim($post[ 'post_excerpt' ]);

    return $post;
}, 10, 2);

Lastly, we don’t want search engines to index these articles, they aren’t original content on our site. I also make use of Yoast WordPress SEO, we’ll use that to our advantage.

/**
 * Yoast WordPress SEO - Hide Syndicated Posts, and Sign Up form from Search Engines.
 *
 * @return void
 */
add_action('template_redirect', function (): void {
    if (!function_exists('YoastSEO')) {
        return;
    }

    $noindex = false;

    // Don't index Syndicated posts from FeedWordpress
    $is_syndicated = false;
    if (function_exists('is_syndicated')) {
        $is_syndicated = is_syndicated();
    }

    if (is_single() && $is_syndicated) {
        $noindex = true;
    }

    if ($noindex) {
        add_filter('wpseo_robots_array', [ YoastSEO()->helpers->robots, 'set_robots_no_index' ], 10, 2);
    }
});