WordPressメモ

はじめに

あとでミスを見つけることもあるので、こまめに書き換えると思う、たぶん。それと間違いがあるかもしれないので、ここに書かれていることは鵜呑みにしないこと。あくまで参考程度に。

サンプルコードは諸処の事情で全角スペース使って字下げしているので、そのままコピペしても動かない。一部だけを抜き出して載せてるのもあるのでコピペするときは要注意。

それと2.6でのメモと2.7でのメモが混在しているのでそれも注意。

特定のカテゴリ且つ特定のタグを持つ記事の抽出

<?php 
$category_id = 任意の値;
$current_tag = single_tag_title("", false);
$current_paged = intval(get_query_var('paged'));
$query = array('cat'=>$category_id, 'tag_slug__and'=>array($current_tag), 'paged'=>$current_paged);
query_posts($query);
?>

クエリを文字列ではなく配列形式で関数に代入する必要がある。また、クエリ内にpagedの値を入れないとページナビゲーション系が動作しない。

あと

<?php query_posts($query_string . ""); ?>

記事等の呼び出しループが終了したあと上のように記述してquery_stringを初期化することが必要。これもページナビゲーションを上手く動作させるため。これに限らず、query_stringの初期化はquery_posts()で条件指定した場合はとりあえずやっておいた方がいい、かも。

カテゴリID(term_id)からカテゴリ名またはスラッグを取得

function get_category_name_by_id($cat_ID,$type) {
 $cat_ID = (int) $cat_ID;
 $category = &amp;get_category($cat_ID);
 if($type == 'name'){
  return $category->cat_name;
 } elseif($type == 'slug') {
  return $category->slug;
 }
}

関数の引数は「カテゴリID」と「取得したい値の種類( ‘name’ または ’slug’ )」

カテゴリ別月別アーカイブページの作成

<?php 
$arc_year = substr($_SERVER['REQUEST_URI'], 6,4);
$arc_month_first = substr($_SERVER['REQUEST_URI'], 11,1); //月の値の二桁目を取得
if($arc_month_first) { //月が二桁だったら
 $arc_month = substr($_SERVER['REQUEST_URI'], 11,2);
} else { //一桁だったら
 $arc_month = substr($_SERVER['REQUEST_URI'], 12,1);
}
?>

URLから年・月の値を取得。

<?php if($_GET['mcat']): ?>
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$queryArray = array('cat'=>$_GET['mcat'],'monthnum'=>$arc_month,'year'=>$arc_year,'paged'=>$paged);
query_posts($queryArray);
?>
<?php endif; ?>

取得した年・月の値、及び、URLのGET変数から取得したカテゴリID(term_id)を利用してアーカイブを出力。

ちなみに。月別アーカイブのURLが「http://www.example.com/wordpress/date/2008/07」ってなってることが前提。フレンドリーURI設定になってない場合は適当に何とかしてください。それと11とか12とかって数値はWebサイトのアドレスに応じて変更しないとたぶんダメ。

カテゴリ別月別アーカイブリストの出力

「wp-includes」ディレクトリ内の「general-template.php」に記述されているwp_get_archives関数をカスタマイズする。基本的にテーマ内「functions.php」を作成し、その中にカスタマイズした関数を記述する。関数名は仮に「wp_get_archives_custom」とする。

関数の引数である文字列にカテゴリID(term_id)である「mcat」を加える。

function wp_get_archives_custom($args = '') {
 global $wpdb, $wp_locale;
 $defaults = array(
  'type' => 'monthly', 'limit' => '',
  'format' => 'html', 'before' => '',
  'after' => '', 'show_post_count' => false,
  'mcat' => false //デフォルト値はなし
 );

月別アーカイブリストを処理している部分を書き換える

if ( 'monthly' == $type ) {
 if($mcat){ //$mcatが'0'でなければ
  $taxID = $wpdb->get_var("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE $wpdb->term_taxonomy.term_id = $mcat",0,0);<em>//※1</em>
  $query = "SELECT DISTINCT YEAR(post_date) AS year, MONTH(post_date) AS month, count(ID) as posts FROM $wpdb->posts, $wpdb->term_relationships WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND $wpdb->term_relationships.term_taxonomy_id = $taxID AND $wpdb->posts.post_type = 'post' AND $wpdb->posts.post_status = 'publish' GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date DESC" . $limit;<em>//※2</em>
 } else { //$mcatが'0'であれば
  $query = "SELECT DISTINCT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date DESC $limit";
 }
 $key = md5($query);
 $cache = wp_cache_get( 'wp_get_archives' , 'general');
 if ( !isset( $cache[ $key ] ) ) {
  $arcresults = $wpdb->get_results($query);
  $cache[ $key ] = $arcresults;
  wp_cache_add( 'wp_get_archives', $cache, 'general' );
 } else {
  $arcresults = $cache[ $key ];
 }
 if ( $arcresults ) {
  $afterafter = $after;
  foreach ( $arcresults as $arcresult ) {
   $url = get_month_link($arcresult->year,$arcresult->month);
   $text = sprintf(__('%1$s %2$d'), $wp_locale->get_month($arcresult->month), $arcresult->year);
   if ( $show_post_count )
    $after = ' ('.$arcresult->posts.')' . $afterafter;
    echo get_archives_link_custom($url, $text, $format, $before, $after, $mcat); <em>//※3</em>
   }
  }
 }
※1
関数の引数として与える値はカテゴリID(term_id)である。しかし、実際に記事とカテゴリを結び付けている値は’term_taxonomy_id’であるため、’term_id’から’term_taxonomy_id’を取得する必要がある
※2
‘$mcat’に値が指定されていた場合のSQL文に変更を加える
※3
アーカイブリンクのURLを取得する関数にも変更を加える必要があり、引数に’$mcat’を追加する。
※4
これはあくまでもアーカイブのリストを取り出す方法なので、archive.php自体は別途記述しないとダメ。$mcatがURLパラメータに含まれていたらどうこうする、みたいな感じでquery_posts();なんかで条件指定する必要がある。それがこの前のセクションの処理。

アーカイブリンクのURLを取得する関数にカテゴリ関係の処理を追加する

function get_archives_link_custom ($url, $text, $format = 'html', $before = '', $after = '', $mcat) {
 $text = wptexturize($text);
 $title_text = attribute_escape($text);
 $url = clean_url($url);
 if($mcat) { //$mcatが'0'でなければ
  $url = $url."?mcat=".$mcat;
 }
 if ('link' == $format)
  return "\t<link rel='archives' title='$title_text' href='$url' />\n";
 elseif ('option' == $format)
  return "\t<option value='$url'>$before $text $after</option>\n";
 elseif ('html' == $format)
  return "\t<li>$before<a href='$url' title='$title_text'>$text</a>$after</li>\n";
 else // custom
  return "\t$before<a href='$url' title='$title_text'>$text</a>$after\n";
 }

オリジナルの関数に、引数$mcatに値が指定されていた場合は出力するURLにGET変数として$mcatの値を加える処理を追加。

追記

Archives for a category WordPress pluginを導入すれば<?php wp_get_archives('cat=1'); ?>とか記述して簡単に呼び出せるらしい。自分では試してないから2.7でも動作するのかどうかとかその辺のアレは知らん。

head要素内に前後の記事へのリンク要素を生成

function meta_link() {
 if(is_single()) {
  global $wpdb, $wp_query;
  $post = $wp_query->post;
  $prev_post = get_previous_post();
  if($prev_post) {
   $prev_title = strip_tags(str_replace('"', '', $prev_post->post_title));
   echo '<link rel="prev" href="' . get_permalink($prev_post->ID) . '" title="' . $prev_title. '" />' . "\n";
  }
  $next_post = get_next_post();
  if($next_post) {
   $next_title = strip_tags(str_replace('"', '', $next_post->post_title));
   echo '<link rel="next" href="' . get_permalink($next_post->ID) . '" title="' . $next_title. '" />' . "\n";
  }
 }
}

WP-Pagenaviを使わずにページナビゲーションを表示

吟遊詩人の戯言 » ページナビゲーション機能を改版してみたり」より。

function bmPageNavi() {
 global $wp_rewrite;
 global $wp_query;
 global $paged;
 $paginate_base = get_pagenum_link(1);
 if(($wp_query->max_num_pages) > 1):
   if (strpos($paginate_base, '?') || ! $wp_rewrite->using_permalinks()) {
     $paginate_format = '';
     $paginate_base = add_query_arg('paged', '%#%');
   } else {
     $paginate_format = (substr($paginate_base, -1 ,1) == '/' ? '' : '/') .
     user_trailingslashit('page/%#%/', 'paged');;
     $paginate_base .= '%_%';
   }
   $result = paginate_links( array(
     'base' => $paginate_base,
     'format' => $paginate_format,
     'total' => $wp_query->max_num_pages,
     'mid_size' => 5,
     'current' => ($paged ? $paged : 1),
   ));
   echo '<ul class="pageNav">'."\n\t<li>".$result."</li>\n</ul>\n";
 endif;
}

特定のIDを持つ記事を除外する方法

query_posts( array(’post__not_in’ => array(83) ); とかなんとかやって配列で除外したい投稿 ID を入れれば OK。当然、$query_stringの中身も入れないと特定記事を除いた全記事が出力されてしまう。

子カテゴリのidから親カテゴリの情報を取得する

$childCat = get_category($cat);
if ($childCat->parent) {
 $parentCat = get_category($cat->parent);
}

カテゴリーアーカイブ内での使用を想定。あとはecho attribute_escape($parentCat->cat_name);とかやればカテゴリ名を出力できたり、色々。var_dump($parentCat);とかやって$parentCatの中身を出力してみると何が格納されてるのか分かりやすいと思う。

query_posts()を利用して親カテゴリのアーカイブで子カテゴリの記事を出力する

カテゴリアーカイブ内の$catで取得できる値は親カテのIDだから、そのままquery_posts()に値を投げ込むと親カテと子カテの両方にチェック入れてない限り、親カテのアーカイブでは子カテの記事は表示されない。

よって、get_category_children()でその親カテに所属する子カテのIDを取得してquery_posts()に投げ込めば、子カテにしかチェック入れてない記事も親カテのアーカイブに表示させることができる。

補足。get_category_children()で取得できる値は文字列*1なのでsplit関数を使って配列形式にしてからquery_posts()に投げ込まないといけない。

(あくまでも query_posts() を利用して色々やりたい時用。単にWPループを使って記事を出力した場合は、何もしなくても親カテのアーカイブで子カテにしか所属していない記事も表示される。)

  1. たしか「/」区切りだったはず。

文書情報

公開日時
2008年7月12日土曜日 11時12分16秒
最終更新日時
2009年4月30日木曜日 22時07分40秒
文書制作者
Rusica