函数文档

add_feed()

💡 云策文档标注

概述

add_feed() 函数用于在 WordPress 中注册一个新的自定义 feed 类型,例如 /atom1/。它通过添加 feed 名称到重写规则并关联回调函数来实现,适用于创建 RSS 或 Atom 等自定义 feed 端点。

关键要点

  • 参数 $feedname(字符串,必需)指定 feed 名称,不应以下划线 '_' 开头,否则可能导致错误。
  • 参数 $callback(可调用,必需)是处理 feed 显示的回调函数。
  • 函数返回一个字符串,表示 feed 动作名称(如 'do_feed_custom')。
  • 使用后需调用 flush_rules() 一次以使新 feed 生效。
  • 内部实现涉及全局变量 $wp_rewrite 和 add_action() 钩子。

代码示例

function add_custom_feed() {
    add_feed( 'custom', 'render_custom_feed' );
}
add_action( 'init', 'add_custom_feed' );

function render_custom_feed() {
    header( 'Content-Type: application/rss+xml' );
    echo 'aye!';
}

注意事项

  • 自定义 feed 默认使用 Content-Type: application/octet-stream; charset=UTF-8,建议在回调中设置正确的 Content-Type 头。
  • feed 名称以下划线开头时,do_feed() 函数会移除下划线,可能导致动作名称不匹配和 404 错误。
  • 相关函数包括 remove_action() 和 add_action(),用于管理动作钩子。

📄 原文内容

Adds a new feed type like /atom1/.

Parameters

$feednamestringrequired
Feed name. Should not start with '_'.
$callbackcallablerequired
Callback to run on feed display.

Return

string Feed action name.

More Information

Requires one-time use of flush_rules() to take effect.

$feedname parameter should not start with ‘_‘. Please refer #59945.

Source

function add_feed( $feedname, $callback ) {
	global $wp_rewrite;

	if ( ! in_array( $feedname, $wp_rewrite->feeds, true ) ) {
		$wp_rewrite->feeds[] = $feedname;
	}

	$hook = 'do_feed_' . $feedname;

	// Remove default function hook.
	remove_action( $hook, $hook );

	add_action( $hook, $callback, 10, 2 );

	return $hook;
}

Changelog

Version Description
2.1.0 Introduced.

User Contributed Notes

  1. Skip to note 5 content

    When a new custom feed is added, the endpoint will render using a `Content-Type: application/octet-stream; charset=UTF-8` by default. It would be useful to document working with content types in combination with add_feed() .

    For example either:

    function add_custom_feed() {
    	add_feed( 'custom', 'render_custom_feed' );
    }
    add_action( 'init', 'add_custom_feed' );
    
    function render_custom_feed() {
    	header( 'Content-Type: application/rss+xml' );
    	echo 'aye!';
    }

    or:

    function add_custom_feed() {
    	add_feed( 'custom', 'render_custom_feed' );
    }
    add_action( 'init', 'add_custom_feed' );
    
    
    function custom_feed_content_type( $content_type, $type ) {
    	if( 'custom' == $type ) {
    		$content_type = 'application/rss+xml';
    	}
    	return $content_type;
    }
    add_filter( 'feed_content_type', 'custom_feed_content_type', 10, 2 );
    
    function render_custom_feed() {
    	echo 'aye!';
    }

    will work.

    See: https://core.trac.wordpress.org/ticket/36334

  2. Skip to note 6 content

    Usage of add_feed()

    function wpdocs_add_mwb_feed() {
        add_feed( 'mwbfeed', 'wpdocs_makewebbetter_feed' );
    }
    add_action( 'init', 'wpdocs_add_mwb_feed' );
    
    function wpdocs_makewebbetter_feed() {
        add_filter( 'pre_option_rss_use_excerpt', '__return_zero' );
        load_template( PATHTEMPLATEFILE . '/feeds/a-feed-template.php' );
    }

  3. Skip to note 7 content

    RSS Feed based on custom WP Query with parameters

    add_action( 'init', 'wpdocs_custom_feed_rss2' );
    function wpdocs_custom_feed_rss2() {
    
        // Create your feed name like this : <a href="https://yoursite.com/wpdocs_custom?tag=test" rel="nofollow ugc">https://yoursite.com/wpdocs_custom?tag=test</a>
        add_feed( 'wpdocs_custom', 'wpdocs_change_main_query' );
        function wpdocs_change_main_query() {
    
            // Set right headers for RSS Feed
            header( 'Content-Type: application/rss+xml' );
    
            // Get main WP Query
            global $wp_query;
    
            // Get parameters in url
            if ( ! empty( $_GET['tag'] ) ) :
                $tag = $_GET['tag'];
            endif;
    
            // Overwrite main WP Query with yours
            $wp_query = new WP_Query(
                array(
                    'post_type' => 'any',
                    'fields'    => 'ids',
                    'tag'       => $tag,
                )
            );
    
            // Use the basic template to load your custom RSS Feed
            get_template_part( 'feed', 'rss2' );
        }
    }

  4. Skip to note 8 content

    The Feed name Parameters $feedname(required) should not start with `_` if it start with this then we will recieve the wp_die error message.

    function feed2_callback( $is_comment_feed, $feed ) {
    	header( 'Content-Type: application/xml; charset=UTF-8', true );
    	echo '';
    ?>
    
    	Test
    
    </pre>
    <p>Next, update the rewrite rule and access <a href="http://localhost/_feed2" rel="nofollow ugc">http://localhost/_feed2</a>, which will return <strong>wp_die</strong> with <strong>404</strong> status.</p>
    <p>This is not a problem with the code I tried, but because the “_” at the beginning of the feed name is removed in the do_feed function.</p>
    <pre class="wp-block-code"><code lang="php" class="language-php line-numbers">function do_feed() {
    	global $wp_query;
    
    	$feed = get_query_var( 'feed' );
    
    	// Remove the pad, if present.
    	$feed = preg_replace( '/^_+/', '', $feed );

    This process results in an action name of 'do_feed_' . 'feed2' when $feed is '_feed2'.

    Since this is not done in the add_feed function and the action name specified in the add_action function is 'do_feed_' . '_feed2', since the two action names do not match, which resulting in the error indicated in the response.