行き着く先はあんこ

WordPressにプラグインを使わずそこそこ精度の高い関連記事を表示する

似た内容の記事が関連記している

WordPressにプラグインを使わずに、そこそこ精度の高い関連記事を表示させる方法を備忘録もかねてまとめておきます。

スポンサーリンク

WordPressに関連記事を表示する

WordPressに関連記事を表示させるには「YARPP」といったプラグインがとても便利です。手軽に導入できるうえに、カテゴリやタグやタイトルなどから関連記事を選び出すため精度も非常に優れています。

しかし、今回はプラグインに頼らずに関連記事を表示させます。以下のサイトで紹介されている方法を使わせてもらいます。

参考タグとカテゴリで強弱を設定した関連記事を取得する | weblog by web.contempo.jp

この方法では記事に付けられているタグ、カテゴリ、カスタムタクソノミーの重複回数によって関連記事を選ぶようになっています。デフォルトではタグの優先度が最も高く、その次にカテゴリになっています。

functions.phpに追加するコード

functions.phpに追加するコードは以下のようになります。

//そこそこ精度の高い関連記事コード
function get_related_posts( $show_post = 5 ){
    $post_id = get_post()->ID;
    if ( empty( $post_id ) ) return;
    $target_posttype = get_post( $post_id )->post_type;

    // 関連記事の表示数
    $ex_show_post = get_post_meta( $post_id, '_my_relatedposts_shownum', true );
    // 関連記事の登録日
    $rel_date = get_post_meta( $post_id, '_my_relatedposts_update', true );
    // ブログの最終更新日
    $modified_date = mysql2date( 'Ymd', get_lastpostmodified(), false );
    // 検索する記事数 (-1なら全ての記事)
    $posts_per_page = -1;

    /* 関連記事が未登録 or 関連記事の登録日よりもあとに記事が更新されている
        or 関連記事の表示数が変わった、ときに新規で関連記事を設定する */
    if( empty($rel_date) || $modified_date > $rel_date || $show_post != $ex_show_post ){

        $rel_ids = array();
        // 使用タクソノミを取得(カテゴリ+カスタムタクソノミ)
        $taxes = get_object_taxonomies( get_post( $post_id )->post_type, 'names' );
        unset( $taxes['post_format'] ); // post_formatを除外
        $tax_count = count($taxes);
        $tax_array = array_fill( 0, $tax_count, '' );

        if ($taxes) { 
            foreach ( $taxes as $taxname ) {
		$terms = get_the_terms( $post_id, $taxname );
                if ( $terms ){
                    foreach ( $terms as $term ) {
                        $rel_ids[ $taxname ][] = $term->term_id; // タームIDを配列に入れる
                    }
                    $tax_array[] = array(
                        'taxonomy' => $taxname, // categoryとかpost_tagとか
                        'field' => 'id', // 'id' または 'slug'
                        'terms' => $rel_ids[ $taxname ], // int または string または array
                        'include_children' => false, // 子カテゴリを含まない
                        'operator' => 'IN',
                    );
                } 
            }
        }

        $args = array(
            'post__not_in' => array( $post_id ), // 表示している記事を除外
            'posts_per_page' => $posts_per_page, // 検索する記事数
            'post_status' => 'publish', // 公開記事に限定
            'post_type' => $target_posttype, // ターゲットポストタイプ
            'tax_query' => array_merge( array('relation' => 'OR'), $tax_array )
        );
        $rel_query = get_posts( $args );

        if ( $rel_query ) : foreach ($rel_query as $rel ):
            $rel_point = 0;
            $set_id = $rel->ID;
            foreach ( $taxes as $taxname ) {
                 $terms = get_the_terms( $set_id, $taxname );
                 if ( is_array($terms)) : foreach ( $terms as $term ):
                    if ( isset( $rel_ids[ $taxname ]) && in_array( $term->term_id , (array)$rel_ids[ $taxname ] ) ) { // 関連するIDを含んでいる
                        $rel_point++; 
                        if( $taxname == 'post_tag' ){ // タグの優先度を上げる
                            $rel_point++;
                        }
                    }
                endforeach; endif;
            }
             $rel_with[ $set_id ] = intval($rel_point); // 関連度数
        endforeach; endif; 
        if ( !empty( $rel_with ) ) {
            arsort( $rel_with ); // 関連度数を降順で並び替え
            $i = 0;
            foreach ( $rel_with as $key => $val ) { 
                if( $i >= $show_post ) { 
                    break;
                } else {
                    $rel_posts[] = $key;
                    $i++;
                }
            }
            update_post_meta( $post_id, '_my_relatedposts', $rel_posts );
        } else {
            $no_related = false;
            update_post_meta( $post_id, '_my_relatedposts', $no_related );
        }
        $timestamp = date( 'Ymd' );
        update_post_meta( $post_id, '_my_relatedposts_update', $timestamp );
        update_post_meta( $post_id, '_my_relatedposts_shownum', $show_post );
    }
    $return_array = get_post_meta( $post_id, '_my_relatedposts', true );
    return $return_array;
}

参考にしたサイトに書かれているように、関連記事IDは個々の記事のカスタムフィールドに登録されているため、関連記事が更新されないときの処理速度は遅くありません。

また、標準ではタグの優先度が高いようになっていますが、カテゴリの優先度を高くしたければ

if( $taxname == 'post_tag' )

のとろこを

if( $taxname == 'category' )

に変更することで対応できます。

関連記事IDを取得して表示する

上で作成した関数get_related_posts()を呼ぶと、関連記事の記事IDが配列で取得できます。あとは表示したいところでループさせて関連記事を表示させます。

一例としてこのサイトではこんな感じで表示させています。

<?php $related_posts = get_related_posts(6); ?>
<div id="related-posts">
    <h3>関連記事</h3>
    <div class="related-posts-box">
        <?php if ( $related_posts ): foreach( $related_posts as $rid ): ?>
            <article>
                <a href="<?php the_permalink( $rid ); ?>" title="<?php echo get_the_title( $rid );>
                    <?php if ( has_post_thumbnail( $rid ) ):
                        $thumb_id = get_post_thumbnail_id( $rid );
                        $thumb_url = wp_get_attachment_image_src($thumb_id, 'thumbnail'); ?>
                        <img src="<?php echo $thumb_url[0]; ?>">
                    <?php endif; ?>
                    <div><h4><?php echo get_the_title( $rid ); ?></h4></div>
                </a>
            </article>
        <?php endforeach;
        else: ?>
            <p>関連する記事はありませんでした。</p>
        <?php endif; ?>
    </div>
</div>

関連記事の表示数はデフォルトで5つになっていますが、

<?php $related_posts = get_related_posts(6); ?>

のように関数get_related_postsに引数を渡すことで表示数を変更できます。

また、サムネイル画像のサイズ変更には

wp_get_attachment_image_src($thumb_id, 'thumbnail')

の「thumbnail」部分を

wp_get_attachment_image_src($thumb_id, 'medium')
wp_get_attachment_image_src($thumb_id, array( 100, 100 ))

のように変更することで対応できます。

さいごに

これでプラグインを使わなくてもそこそこ精度の高い関連記事を表示することができるようになりました。より精度を高めるにはタグ付けが非常に重要になりますが、タグに関して考え改めるいい機会にもなりました。

さいごに、この関数の根幹に関わる部分は参考にしたサイトで紹介されているコードをほぼそのまま使わせてもらいました。製作者さんには感謝感謝です。

参考タグとカテゴリで強弱を設定した関連記事を取得する | weblog by web.contempo.jp

スポンサーリンク

スポンサーリンク

コメントを残す