Benutzerdefinierte Feeds in WordPress anlegen

WordPress bietet standardmäßig RSS Feeds für Beiträge, Kommentare, Taxonomien, Archive und Custom Post Types an. In „Alle Feeds einer WordPress-Installation“ hat Vladimir diese mal aufgelistet.

Die Inhalte der vorhandenen Feeds können mit den richtigen Filtern angepasst werden. Doch wie kann ein eigener Feed angelegt werden?

Mit add_feed() einen eigenen Feed anlegen

Die seit WordPress 2.1.0 mitgelieferte Funktion add_feed() befindet sich in wp-includes/rewrite.php und ist, wie der Name schon verspricht, für das Anlegen neuer Feeds zuständig. Die Funktion ist folgendermaßen aufgebaut:

/**
 * Add a new feed type like /atom1/.
 *
 * @since 2.1.0
 *
 * @param string $feedname
 * @param callback $function Callback to run on feed display.
 * @return string Feed action name.
 */
function add_feed($feedname, $function) {
	global $wp_rewrite;
	if ( ! in_array($feedname, $wp_rewrite->feeds) ) //override the file if it is
		$wp_rewrite->feeds[] = $feedname;
	$hook = 'do_feed_' . $feedname;
	// Remove default function hook
	remove_action($hook, $hook, 10, 1);
	add_action($hook, $function, 10, 1);
	return $hook;
}

Zunächst erwartet die Funktion einen Slug für den Feed. Es ist der Name, unter welchem der Feed später aufrufbar sein wird. Er sollte deswegen nur aus den Zeichensatz [a-z0-9_-] bestehen. Die Feed URL wird bei aktivierten Permalinks im Format example.com/feed/{feed_slug} sein.
Der zweite Teil ist die Callback-Funktion. Diese Funktion sollte den Feed rendern und wird beim Aufruf des Feeds aufgegriffen.

Das feed-rss2.php Template

feed-rss2.php ist ein Template in WordPress und übernimmt die Darstellung für jegliche Art von Post Type im RSS2 Format.

Das Template ist somit die optimale Ausgangslage für die Darstellung des eigenen Feeds und kann deswegen in der Callback-Funktion geladen werden.

Anregung für PHP 5.3:

function ds_custom_feed() {
	add_feed( 'custom', function() {
		load_template( ABSPATH . WPINC . '/feed-rss2.php' );
	} );
}
add_action( 'init', 'ds_custom_feed' );

Feed mit eigenen Inhalt füllen

Was nun noch fehlt, ist der Inhalt des Feeds. Dazu als Beispiel folgende Klasse anschauen:

PHP / RAW / github:gist
<?php
/**
 * Add a custom feed to WordPress.
 *
 * The feed will be rendered through the wp-includes/feed-rss2.php template
 * and avaiable under example.com/feed/{$feed_slug}.
 *
 * Note: Don't forget to flush the rewrite rules once.
 *
 * @author Dominik Schilling
 * @link   https://dominikschilling.de/897
 */
class DS_Custom_Feed {
	/**
	 * Sets the feed slug.
	 *
	 * @var string
	 */
	public static $feed_slug = 'custom';

	/**
	 * Registers the feed and the pre_get_posts action
	 */
	public static function init() {
		add_feed( self::$feed_slug, array( __CLASS__, 'feed_template' ) );

		add_action( 'pre_get_posts', array( __CLASS__, 'feed_content' ) );
	}

	/**
	 * Customizes the query.
	 * It will bail if $query is not an object, filters are suppressed and it's not
	 * our feed query.
	 *
	 * @param  WP_Query $query The current query
	 */
	public static function feed_content( $query ) {
		// Bail if $query is not an object or of incorrect class
		if ( ! $query instanceof WP_Query )
			return;

		// Bail if filters are suppressed on this query
		if ( $query->get( 'suppress_filters' ) )
			return;

		// Bail if it's not our feed
		if ( ! $query->is_feed( self::$feed_slug ) )
			return;

		// Change the feed content
		// Example: A feed for pages
		$query->set( 'post_type', array( 'page' ) );
	}

	/**
	 * Loads the feed template which is placed in wp-includes/feed-rss2.php.
	 */
	public static function feed_template() {
		load_template( ABSPATH . WPINC . '/feed-rss2.php' );
	}
}

/**
 * Hooks into `init`.
 *
 * Note: add_feed() needs access to the global $wp_rewrite
 */
add_action( 'init', array( 'DS_Custom_Feed', 'init' ) );

Es wird Gebrauch vom pre_get_posts Hook gemacht. Dieser erlaubt es die Query nach Bedarf anzupassen – hier wird z.B. der Post Type auf page gesetzt. Was alles angepasst werden kann, kann dem Eintrag im Codex entnommen werden.

Als Beispiel kann ich auf meinen Feed für den WPD Planet hinweisen, welcher nur Beiträge mit einem bestimmten Custom Field anzeigt – Nachzulesen im GitHub Repo zum Theme.

Zum Thema

4 thoughts on “Benutzerdefinierte Feeds in WordPress anlegen”

  1. Zur Prüfung ob ein Objekt von einer bestimmten Klasse abgeleitet ist, möchte ich dir mal instanceof ( if ( $query instanceof WP_Query ) { ... }) ans Herz legen ;)

    Was ich allerdings noch nicht ganz kapiert habe ist, wie der Content in den Feed kommt. Auf der einen Seite habe ich eine Funktion die den Content (z.B. ein Array) liefert. Auf der anderen Seite habe ich ein Template das den Content verarbeitet (z.B. mit Foreach). Reicht es aus das Array global zu machen und dann im Template zu verarbeiten? Das würde dann ja bedeuten das ich für meinen “speziellen” Content auch ein spezielles Template benötigen würde, oder?

  2. Ich bin gerade zum ersten Mal hier und benutze WP erst seit ein paar Tagen, der Beitrag kommt da gerade wie gerufen. Super erklärt. Danke.

  3. Danke für die Anleitung! In Bezug auf das Thema würde mich außerdem interessieren, ob es eine Möglichkeit gibt, Bilder von Artikeln automatisch in den RSS Feed einbinden zu lassen. Habe mich dahingehend schon versucht zu informieren, aber konnte leider noch nicht herausfinden wie man dem RSS-Feed die Bild-URLs übermittelt.

Leave a Reply