WordPressでカテゴリを選択して自分自身のRSSフィードを作成し、それを電子メールで購読できるようにする方法があるのかどうかと疑問に思っていました。 2つの問題があるようです。
どちらに進むのが一番良いかについて何か考えがありますか?
これは本当にクールなアイデアです。
パート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_profile
とedit_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つのヘルパーメソッドも紹介します。
get_user_terms
、get_user_meta
への呼び出しを伴う apply_filters
の簡単なラッパー-必要に応じて他の人が変更できるようにします!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);
}
}
}
ステップ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+が必要です。
私はこれを、通常の WordPressカテゴリフィード および MailChimp を使用して、受信したいカテゴリにのみ新しい投稿を受信するオプションを電子メール購読者に提供するために使用します。
MailChimp内で、各WordPressカテゴリのグループを作成してから、電子メール購読フォームで、購読を希望するグループ(カテゴリ)を購読者が選択できるようにします(一連のチェックボックスが最も簡単です)。彼らが購読するとき、彼らの選択は伝えられ、それらはMailChimpのそれらのグループに入れられるでしょう。
次にMailChimpで、カテゴリフィードを使用して各カテゴリのRSSキャンペーンを作成し、新しい投稿を購読者のセグメント(そのカテゴリに対応するグループを選択したセグメント)にのみ送信するようにキャンペーン設定で指定します。
最も簡単な方法は、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'
);
}
WordPressはすでに各カテゴリのRSSフィードを提供しています。これは、それらがどのように構成されているかを説明するコーデックスの記事です。
http://codex.wordpress.org/WordPress_Feeds#Categories_and_Tags
Eメール購読を機能させるには、通常、 Feedburner Eメール購読を有効にして(フィードを申請した後、[公開]> [Eメール購読]に移動します)、そのためには、カテゴリフィードを取得してFeedburnerでそれぞれフィードを設定してから、それらのリンクを適切な場所のサイトに追加する必要があります。大量のカテゴリを扱っているのであれば、それはかなりの作業になる可能性があります。うまくいけば、ここの他の人々が提案をするでしょう。
頑張って!