質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.12%

WPの月別アーカイブを複数のカスタム投稿が混在した形で表示したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,814

MOMONUTS

score 39

WPでカスタム投稿を数種類作り、固定ページで複数のカスタム投稿の記事が混在した記事一覧リストを作っております。
記事表示やページ送りは問題なく出来るのですが、複数のカスタム投稿記事を混在させた月別アーカイブが作れず苦戦しております。

固定ページはテンプレートphpを作り、その中に

<?php
    $wp_query = new WP_Query();
    $my_posts03 = array(
        'post_type' => array('topics_01', 'topics_02', 'topics_03', 'topics_04', 'topics_05', 'topics_06'),
        'posts_per_page'=> '10',
        'paged' => $paged,
    );
    $wp_query->query( $my_posts03 );
    if( $wp_query->have_posts() ): while( $wp_query->have_posts() ) : $wp_query->the_post();
?>
<ul class="topnews clearfix">
<li><?php the_time('Y年m月d日') ?></li>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
</ul>
<?php endwhile; endif; wp_reset_postdata(); ?>
<?php get_template_part( 'nav', 'below' ); ?>


と記述し、記事一覧とページ送りを表示させております。

月別アーカイブ部分は

<?php
$string = wp_get_archives(array(
'show_post_count' => 1, 
'post_type' => array('topics_01', 'topics_02', 'topics_03', 'topics_04', 'topics_05', 'topics_06'),
'echo' => 0
));
echo preg_replace('/<\/a>&nbsp;(\([0-9]*\))/', ' <span class="count">$1</spn></a>', $string);
?>


と記述してみましたが、複数ですと認識されません。
'post_type' =>topics_01,
のみですと正常に動作するのですが...

試行錯誤してみましたが、どの様に記述すれば良いか分からず質問させていただきました。

ご教授お願いいたしますm(_ _)m

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

wp_get_archives()post_typeパラメータは文字列しか受け付けないため、アクションとフィルターに関数をフックして設定する必要があります。

function my_pre_get_posts( $query ) {
    if ( $query->is_month() && $query->is_main_query() ) {
        $query->set( 'post_type', array('post','test','syohin') );
    }
}
add_action( 'pre_get_posts', 'my_pre_get_posts' );

function my_getarchives_where( $where ){
    $where = "WHERE";
    $where .= " (post_type = 'post' OR post_type = 'test' OR post_type = 'shohin')";
    $where .= " AND post_status = 'publish'";
    return $where;
}
add_filter( 'getarchives_where', 'my_getarchives_where' );

追記

元のwp_get_archives()の仕様をなるべく活かすように改造したら長くなりました。
テストはあまりしていませんが、多分動くと思います。

  • wp_get_archives()の'post_type'パラメータが投稿タイプ名の配列を受け付けるように改造
  • 年月アーカイブページで複数の投稿タイプを表示できるようにクエリを追加

アーカイブリストを表示

<?php
$args = array(
    'type'            => 'monthly',
    'limit'           => '',
    'format'          => 'html', 
    'before'          => '',
    'after'           => '',
    'show_post_count' => false,
    'echo'            => 1,
    'post_type'       => array('post', 'page'),
);
my_wp_get_archives( $args )
?>

functions.phpに記載

function my_query_vars( $vars ){
  $vars[] = "apt";
  return $vars;
}
add_filter( 'query_vars', 'my_query_vars' );

function my_pre_get_posts($query) {
    if ( !is_admin() && $query->is_main_query() ) {
        if ($query->is_archive) {
            $apt = $query->get('apt');

            if( !empty($apt) ) {
                $post_type_array = explode(',', $apt);
                $query->set( 'post_type', $post_type_array );
            }
        }
    }
}
add_action( 'pre_get_posts','my_pre_get_posts' );

function my_wp_get_archives( $args = '' ) {
    global $wpdb, $wp_locale;

    $defaults = array(
        'type' => 'monthly', 'limit' => '',
        'format' => 'html', 'before' => '',
        'after' => '', 'show_post_count' => false,
        'echo' => 1, 'order' => 'DESC',
        'post_type' => 'post'
    );

    $r = wp_parse_args( $args, $defaults );

    if( !is_array($r['post_type']) ) {
        $r['post_type'] = array($r['post_type']);
    }

    foreach( $r['post_type'] as $post_type ) {
        $post_type_object = get_post_type_object( $post_type );
        if ( ! is_post_type_viewable( $post_type_object ) ) {
            return;
        }
        $post_types[] = $post_type_object->name;
    }

    $r['post_type'] = $post_types;

    if ( '' == $r['type'] ) {
        $r['type'] = 'monthly';
    }

    if ( ! empty( $r['limit'] ) ) {
        $r['limit'] = absint( $r['limit'] );
        $r['limit'] = ' LIMIT ' . $r['limit'];
    }

    $order = strtoupper( $r['order'] );
    if ( $order !== 'ASC' ) {
        $order = 'DESC';
    }

    // this is what will separate dates on weekly archive links
    $archive_week_separator = '&#8211;';

    $sql_where = $wpdb->prepare("WHERE (post_type = %s", $r['post_type'][0]);
    if( !(count($r['post_type'])==1) ) {
        for($i=1; $i<count($r['post_type']); $i++) {
            $sql_where .= $wpdb->prepare(" OR post_type = %s", $r['post_type'][$i]);
        }
    }
    $sql_where .= ") ";

    $sql_where .= "AND post_status = 'publish'";

    $where = $sql_where;
    $join = '';

    $output = '';

    $last_changed = wp_cache_get_last_changed( 'posts' );

    $limit = $r['limit'];

// 文字数制限に引っかかったので、続きは別回答に記載

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/07 09:16

    miz様
    ご回答ありがとうございます。
    教えていただいたコードをfunctionsに追記する事で全カテゴリー記事が混在した月別アーカイブ表示が出来ました。
    ただし、やりたい事は
    topics01の記事一覧ページ=topics01のみの月別アーカイブを表示
    topics02の記事一覧ページ=topics02のみの月別アーカイブを表示
    topics03の記事一覧ページ=topics03のみの月別アーカイブを表示
    .
    .
    .
    全カテゴリー記事が混在した記事一覧ページ(固定ページ)=全カテゴリーの記事が混在した月別アーカイブを表示
    という形になります。
    特定のページのみ全てのカテゴリー記事が混在した月別アーカイブを表示させる事は可能でしょうか?

    質問ばかりですみません....

    キャンセル

  • 2017/03/07 17:20

    条件を後出しされても困るのですが……

    そういう条件であれば、以下のようにすればいいかと思います。
    (1) wp_get_archivesをコピペし、複数の投稿タイプ入力に対応したアーカイブリスト表示関数を新規作成
    (2) pre_get_postsにアーカイブのタイプによって投稿タイプを設定するように関数をフック

    キャンセル

  • 2017/03/08 09:13

    miz様
    重要な部分が後出しの様な形になってしまい、大変申し訳ございません。
    上記の方法ですが、具体的にどの様に記述すれば良いか分からず、未だ全カスタム投稿ページで全記事の月別アーカイブが出てしまっている状態です。

    どの様に記述すれば良いかご指導を賜れますでしょうか...
    本当に何度も申し訳ございません...m(_ _)m

    キャンセル

0

// 文字数制限に引っかかったので、回答を分割して記載

    if ( 'monthly' == $r['type'] ) {
        $query = "SELECT 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 $order $limit";
        $key = md5( $query );
        $key = "wp_get_archives:$key:$last_changed";
        if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
            $results = $wpdb->get_results( $query );
            wp_cache_set( $key, $results, 'posts' );
        }

        if ( $results ) {
            $after = $r['after'];
            foreach ( (array) $results as $result ) {
                $url = get_month_link( $result->year, $result->month );
                /* translators: 1: month name, 2: 4-digit year */
                $text = sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $result->month ), $result->year );
                if ( $r['show_post_count'] ) {
                    $r['after'] = '&nbsp;(' . $result->posts . ')' . $after;
                }

                if( !empty($r['post_type']) ) {
                    $apt = implode( ',', $r['post_type'] );
                    $url = add_query_arg( 'apt', $apt, $url );
                }

                $format = (empty($r['format']))?('html'):($r['format']);
                $before = (empty($r['before']))?(''):($r['before']);
                $after = (empty($r['after']))?(''):($r['after']);

                $text = wptexturize($text);
                $url = esc_url($url);

                if ('link' == $format)
                    $link_html = "\t<link rel='archives' title='" . esc_attr( $text ) . "' href='$url' />\n";
                elseif ('option' == $format)
                    $link_html = "\t<option value='$url'>$before $text $after</option>\n";
                elseif ('html' == $format)
                    $link_html = "\t<li>$before<a href='$url'>$text</a>$after</li>\n";
                else // custom
                    $link_html = "\t$before<a href='$url'>$text</a>$after\n";

                $output .= $link_html;
            }
        }
    } elseif ( 'yearly' == $r['type'] ) {
        $query = "SELECT YEAR(post_date) AS `year`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date) ORDER BY post_date $order $limit";
        $key = md5( $query );
        $key = "wp_get_archives:$key:$last_changed";
        if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
            $results = $wpdb->get_results( $query );
            wp_cache_set( $key, $results, 'posts' );
        }
        if ( $results ) {
            $after = $r['after'];
            foreach ( (array) $results as $result) {
                $url = get_year_link( $result->year );
                $text = sprintf( '%d', $result->year );
                if ( $r['show_post_count'] ) {
                    $r['after'] = '&nbsp;(' . $result->posts . ')' . $after;
                }

                if( !empty($r['post_type']) ) {
                    $apt = implode( ',', $r['post_type'] );
                    $url = add_query_arg( 'apt', $apt, $url );
                }

                $format = (empty($r['format']))?('html'):($r['format']);
                $before = (empty($r['before']))?(''):($r['before']);
                $after = (empty($r['after']))?(''):($r['after']);

                $text = wptexturize($text);
                $url = esc_url($url);

                if ('link' == $format)
                    $link_html = "\t<link rel='archives' title='" . esc_attr( $text ) . "' href='$url' />\n";
                elseif ('option' == $format)
                    $link_html = "\t<option value='$url'>$before $text $after</option>\n";
                elseif ('html' == $format)
                    $link_html = "\t<li>$before<a href='$url'>$text</a>$after</li>\n";
                else // custom
                    $link_html = "\t$before<a href='$url'>$text</a>$after\n";

                $output .= $link_html;
            }
        }
    } elseif ( 'daily' == $r['type'] ) {
        $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, DAYOFMONTH(post_date) AS `dayofmonth`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date), DAYOFMONTH(post_date) ORDER BY post_date $order $limit";
        $key = md5( $query );
        $key = "wp_get_archives:$key:$last_changed";
        if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
            $results = $wpdb->get_results( $query );
            wp_cache_set( $key, $results, 'posts' );
        }
        if ( $results ) {
            $after = $r['after'];
            foreach ( (array) $results as $result ) {
                $url  = get_day_link( $result->year, $result->month, $result->dayofmonth );
                $date = sprintf( '%1$d-%2$02d-%3$02d 00:00:00', $result->year, $result->month, $result->dayofmonth );
                $text = mysql2date( get_option( 'date_format' ), $date );
                if ( $r['show_post_count'] ) {
                    $r['after'] = '&nbsp;(' . $result->posts . ')' . $after;
                }

                if( !empty($r['post_type']) ) {
                    $apt = implode( ',', $r['post_type'] );
                    $url = add_query_arg( 'apt', $apt, $url );
                }

                $format = (empty($r['format']))?('html'):($r['format']);
                $before = (empty($r['before']))?(''):($r['before']);
                $after = (empty($r['after']))?(''):($r['after']);

                $text = wptexturize($text);
                $url = esc_url($url);

                if ('link' == $format)
                    $link_html = "\t<link rel='archives' title='" . esc_attr( $text ) . "' href='$url' />\n";
                elseif ('option' == $format)
                    $link_html = "\t<option value='$url'>$before $text $after</option>\n";
                elseif ('html' == $format)
                    $link_html = "\t<li>$before<a href='$url'>$text</a>$after</li>\n";
                else // custom
                    $link_html = "\t$before<a href='$url'>$text</a>$after\n";

                $output .= $link_html;
            }
        }
    } elseif ( 'weekly' == $r['type'] ) {
        $week = _wp_mysql_week( '`post_date`' );
        $query = "SELECT DISTINCT $week AS `week`, YEAR( `post_date` ) AS `yr`, DATE_FORMAT( `post_date`, '%Y-%m-%d' ) AS `yyyymmdd`, count( `ID` ) AS `posts` FROM `$wpdb->posts` $join $where GROUP BY $week, YEAR( `post_date` ) ORDER BY `post_date` $order $limit";
        $key = md5( $query );
        $key = "wp_get_archives:$key:$last_changed";
        if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
            $results = $wpdb->get_results( $query );
            wp_cache_set( $key, $results, 'posts' );
        }
        $arc_w_last = '';
        if ( $results ) {
            $after = $r['after'];
            foreach ( (array) $results as $result ) {
                if ( $result->week != $arc_w_last ) {
                    $arc_year       = $result->yr;
                    $arc_w_last     = $result->week;
                    $arc_week       = get_weekstartend( $result->yyyymmdd, get_option( 'start_of_week' ) );
                    $arc_week_start = date_i18n( get_option( 'date_format' ), $arc_week['start'] );
                    $arc_week_end   = date_i18n( get_option( 'date_format' ), $arc_week['end'] );
                    $url            = add_query_arg( array( 'm' => $arc_year, 'w' => $result->week, ), home_url( '/' ) );
                    $text           = $arc_week_start . $archive_week_separator . $arc_week_end;
                    if ( $r['show_post_count'] ) {
                        $r['after'] = '&nbsp;(' . $result->posts . ')' . $after;
                    }

                    if( !empty($r['post_type']) ) {
                        $apt = implode( ',', $r['post_type'] );
                        $url = add_query_arg( 'apt', $apt, $url );
                    }

                    $format = (empty($r['format']))?('html'):($r['format']);
                    $before = (empty($r['before']))?(''):($r['before']);
                    $after = (empty($r['after']))?(''):($r['after']);

                    $text = wptexturize($text);
                    $url = esc_url($url);

                    if ('link' == $format)
                        $link_html = "\t<link rel='archives' title='" . esc_attr( $text ) . "' href='$url' />\n";
                    elseif ('option' == $format)
                        $link_html = "\t<option value='$url'>$before $text $after</option>\n";
                    elseif ('html' == $format)
                        $link_html = "\t<li>$before<a href='$url'>$text</a>$after</li>\n";
                    else // custom
                        $link_html = "\t$before<a href='$url'>$text</a>$after\n";

                    $output .= $link_html;
                }
            }
        }
    } elseif ( ( 'postbypost' == $r['type'] ) || ('alpha' == $r['type'] ) ) {
        $orderby = ( 'alpha' == $r['type'] ) ? 'post_title ASC ' : 'post_date DESC, ID DESC ';
        $query = "SELECT * FROM $wpdb->posts $join $where ORDER BY $orderby $limit";
        $key = md5( $query );
        $key = "wp_get_archives:$key:$last_changed";
        if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
            $results = $wpdb->get_results( $query );
            wp_cache_set( $key, $results, 'posts' );
        }
        if ( $results ) {
            foreach ( (array) $results as $result ) {
                if ( $result->post_date != '0000-00-00 00:00:00' ) {
                    $url = get_permalink( $result );
                    if ( $result->post_title ) {
                        /** This filter is documented in wp-includes/post-template.php */
                        $text = strip_tags( apply_filters( 'the_title', $result->post_title, $result->ID ) );
                    } else {
                        $text = $result->ID;
                    }

                    if( !empty($r['post_type']) ) {
                        $apt = implode( ',', $r['post_type'] );
                        $url = add_query_arg( 'apt', $apt, $url );
                    }

                    $format = (empty($r['format']))?('html'):($r['format']);
                    $before = (empty($r['before']))?(''):($r['before']);
                    $after = (empty($r['after']))?(''):($r['after']);

                    $text = wptexturize($text);
                    $url = esc_url($url);

                    if ('link' == $format)
                        $link_html = "\t<link rel='archives' title='" . esc_attr( $text ) . "' href='$url' />\n";
                    elseif ('option' == $format)
                        $link_html = "\t<option value='$url'>$before $text $after</option>\n";
                    elseif ('html' == $format)
                        $link_html = "\t<li>$before<a href='$url'>$text</a>$after</li>\n";
                    else // custom
                        $link_html = "\t$before<a href='$url'>$text</a>$after\n";

                    $output .= $link_html;
                }
            }
        }
    }

    if ( $r['echo'] ) {
        echo $output;
    } else {
        return $output;
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる