web-dev-qa-db-ja.com

ユーザーが選択したカテゴリから独自のフィードを作成することを許可しますか?

WordPressでカテゴリを選択して自分自身のRSSフィードを作成し、それを電子メールで購読できるようにする方法があるのか​​どうかと疑問に思っていました。 2つの問題があるようです。

  1. 人々がカテゴリからパーソナライズされたフィードを構築することを可能にします。
  2. メール購読を有効にする.

どちらに進むのが一番良いかについて何か考えがありますか?

7
Christopher

これは本当にクールなアイデアです。

パート2はWordPress内で処理されるべきではないと思います。メールプロバイダーへのRSSはたくさんあります。プラグイン(またはテーマ)がそうであるよりも、はるかに優れているでしょう。

しかし、RSSフィードを作成できます。

ステップ1:すべてをラップするようにクラスを設定します

ここにはいくつかのクラス定数と変数があります-後で使用します。ただのシングルトンパターン。

<?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;
    }
}

ステップ2:ユーザープロファイルページにフィールドを追加(および保存)

これを行うには、show_user_profileedit_user_profileにフックする必要があります。一回だけ、ラベル、およびフィールドを吐き出します。 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>';
        }
    }
}

また、最初の2つのヘルパーメソッドも紹介します。

  1. get_user_termsget_user_metaへの呼び出しを伴う apply_filters の簡単なラッパー-必要に応じて他の人が変更できるようにします!
  2. get_termsget_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);
        }
    }
}

ステップ3:フィードを提供する

これは非常にカスタムフィードであるため、これを行うために著者フィードのようなものをハイジャックする必要はありません(ただし、これはオプションです!)。代わりに、書き換えを追加しましょう。yoursite.com/user-feed/{{user_id}}は、パーソナライズされたユーザーフィードをレンダリングします。

書き換えを追加するには、initにフックして、 add_rewrite_rule を使用する必要があります。これはカスタムクエリ変数を使用してパーソナライズされたユーザーフィードを検出するため、WordPressが無視しないようにquery_varsとカスタム変数にもフックする必要があります。

<?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にフックし、カスタムクエリ変数(見つからない場合はベイリング)を探し、グローバルな$wp_queryをパーソナライズバージョンでハイジャックします。

また、wp_title_rssに接続してRSSタイトルを変更しましたが、これは少し奇妙でした。最初のカテゴリを取得し、フィードのタイトルを1つのカテゴリを見ているように表示しました。

<?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 を使用します。これをもっとカスタムなものに置き換えることもできますが、なぜ怠けてはいけませんか?

3番目のヘルパーメソッドもここにあります: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);
}

上記はすべて プラグインとして です。プラグイン(およびこの回答)では、匿名関数を使用するため、PHP 5.3+が必要です。

7
chrisguitarguy

私はこれを、通常の WordPressカテゴリフィード および MailChimp を使用して、受信したいカテゴリにのみ新しい投稿を受信するオプションを電子メール購読者に提供するために使用します。

MailChimp内で、各WordPressカテゴリのグループを作成してから、電子メール購読フォームで、購読を希望するグループ(カテゴリ)を購読者が選択できるようにします(一連のチェックボックスが最も簡単です)。彼らが購読するとき、彼らの選択は伝えられ、それらはMailChimpのそれらのグループに入れられるでしょう。

次にMailChimpで、カテゴリフィードを使用して各カテゴリのRSSキャンペーンを作成し、新しい投稿を購読者のセグメント(そのカテゴリに対応するグループを選択したセグメント)にのみ送信するようにキャンペーン設定で指定します。

3
Raam Dev

最も簡単な方法は、2つの非常に短い(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'
    );
}
1
kaiser

WordPressはすでに各カテゴリのRSSフィードを提供しています。これは、それらがどのように構成されているかを説明するコーデックスの記事です。

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

Eメール購読を機能させるには、通常、 Feedburner Eメール購読を有効にして(フィードを申請した後、[公開]> [Eメール購読]に移動します)、そのためには、カテゴリフィードを取得してFeedburnerでそれぞれフィードを設定してから、それらのリンクを適切な場所のサイトに追加する必要があります。大量のカテゴリを扱っているのであれば、それはかなりの作業になる可能性があります。うまくいけば、ここの他の人々が提案をするでしょう。

頑張って!

0
Michelle