私はこれに関して多くの質問/投稿を見ました、しかしまともな解決策をまだ見つけていません。基本的に私はwp_get_archives
がすることをやろうとしています、しかしカスタム投稿タイプのために(個人的に私はwp_get_archives
がカスタム投稿タイプをサポートしない理由はわからない!).
私が現在使っているコードは以下の通りです。
functions.php
function Cpt_getarchives_where_filter( $where , $r ) {
$post_type = 'events';
return str_replace( "post_type = 'post'" , "post_type = '$post_type'" , $where );
}
sidebar-events.php
add_filter( 'getarchives_where' , 'Cpt_getarchives_where_filter' , 10 , 2 );
wp_get_archives();
remove_filter('getarchives_where' , 'Cpt_getarchives_where_filter' , 10 );
このコードは、日付(2014年4月、2014年3月など)などを表示します。素晴らしいですが、リンクをクリックすると404に移動します。各日付リンクに作成されるURLは/ 2014/04 /です。/events/2014/04 /のように。
Archive-events.phpテンプレートを使用できるようにURLに「イベント」を含める方法はありますか。また、リンクが現在404を生成する理由はありますか?
助けてくれてありがとう
毎月のアーカイブの場合は'month_link'
、年間のアーカイブの場合は'year_link'
、毎日のアーカイブの場合は'day_link'
をフィルタリングすることもできます。
CPTを扱うようにwp_get_archives
を拡張し、'getarchives_where'
とアーカイブリンクにフィルタを追加する関数を書くこともできます。
function wp_get_cpt_archives( $cpt = 'post', $args = array() ) {
// if cpt is post run the core get archives
if ( $cpt === 'post' ) return wp_get_archives($args);
// if cpt doesn't exists return error
if ( ! post_type_exists($cpt) ) return new WP_Error('invalid-post-type');
$pto = get_post_type_object($cpt);
// if cpt doesn't have archive return error
if ( ! $pto = get_post_type_object( $cpt ) ) return false;
$types = array('monthly' => 'month', 'daily' => 'day', 'yearly' => 'year');
$type = isset( $args['type'] ) ? $args['type'] : 'monthly';
if ( ! array_key_exists($type, $types) ) {
// supporting only 'monthly', 'daily' and 'yearly' archives
return FALSE;
}
$done_where = $done_link = FALSE;
// filter where
add_filter( 'getarchives_where' , function( $where ) use (&$done_where, $cpt) {
if ( $done_where ) return $where;
return str_replace( "post_type = 'post'" , "post_type = '{$cpt}'" , $where );
});
// filter link
add_filter( "{$types[$type]}_link", function( $url ) use (&$done_link, $pto, $cpt) {
if ( $done_link ) return $url;
// if no pretty permalink add post_type url var
// if ( get_option( 'permalink_structure' ) || ! $pto->rewrite ) {
if ( ! get_option( 'permalink_structure' ) || ! $pto->rewrite ) {
return add_query_arg( array( 'post_type' => $cpt ), $url );
} else { // pretty permalink
global $wp_rewrite;
$slug = is_array( $pto->rewrite ) ? $pto->rewrite['slug'] : $cpt;
$base = $pto->rewrite['with_front'] ? $wp_rewrite->front : $wp_rewrite->root;
$home = untrailingslashit( home_url( $base ) );
return str_replace( $home, home_url( $base . $slug ), $url );
}
});
// get original echo arg and then set echo to false
$notecho = isset($args['echo']) && empty($args['echo']);
$args['echo'] = FALSE;
// get archives
$archives = wp_get_archives($args);
// prevent filter running again
$done_where = $done_link = TRUE;
// echo or return archives
if ( $notecho ) {
return $archives;
} else {
echo $archives;
}
}
機能がどのように機能するかについての詳細はインラインコメントを読んでください。
今問題があります。 /events/2014/04/
のようなURLはWordPressに認識されないので、その種類のURLを処理するreqriteルールを追加する必要があります。
繰り返しますが、そのルールを追加する関数を書くことができます。
function generate_cpt_archive_rules( $cpt ) {
if ( empty($cpt) || ! post_type_exists($cpt) ) return;
global $wp_rewrite;
$pto = get_post_type_object($cpt);
if ( ! $pto->has_archive ) return;
$base = $pto->rewrite['with_front'] ? $wp_rewrite->front : $wp_rewrite->root;
$base = trailingslashit( $base );
$slug = is_array( $pto->rewrite ) ? $pto->rewrite['slug'] : $cpt;
$year = ltrim( $base . $slug . '/([0-9]{4})/?$', '/' );
$month = ltrim( $base . $slug . '/([0-9]{4})/([0-9]{2})/?$', '/' );
$day = ltrim( $base . $slug . '/([0-9]{4})/([0-9]{2})/([0-9]{2})/?$', '/' );
$index = 'index.php?post_type=' . $cpt;
$rules[$year] = $index . '&m=$matches[1]';
$rules[$month] = $index . '&m=$matches[1]$matches[2]';
$rules[$day] = $index . '&m=$matches[1]$matches[2]$matches[3]';
$page = 2;
foreach ( array( $year, $month, $day ) as $rule ) {
$paged = str_replace( '/?$', '/page/([0-9]{1,})/?$', $rule);
$rules[$paged] = $rules[$rule] . '&paged=$matches[' . $page . ']';
$page++;
}
return $rules;
}
この関数はルールを生成しますが、それらを追加してフラッシュする必要もあります。
テーマ(またはプラグイン)の有効化に関するルールをフラッシュしてinitに登録することをお勧めします。そのため、次のようにします。
function register_cpt_dates_rules() {
$cpts = array( 'events' );
foreach ( $cpts as $cpt ) {
foreach ( generate_cpt_archive_rules( $cpt ) as $rule => $rewrite ) {
add_rewrite_rule( $rule, $rewrite, 'top' );
}
}
}
// flushing on theme switch
add_action('after_switch_theme', function() {
register_cpt_dates_rules();
$GLOBALS['wp_rewrite']->flush_rules();
});
// registering on init
add_action( 'init', 'register_cpt_dates_rules' );
これらの関数をfunctions.php
に追加したら(そして'after_switch_theme'
を実行させるためにあなたのテーマを非アクティブ化し再度アクティブ化したら)、アーカイブを表示することができます。
wp_get_cpt_archives( 'events' );
そしてそれはイベントCPTのためのアーカイブを表示し、そしてリンクは何か/events/2014/04/
になるでしょう。
年間または毎日のアーカイブにも使用できます。
wp_get_cpt_archives( 'events', array( 'type'=>'yearly' ) );
wp_get_cpt_archives( 'events', array( 'type'=>'daily' ) );
私の2つの関数を使用すると、wp_get_archives
をCPTで動作させるための非常に簡単な方法があります。
ここでallのコードにはPHP 5.3+が必要です。
私はG.Mがあなたが必要とするすべてを与えたと思います。 CPTの日付アーカイブのパーマリンク生成について ブログ記事 を書きましたが、他のpre_get_posts
部分をブログに入れる時間がありませんでしたまだ投稿フォーム。
パズルには基本的に3つの部分があります。
/2014/04/30
、/2014/
などの日付文字列を読み取るための書き換え規則を生成します。