是否允许用户从所选类别创建自己的提要?

时间:2012-03-19 作者:Christopher

过去几个小时我一直在网上徘徊,想知道是否有一种方法可以让用户通过在WordPress中选择类别来构建自己的RSS提要,然后通过电子邮件订阅。似乎存在两个问题:

允许人们根据类别构建个性化提要启用电子邮件订阅关于如何最好地继续这两种方法,您有什么想法吗?

4 个回复
最合适的回答,由SO网友:chrisguitarguy 整理而成

这是个很酷的主意。

我认为第2部分不应该在WordPress内部处理:有很多RSS到电子邮件提供商。他们将比插件(或主题)在这方面做得更好。

但我们可以创建RSS提要。

Step one: set up a class to wrap everything up.

这里有几个类常量和变量——我们稍后将使用它们。只是一个单件模式。

<?php
class Per_User_Feeds
{
    // Where we\'ll store the user cats
    const META_KEY = \'_per_user_feeds_cats\';

    // Nonce for the form fields
    const NONCE = \'_user_user_feeds_nonce\';

    // Taxonomy to use
    const TAX = \'category\';

    // The query variable for the rewrite
    const Q_VAR = \'puf_feed\';

    // container for the instance of this class
    private static $ins = null;

    // container for the terms allowed for this plugin
    private static $terms = null;

    public static function init()
    {
        add_action(\'plugins_loaded\', array(__CLASS__, \'instance\'));
    }

    public static function instance()
    {
        is_null(self::$ins) && self::$ins = new self;
        return self::$ins;
    }
}

Step two: add a field to the user profile pages (and save it)

你需要加入show_user_profileedit_user_profile 这样做。弹出一个nonce、一个标签和字段。show_user_profile 当用户在管理区域查看其配置文件时激发。edit_user_profile 当他们编辑其他人的配置文件时激发--这是您的管理员用户在编辑用户类别中的方式。

<?php
class Per_User_Feeds
{
    // snip snip

    protected function __construct()
    {
        add_action(\'show_user_profile\', array($this, \'field\'));
        add_action(\'edit_user_profile\', array($this, \'field\'));
    }

    public function field($user)
    {
        wp_nonce_field(self::NONCE . $user->ID, self::NONCE, false);

        echo \'<h4>\', esc_html__(\'Feed Categories\', \'per-user-feed\'), \'</h4>\';

        if($terms = self::get_terms())
        {
            $val = self::get_user_terms($user->ID);
            printf(\'<select name="%1$s[]" id="%1$s" multiple="multiple">\', esc_attr(self::META_KEY));
            echo \'<option value="">\', esc_html__(\'None\', \'per-user-feed\'), \'</option>\';
            foreach($terms as $t)
            {
                printf(
                    \'<option value="%1$s" %3$s>%2$s</option>\',
                    esc_attr($t->term_id),
                    esc_html($t->name),
                    in_array($t->term_id, $val) ? \'selected="selected"\' : \'\'
                );
            }
            echo \'</select>\';
        }
    }
}
这还介绍了我们的前两个助手方法:

  1. get_user_terms, 一个简单的包裹器get_user_meta 打电话给apply_filters -- 如果别人愿意,就让他们修改吧
  2. get_terms 包裹物get_terms 打电话给apply_filters.
这两个都是方便的事情。它们还为其他插件/主题提供了连接和修改内容的方法。

<?php
/**
 * Get the categories available for use with this plugin.
 *
 * @uses    get_terms
 * @uses    apply_filters
 * @return  array The categories for use
 */
public static function get_terms()
{
    if(is_null(self::$terms))
        self::$terms = get_terms(self::TAX, array(\'hide_empty\' => false));

    return apply_filters(\'per_user_feeds_terms\', self::$terms);
}

/**
 * Get the feed terms for a given user.
 *
 * @param   int $user_id The user for which to fetch terms
 * @uses    get_user_meta
 * @uses    apply_filters
 * @return  mixed The array of allowed term IDs or an empty string
 */
public static function get_user_terms($user_id)
{
    return apply_filters(\'per_user_feeds_user_terms\',
        get_user_meta($user_id, self::META_KEY, true), $user_id);
}
要保存字段,请连接到personal_options_update (当用户保存自己的配置文件时激发)和edit_user_profile_update (保存其他用户的配置文件时激发)。

<?php
class Per_User_Feeds
{
    // snip snip

    protected function __construct()
    {
        add_action(\'show_user_profile\', array($this, \'field\'));
        add_action(\'edit_user_profile\', array($this, \'field\'));
        add_action(\'personal_options_update\', array($this, \'save\'));
        add_action(\'edit_user_profile_update\', array($this, \'save\'));
    }

    // snip snip

    public function save($user_id)
    {
        if(
            !isset($_POST[self::NONCE]) ||
            !wp_verify_nonce($_POST[self::NONCE], self::NONCE . $user_id)
        ) return;

        if(!current_user_can(\'edit_user\', $user_id))
            return;

        if(!empty($_POST[self::META_KEY]))
        {
            $allowed = array_map(function($t) {
                return $t->term_id;
            }, self::get_terms());

            // PHP > 5.3: Make sure the items are in our allowed terms.
            $res = array_filter(
                (array)$_POST[self::META_KEY],
                function($i) use ($allowed) {
                    return in_array($i, $allowed);
                }
            );

            update_user_meta($user_id, self::META_KEY, array_map(\'absint\', $res));
        }
        else
        {
            delete_user_meta($user_id, self::META_KEY);
        }
    }
}

Step three: provide a feed

由于这在很大程度上是一个自定义提要,我们不想劫持像author提要这样的东西来完成这项工作(尽管这是一种选择!)。相反,让我们添加一个重写:yoursite.com/user-feed/{{user_id}} 将呈现个性化用户提要。

要添加我们需要连接到的重写init 和使用add_rewrite_rule. 由于这使用了一个自定义查询变量来检测何时使用个性化的用户提要,因此我们还需要连接到query_vars 以及我们的自定义变量,以便WordPress不会忽略它。

<?php
class Per_User_Feeds
{
    // snip snip

    protected function __construct()
    {
        add_action(\'show_user_profile\', array($this, \'field\'));
        add_action(\'edit_user_profile\', array($this, \'field\'));
        add_action(\'personal_options_update\', array($this, \'save\'));
        add_action(\'edit_user_profile_update\', array($this, \'save\'));
        add_action(\'init\', array($this, \'rewrite\'));
        add_filter(\'query_vars\', array($this, \'query_var\'));
    }

    // snip snip

    public function rewrite()
    {
        add_rewrite_rule(
            \'^user-feed/(\\d+)/?$\',
            \'index.php?\' . self::Q_VAR . \'=$matches[1]\',
            \'top\'
        );
    }

    public function query_var($v)
    {
        $v[] = self::Q_VAR;
        return $v;
    }
}
要实际渲染提要,我们将template_redirect, 查找我们的自定义查询var(如果找不到,则进行bailing),并劫持全局$wp_query 具有个性化版本。

我还迷上了wp_title_rss 修改RSS标题,这有点奇怪:它抓取了第一个类别,并显示提要标题,就像查看单个类别一样。

<?php
class Per_User_Feeds
{
    // snip snip

    protected function __construct()
    {
        add_action(\'show_user_profile\', array($this, \'field\'));
        add_action(\'edit_user_profile\', array($this, \'field\'));
        add_action(\'personal_options_update\', array($this, \'save\'));
        add_action(\'edit_user_profile_update\', array($this, \'save\'));
        add_action(\'init\', array($this, \'rewrite\'));
        add_filter(\'query_vars\', array($this, \'query_var\'));
        add_action(\'template_redirect\', array($this, \'catch_feed\'));
    }

    // snip snip

    public function catch_feed()
    {
        $user_id = get_query_var(self::Q_VAR);

        if(!$user_id)
            return;

        if($q = self::get_user_query($user_id))
        {
            global $wp_query;
            $wp_query = $q;

            // kind of lame: anon function on a filter...
            add_filter(\'wp_title_rss\', function($title) use ($user_id) {
                $title = \' - \' . __(\'User Feed\', \'per-user-feed\');

                if($user = get_user_by(\'id\', $user_id))
                    $title .= \': \' . $user->display_name;

                return $title;
            });
        }

        // maybe want to handle the "else" here?

        // see do_feed_rss2
        load_template( ABSPATH . WPINC . \'/feed-rss2.php\' );
        exit;
    }
}
实际渲染我们所依赖的提要wp-includes/feed-rss2.php. 你可以用一些更习惯的东西来代替它,但为什么不懒惰呢?

这里还有第三个助手方法:get_user_query. 与上述助手的想法相同——抽象出一些可重用的功能并提供挂钩。

<?php
/**
 * Get a WP_Query object for a given user.
 *
 * @acces   public
 * @uses    WP_Query
 * @return  object WP_Query
 */
public static function get_user_query($user_id)
{
    $terms = self::get_user_terms($user_id);

    if(!$terms)
        return apply_filters(\'per_user_feeds_query_args\', false, $terms, $user_id);

    $args = apply_filters(\'per_user_feeds_query_args\', array(
        \'tax_query\' => array(
            array(
                \'taxonomy\'  => self::TAX,
                \'terms\'     => $terms,
                \'field\'     => \'id\',
                \'operator\'  => \'IN\',
            ),
        ),
    ), $terms, $user_id);

    return new WP_Query($args);
}
以上都是as a plugin. 由于使用匿名函数,该插件(以及随后的回答)需要PHP 5.3+。

SO网友:Raam Dev

我用常规的WordPress Category FeedsMailChimp 为我的电子邮件订阅者提供只接收他们感兴趣的类别的新帖子的选项。

在MailChimp中,您为每个WordPress类别创建一个组,然后在您的电子邮件订阅表单上允许您的订阅者选择他们感兴趣订阅的组(即类别)(一组复选框可能是最简单的)。当他们订阅时,他们的选择将被传递,并被放入MailChimp上的这些组中。

然后在MailChimp上,使用类别提要为每个类别创建一个RSS活动,并在活动设置中指定只向订阅者的某个部分(已选择与该类别对应的组的部分)发送新帖子。

SO网友:kaiser

最简单的方法是添加一系列两个非常短的(mu)插件。这也会为page/2, 等:

http://example.com/u/%author%

<?php
/** Plugin Name: (WPSE) #46074 Add /u/%author% routes */

register_activation_hook(   __FILE__, function() { flush_rewrite_rules(); } );
register_deactivation_hook( __FILE__, function() { flush_rewrite_rules(); } );

add_action( \'init\', function()
{
    // Adds `/u/{$author_name}` routes
    add_rewrite_rule(
        \'u/([^/]+)/?\',
        \'index.php?author_name=$matches[1]\',
        \'top\'
    );
    add_rewrite_rule(
        \'u/([^/]+)/page/?([0-9]{1,})/?\',
        \'index.php?author_name=$matches[1]&paged=$matches[2]\',
        \'top\'
    );
}

http://example.com/p/%postname%

<?php
/** Plugin Name: (WPSE) #46074 Add /u/%author% routes */

register_activation_hook(   __FILE__, function() { flush_rewrite_rules(); } );
register_deactivation_hook( __FILE__, function() { flush_rewrite_rules(); } );

add_action( \'init\', function()
{
    // Adds `/p/{$postname}` routes
    add_rewrite_rule(
        \'p/([^/]+)/?\',
        \'index.php?p=$matches[1]\',
        \'top\'
    );
    add_rewrite_rule(
        \'p/([^/]+)/page/?([0-9]{1,})/?\',
        \'index.php?p=$matches[1]&paged=$matches[2]\',
        \'top\'
    );
}

SO网友:Michelle

WordPress已经为每个类别提供了RSS提要,这是codex的文章,解释了它们的结构:

http://codex.wordpress.org/WordPress_Feeds#Categories_and_Tags

为了使电子邮件订阅正常工作,我通常会设置Feedburner 启用电子邮件订阅后(在申请订阅源后,转到Publication>email subscriptions)。这将要求您获取您的分类提要,并在Feedburner中设置每个提要,然后在适当的位置将这些链接添加到您的站点。如果你要处理大量的类别,那可能需要做很多工作。希望这里的其他人会有建议。

祝你好运!

结束

相关推荐

NEXT_POST_LINK()中的EXCLUDE_CATEGORIES参数行为异常

我有一个Wordpress模板。php页面。该页面有“下一页”和“上一页”箭头,允许浏览所有帖子。我想将某些类别的帖子排除在“下一个”和“上一个”计算中。我有以下代码: // in single.php next_post_link( \'%link\', \'&larr; Previous\', false, \'11 and 13 and 15\'); 这应该会显示到下一篇文章的链接。第11、13和15类的职位不应按照the $ignore_categories para