概要
webサイトを運営している際に記事の終わりやサイドバーなどに特定の記事を表示したい場合があります。
具体的には新着記事や関連記事、ランキングなどではなく見てもらいたい記事を自分で選んで表示したいような時です。
よくある方法だとこのあたりでしょうか。
- プラグイン「Related Posts」などを使う方法
- ウィジェットのテキスト欄に記事へのリンクをhtmlで記述する方法
- プラグイン「Advanced Custom Fields」でピックアップ記事にするためのチェックボックスを設ける方法
- プラグイン「Advanced Custom Fields」で任意の番号が設定されているものをピックアップ記事として出力する方法
確かにこちらの方法でも任意のピックアップ記事を表示することは出来ます。
ただ、出力したい情報をコントロール出来ない、htmlがわからないと更新できない、並び替えができないなどそれぞれデメリットもあります。
今回やりたいことをまとめるとこのようになります。
- 任意の記事を選べる(ドラッグ&ドロップで選べる)
- htmlがわからなくても更新できる
- 選んだ記事を自由に並び替えできる
- 出力できる情報をカスタムできる
これを実現するために今回はWordPressのメニューをカスタマイズして特定のピックアップ記事を表示する方法を紹介します。
制作会社さんなどがサイトを制作し、更新作業などはクライアントにお任せする場合などにオススメです。
まずは管理画面で新しくメニューを作成する
こちらの画面をご覧になったことはありますでしょうか。
管理画面 > 外観 > メニューで表示される画面です。グローバルナビやフッターナビを設定する際に使う場所ですね。
今回はこれをカスタムしていきます。
まずは今回使用するカスタムメニューを作成します。
自作のテーマを使っていて外観にメニューの項目がないよーって方もこちらのコードをfunction.phpに追加してメニューを追加しましょう。
<pre class="line-numbers"><code class="language-markup">//カスタムメニューを作成
register_nav_menus( array(
'pickup' => 'ピックアップ',
) );</code></pre>
追加したら管理画面 > 外観 > メニューより新規メニューを作成。メニューの位置はピックアップにチェックを入れます。
ちなみにピックアップなどはわかりやすいように名前をつけただけなので任意の名前でOKです。
まずはこのようになれば準備完了です。
では実際にピックアップする記事を選んでみましょう。
左側の投稿の部分からピックアップしたい記事を選んでメニューに追加します。
この方法であればhtmlなどがわからなくても好きな記事を選ぶだけ。並び替えもできてとても便利ですね。
記事を選ぶとこのようになります。
いくらでも記事を足すことはできますが、今回は3件を表示することにします。
これで下準備は整いました。
続いて出力する方法を紹介します。
function.phpに出力内容を記述
普通に出力するだけであればこのように記述すればOKです。
wp_nav_menu( array(
'theme_location' => 'pickup',
) );
出力結果はこのようになります。
<ul id="menu-xxx" class="menu">
<li id="menu-item-xxx" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-xxx"><a href="https://hoge.com/huga1/">記事タイトル1</a></li>
<li id="menu-item-xxx" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-xxx"><a href="https://hoge.com/huga2/">記事タイトル2</a></li>
<li id="menu-item-xxx" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-xxx"><a href="https://hoge.com/huga3/">記事タイトル3</a></li>
</ul>
デフォルトの出力ですが一応これでもピックアップ記事を選んで表示は出来ているといえば出来ています。
ただ、この記事を読まれている方は欲しい情報はそれじゃない。サムネイル画像とかカテゴリー、投稿日とかを出力したいんだよー!って方もいらっしゃると思います。
サムネイル画像や本文などカスタムメニューの出力内容を変更する場合はfunction.phpにこのような記述をする必要があります。
//メニューの出力内容をカスタム
class Walker_Nav_Menu_Custom extends Walker_Nav_Menu {
function start_el( & $output, $item, $depth, $args ) {
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
$classes = empty( $item->classes ) ? array() : ( array )$item->classes;
$classes[] = 'menu-item-' . $item->ID;
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ) );
// 不要なIDを削除してli要素に任意のクラスをつける
$id = apply_filters( 'nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args, $depth );
$id = $id ? ' id="' . esc_attr( $id ) . '"': '';
$class_names = $class_names ? ' class="archive"' : '';
$output .= $indent . '<li' . $class_names . '>';
$atts = array();
$atts[ 'title' ] = !empty( $item->attr_title ) ? $item->attr_title : '';
$atts[ 'target' ] = !empty( $item->target ) ? $item->target : '';
$atts[ 'rel' ] = !empty( $item->xfn ) ? $item->xfn : '';
$atts[ 'href' ] = !empty( $item->url ) ? $item->url : '';
$atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth );
$attributes = '';
foreach ( $atts as $attr => $value ) {
if ( !empty( $value ) ) {
$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
$attributes .= ' ' . $attr . '="' . $value . '"';
}
}
$item_output = $args->before;
$item_output .= '<a' . $attributes . '>';
//サムネイル画像を追加・画像にclass[thumnail-img]を付与
$item_output .= '<figure>';
$item_output .= get_the_post_thumbnail( $item->object_id, thum - image, array( 'class' => 'thumnail-img' ), array( 'alt' => $item->title ) );
$item_output .= '</figure>';
//日付・カテゴリーを<div class="span-wrap">で囲って出力
$item_output .= '<div class="span-wrap">';
$cat = get_the_category( $item->object_id );
$catName = $cat[ 0 ]->name;
$item_output .= '<span class="cat">' . $catName . '</span>';
$item_output .= '<span class="date">' . get_the_date( 'Y/m/d', $item->object_id ) . '</span>';
$item_output .= '</div>';
//タイトルを表示
$item_output .= '<p class="title">' . $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after . '</p>';
//本文の抜粋を表示
$item_output .= '<p class="text">';
$post = get_post( $item->object_id );
$item_output .= mb_substr( strip_tags( $post->post_content ), 0, 50 );
$item_output .= '...</p>';
$item_output .= '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}
ちょっと長いかとは思いますが、これで出力する内容を変更することが可能です。
尚、環境によっては(php7.0をサーバーで使っている場合など)function.phpに「class Walker_Nav_Menu〜」の記述をした段階でエラーがでる場合があります。
その際はこちらの記事を参照してください。
サーバーのphpを7.0にした際に出る【Warning: Declaration of My_Walker::start_el〜】の対処方法
出力をさせたい場所でカスタムメニューを呼び出す
あとは実際に出力させたい場所(page.phpなど)にこのコードを記述。
<?php
wp_nav_menu( array(
'theme_location' => 'pickup',
'walker' => new Walker_Nav_Menu_Custom(),
'container' => '',
'menu_class' => '',
'items_wrap' => '<ul class="archiveWrap">%3$s</ul>' ) );
?>
画像につくsrcset属性などは環境によって違うかと思うので細かいところは省きますがおおよそこのような出力となります。
<ul class="archiveWrap">
<li class="archive"><a href="https://hoge.com/huga1/">
<figure><img src="https://hoge.com/xxx/huga1.jpg" class="thumnail-img" alt=""></figure>
<div class="span-wrap"><span class="cat">カテゴリー名</span><span class="date">2017/00/00</span></div>
<p class="title">記事タイトル1</p>
<p class="text">記事1の抜粋が入ります(文字数指定や最後の...などはご自由に設定してください)...</p>
</a></li>
<li class="archive"><a href="https://hoge.com/huga2/">
<figure><img src="https://hoge.com/xxx/huga2.jpg" class="thumnail-img" alt=""></figure>
<div class="span-wrap"><span class="cat">カテゴリー名</span><span class="date">2017/00/00</span></div>
<p class="title">記事タイトル2</p>
<p class="text">記事2の抜粋が入ります(文字数指定や最後の...などはご自由に設定してください)...</p>
</a></li>
<li class="archive"><a href="https://hoge.com/huga3/">
<figure><img src="https://hoge.com/xxx/huga3.jpg" class="thumnail-img" alt=""></figure>
<div class="span-wrap"><span class="cat">カテゴリー名</span><span class="date">2017/00/00</span></div>
<p class="title">記事タイトル3</p>
<p class="text">記事3の抜粋が入ります(文字数指定や最後の...などはご自由に設定してください)...</p>
</a></li>
</ul>
今回は見本で作成したのでclassなどてんこ盛りですが、必要な部分だけ抜粋して使っていただければと思います。