web-dev-qa-db-ja.com

カスタムフィールド/投稿メタの日付値で絞り込まれたアーカイブリスト

モデレータ注: 元のタイトルは「日付を指定してアーカイブを使用する」でした)

カスタムフィールドとして投稿に追加の日付を追加しています。今、私はアーカイブにカスタムの日付で投稿された日付ではなく投稿を表示したいと思います。例えば、私は今日投稿された記事を持っています (12月22日) しかしカスタム日付は 1月1日 に設定されています。ブラウザにURL archives/date/2011/01を読み込むと、カスタム日付が一致する投稿は表示されません (明らかに)。

カスタム日付までに投稿を回収するために、archives/date/2011/01 URLに対して生成されたページの動作を変更する方法はありますか?

ありがとう。

4
Dalen

WordPressの多くのことと同様に、あなたが望むことをするにはいくつかの方法があります。そのうちの1つを説明します。

'year''monthnum'、および'day'クエリ変数を削除します。

WordPressが'pre_get_posts'フック内のアーカイブURLで使用するクエリのパラメータを変更できます。これらのパラメーターは、WP_Query変数query_vars'year'および'monthnum'と呼ばれる'day'オブジェクトのプロパティーへの書き換え規則によって連想配列として取り込まれます。

$wp_query->query_vars'year''monthnum'および'day'の値がある場合、WordPressは記事のリストを照会するときにそれらを使用します。したがって、 - クエリ配列からキーと値のペアを削除することです PHPのunset()関数を使用その$wp_queryは、現在のクエリオブジェクトをWP_Queryクラスのインスタンスとして含むWordPressのグローバル変数です。)

以下の'pre_get_posts'フックによってトリガされたyoursite_pre_get_posts()関数は、それらの変数をquery_vars配列から削除しますが、それは、クエリがメインクエリ*である場合のみです(つまり、フックに渡される$queryがグローバル$wp_the_queryまたは$query===$wp_the_queryと完全に等しい場合)。archiveクエリです。これをあなたのテーマのfunctions.phpファイルに追加すると、あなたのアーカイブページは日付だけの投稿ではなく全ての投稿を表示するでしょう(だから私たちはあなたが望むものに中途半端です...)

add_action('pre_get_posts', 'yoursite_pre_get_posts' );
function yoursite_pre_get_posts( $query ) {
  global $wp_the_query;
  if ($query===$wp_the_query && $query->is_archive) {
    unset($query->query_vars['year']);
    unset($query->query_vars['monthnum']);
    unset($query->query_vars['day']);
  }
}

カスタムフィールドにクエリ変数を追加する

今それが少しトリッキーになるところです。 v3.0.xでは、WordPressはquery_var配列の値を使ってカスタムフィールドを問い合わせることしかできず、それらの基準に関数を適用することもできません。

yoursite_pre_get_posts()を次のように変更すると、カスタムフィールドに'YYYY-MM-DD'の形式で日付を格納したと仮定して、アーカイブクエリが正確な日付と一致するようになります。

add_action('pre_get_posts', 'yoursite_pre_get_posts' );
function yoursite_pre_get_posts( $query ) {
  global $wp_the_query;
  if ($query===$wp_the_query && $query->is_archive) {
    $qv = &$query->query_vars;
    $date = mktime(0,0,0,$qv['monthnum'],$qv['day'],$qv['year']);
    $qv['meta_key'] = 'Custom Date';
    $qv['meta_value'] = date("Y-m-d",$date);
    unset($qv['year']);
    unset($qv['monthnum']);
    unset($qv['day']);
  }
}

これがスクリーンショットのようなものです。

もちろん、それはあなたが望むことではありません。特定の日だけでなく、年だけでなく、年と月を照会する必要があります。私が前に言ったように、それはそれがトリッキーになるところです。

'posts_where'フックを使用してSQLのWHERE句を変更する

基本的には、フックにもっと深く入り込んで'posts_where'フックを呼び出す必要があります。SQLクエリフラグメントでテキストの検索と置換を行うときは、他のプラグインと互換性のないコードを書くのはとても簡単です。同じSQLクエリを変更します。それにもかかわらず、あなたがそれを必要とし、他に何も働かないなら、それはあなたのための最後の手段としてそこにあります。

それでyoursite_posts_where()関数はWordPressがテキスト"AND wp_postmeta.meta_value = '2011-01'"を構築するWHERE節を検索し、それをテキスト"AND SUBSTRING(wp_postmeta.meta_value,1,7) = '2011-01'"に置き換えます、そしてここにコードがあります:

add_action('posts_where','yoursite_posts_where',10,2);
function yoursite_posts_where( $where, $query ) {
  global $wp_the_query;
  if ($query===$wp_the_query && $query->is_archive) {
    $meta_value = $query->query_vars['meta_value'];
    $length = strlen($meta_value);
    $find = "AND wp_postmeta.meta_value = '{$meta_value}'";
    $replace = "AND SUBSTR(wp_postmeta.meta_value,1,{$length}) = '{$meta_value}'";
    $where = str_replace($find,$replace,$where);
  }
  return $where;
}

複数の年月日オプションをサポートするようにyoursite_pre_get_posts()を修正

もちろん、yoursite_pre_get_posts()関数を変更して、異なる長さのメタ値をサポートする必要があります。'YYYY''YYYY-MM'、および'YYYY-MM-DD'(PHPのmktime()およびdate()関数の複雑な使用のように思われるものの使用は単に心配する必要がないようにするためです)これらのパターンについて:'YYYY-M''YYYY-MM-D'および'YYYY-M-D'):

add_action('pre_get_posts','yoursite_pre_get_posts' );
function yoursite_pre_get_posts( $query ) {
  global $wp_the_query;
  if ($query===$wp_the_query && $query->is_archive) {
    $qv = &$query->query_vars;  // Make it less tedious to reference
    if ($qv['monthnum']==0) // Just search on YYYY
      $date = $qv['year'];
    else if ($qv['day']==0) // Search on YYYY-MM
      $date = date('Y-m',mktime(0,0,0,$qv['monthnum'],1,$qv['year']));
    else
      $date = date('Y-m-d',mktime(0,0,0,$qv['monthnum'],$qv['day'],$qv['year']));
    $qv['meta_key'] = 'Custom Date';
    $qv['meta_value'] = $date;
    unset($qv['year']);
    unset($qv['monthnum']);
    unset($qv['day']);
  }
}

そしてそれは私たちにあなたが探していたものをほとんどまとめた次のものを与えます:

テーマにカスタム日付を表示するためのコード

ところで、これが私がテーマでCustom Dateメタ値を取得するために使ったコードです:

<?php if ($custom_date = get_post_meta($post->ID,'Custom Date',true)): ?>
  <h2>Custom Date: <?php echo $custom_date; ?></h2>
<?php endif; ?>

P.Sユーザーは'YYYY-MM-DD'形式で入力する必要があることを忘れないでください

これを機能させるには、ユーザーが'YYYY-MM-DD'形式でカスタム日付を入力する必要があることを忘れないでください。もちろん、SQLコードや日付を再フォーマットする'save_post'フックなど、さまざまな方法でユーザーにやさしいものにすることができますが、他の人のための練習として残しておきます。

P.P.S.オプション:代わりに複数のメタ値を保存する

別のアプローチは、'save_post''YYYY-MM-DD'および'YYYY-MM'に一致させるために'YYYY'フックを使用して'_custom_date''_custom_date_year_month'、および'_custom_date_year'に一致させるために3つの隠しメタ値を保存することでした。また、SQLのWHERE句を変更したいが、投稿ごとに3つの隠しカスタムフィールドを追加するため、投稿数が多いブログにはお勧めできません。何らかの理由で同期がとれなくなる可能性があります。 。

9
MikeSchinkel

はい - query_posts() または get_posts() を使用するか、独自のカスタムクエリを作成する必要があります。

0
Mark

これを試して:

  • archive.php(アーカイブがない場合はindex.php)テンプレートをdate.phpにコピーします
  • date.phpテンプレートでは、sortをオーバーライドするためにquery_posts()を使用します。を使用する必要があります。

PSええと、私は日付アーカイブは通常/year/month/のようなものだと思います、/archives/date/year/month/を取得するために何を使用していますか?..

PPSが実際にMikeの答えを見た後、これは投稿の選択に影響を与えるのに十分ではないかもしれません。これをスクラッチしてください。

0
Rarst