※途中で文が切れておりました・・・
tax_queryのinclude_childrenにて実現しようと思っているのですが、
以外にもなにか方法がございましたら、お教えいただけますと大変ありがたいです。
以上、よろしくお願いいたします。
include_children
は、あるタクソノミーそのもの(dateの値ではなくdateそのもの)に子のタクソノミーがある場合に、子も探す(true
)か探さない(false
)かを指定するものです。
うまくいくか実際に試してはいませんが、次のような方法を考えてみました。
- ループを二重にする。
- 前(外側)のループは、タクソノミー date を一つずつ読み取る。関数
get_taxonomies
または get_terms
が使えないでしょうか?
- 後(内側)のループは、読み取っておいた date(例えば 2014-01)を
tax_query
で検索してカスタム投稿を取り出す。
- カスタム投稿を取り出す時、例えば関数
get_posts
等に条件として numberposts=1
を足しておくことで、1件目だけにする。
実績1-* => 全て2014-01
実績2-* => 全て2014-02
ということでしょうか? work.php というのは、固定ページ用のテンプレートでしょうか? であれば、ORDER BY に post_title、GROUP BY にタクソノミーフィールドを指定するのが一番効率的ですが、JOIN を使ったりちょっと大がかりになってしまうので、別の方法を考えてみました。
archive-work.php を作成します。デフォルト設定なら、http://example.com/?post_type=work
、スラッグが設定してあれば、それでアクセスすると、このテンプレートが使われ、メインクエリがカスタム投稿タイプとなるので、query_post() 関数や、WP_Query クラスなどを使う必要がなくなります。
投稿のタイトル順で並んでほしいので、functions.php で変更します。
<?php
add_action('pre_get_posts', 'rewrite_for_work');
function rewrite_for_work($query) {
if (is_admin() || !$query->is_main_query()) return;
$type = isset($query->query['post_type']) ? $query->query['post_type'] : '';
if ($query->is_archive() && $type == 'work') {
$query->set('order', 'ASC');
$query->set('orderby', 'title');
}
}
?>
次に、archive-work.php の中で、ループを下のような形にします。やっていることは、タイトルの最後の2文字をチェックして、’-1′ となっている投稿タイトルだけを表示するというものです。
<?php
if (have_posts()) {
while (have_posts()) {
the_post();
$title = get_the_title();
if (preg_match('/.+-1$/', $title)) {
the_title();
}
}
}
?>
投稿と、タクソノミーの組み合わせが最初に書いた条件と違う場合は、もう少し手を入れる必要があります。
> ghvstさま。
投稿ありがとうございました!
include_childrenのそもそもの使い方が間違っておりました。。。ご指摘ありがとうございました。
2重のループで、というのは考えつかず、試してみました。
<?php
$args=array(
'name' => 'date'
);
$output = 'objects';
$taxonomies=get_terms($args,$output);
if ($taxonomies) {
foreach ($taxonomies as $taxonomy ) {
$taxdate = $taxonomy->name ;
}
}
?>
<?php
$args = array(
'post_type' => 'works',
'orderby' => 'date',
'order' => 'DESC',
'posts_per_page' => 15,
'paged' => $paged,
);
?>
<?php query_posts( $args ); ?>
<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<?php
query_posts( array(
'posts_per_page' => 1,
'paged' => $paged,
'order' => 'DESC',
'tax_query' => array(
array(
'taxonomy'=>'date',
'terms'=>$taxdate,
'field'=>'slug',
'include_children'=>true,
'operator'=>'IN'
),
'relation' => 'AND'
)
)
);
if (have_posts()) :while (have_posts()) :
the_post();
?>
という具合にまず、dateにある値(2014-01、2014-02)を$taxdateとし、
まず、外のloopでPostTypeのみで絞り、内のループでは$taxdateにて絞ってみました。
としてみた場合、
2014-02の最新一件のみが表示される形になりました。
echo $taxdate;
としてみた所、2014-01 2014-02と表示されている為、
問題なく取得できていそうなのに。。という状況でございます。
どこかおかしい点がございましたら、ご指摘いただけますと幸いです。
>kjmtshさま。
投稿ありがとうございます!
実績1-* => 全て2014-01
実績2-* => 全て2014-02
はい。2014-01の内最新1件。同じく2014-02の・・という具合での一覧表示を目指しております。
work.php というのは、固定ページ用のテンプレートでしょうか?
はい。その通りです。
お教えいただきました手法、一度試してみましたが、
1件も表示されない形となっておりました。
タイトルの最後の2文字をチェックして、’-1′ となっている投稿タイトルだけを表示するというものです。
こちらがページタイトルに-1が含まれているもの、という条件かと思いますが、
タイトルは別で任意の文字が設定されており、
その為かな、と思いました。
勉強不足なため、functions部分に記述する内容個所が詳細にわからなかったため、
すこし調べてみて改造の余地などを検討してみたいと思います。
ありがとうございます!
fst usr さん、作成なさったコードを拝見しました。
外のループが foreach
で、内のループが while
になる筈ですが
作成なさったコードでは、foreach
のループが回り終わってから
(その為、$taxdate
に 2014-02 が入った状態で)
while
のループの1回目が始まります。
狙っているのは下記のような二重ループ構造です。
get_terms(...)
foreach (...) {
query_posts(...)
while (...):
// 1つのタクソノミーの1件目の投稿だけ出力する処理
endwhile;
}
ghvstさま。
ご指摘ありがとうございました!
修正したソースで意図した出力ができました!
ちなみにこんな感じになりました。
ありがとうございました!
<?php
$args=array(
'name' => 'date'
);
$output = 'objects';
$taxonomies=get_terms($args,$output);
if ($taxonomies) {
arsort($taxonomies,SORT_NUMERIC);
foreach ($taxonomies as $taxonomy ) {
$taxdate = $taxonomy->name ;
//ここまでタクソノミー取得とforeach開始
query_posts( array(
'post_type' => 'works',
'orderby' => 'date',
'order' => 'DESC',
'posts_per_page' => '1',
'paged' => $paged,
'tax_query' => array(
array(
'taxonomy'=>'date',
'terms'=>$taxdate,
'field'=>'slug',
'include_children'=>true,
'operator'=>'IN'
),
'relation' => 'AND'
)
));
if (have_posts()) :while (have_posts()) :
the_post();
//html
//html
//html
endwhile;
endif;
wp_reset_query();
//ここまでPostTypeとタクソノミー指定してのループ
}
}
//foreach終了
?>