制作案件でクライアントから、記事内に「合わせて読みたい」のリンクを入れられるようにしたいという要望をいただきました。こんなやつです。
特別難しいそうなことでもないのでプラグインで簡単にできるでしょ?と思っていました。しかし、確かにその手のプラグインはあるのですが、どうも痒い所に手が届かないというか、そんな高機能はいらないというか、なんというか。。。
そこで以前からやろうと思っていたものの、なかなか手をつけなかったショートコードで自作してしまおう!という結論に至りました。
ということで自作ショートコードで「合わせて読みたい」を出力できる様にしていきたいと思います。
今までにショートコードの基本を書いた記事がありますので、「ショートコードがまだよくわからない」という方はぜひ見てみてくださいね。
合わせて読みたい
Contents
今回の仕様
上の目次にあるのですが、ざっと下記の仕様を想定します。必要な機能を洗い出しておくことはとても大事です。
- 記事IDを引数に記事の内容を取得できる様にする
- 記事IDをカンマ区切りで複数指定できる様にする
- 「合わせて読みたい」のラベルも引数で変更できるようにする
- 取得する内容は記事へのパーマリンク、アイキャッチ画像、タイトル、日付
- 引数の入力エラーをハンドリング
実際のコード
php
//合わせて読みたいショートコード function related_func ( $atts ) { extract( shortcode_atts( array( 'id' => '', 'label' => '合わせて読みたい', ), $atts ) ); $ids = mb_split(",",$id); $outputTag = ''; if($id): $outputTag .= ' <div class="awasete"> <h5 class="awasete__title"> <span><i class="fas fa-link"></i>' . $label . '</span> </h5> <ul class="awasete__list">'; foreach($ids as $value): if(ctype_digit($value)): $link = get_permalink($value); $title = get_the_title($value); $date = get_the_time('Y.m.d',$value); if(get_post_thumbnail_id($value)){ $thmbnail_url = wp_get_attachment_url(get_post_thumbnail_id( $value )); }else{ $thmbnail_url = '/wp-content/themes/wdd2/images/common/no-image.jpg'; } $outputTag .=' <li class="awasete__list__item"> <a class="awasete__list__item__link flex flex--bet" href="'. $link . '" target="_blank"> <figure class="awasete__list__item__link__image"> <img src="' . $thmbnail_url . '"> </figure> <div class="awasete__list__item__link__content"> <h6 class="awasete__list__item__link__content__title">' . $title . '</h6> <time class="awasete__list__item__link__content__date">' . $date . '<time> </div> </a> </li>'; else: $outputTag .='<li class="awasete__list__item">記事IDの指定が正しくありません</li>'; endif; endforeach; $outputTag .= '</ul></div>'; return $outputTag; else: return ' <div class="awasete"> <h5 class="awasete__title"> <span><i class="fas fa-link"></i>' . $label . '</span> </h5> <ul class="awasete__list">記事IDがありません</ul> </div>'; endif; } add_shortcode('related', 'related_func');
出力されるHTML
<div class="awasete"> <h5 class="awasete__title"> <span>入力したラベル</span> </h5> <ul class="awasete__list"> <li class="awasete__list__item"> <a class="awasete__list__item__link flex flex--bet" href="記事のパーマリンク" target="_blank"> <figure class="awasete__list__item__link__image"> <img src="アイキャッチ画像のパス"> </figure> <div class="awasete__list__item__link__content"> <h6 class="awasete__list__item__link__content__title">記事のタイトル</h6> <time class="awasete__list__item__link__content__date">記事の日付<time> </div> </a> </li> </ul> </div>
CSS
/*合わせて読みたい*/ .awasete{ margin-bottom: 20px; } .awasete .awasete__title{ border: none; margin: 0; padding: 0; } .awasete .awasete__title span{ background: #333; color: #fff; display: inline-block; font-size: 14px; padding:5px 10px; } .awasete .awasete__title i{ margin-right: 5px; } .awasete .awasete__list{ border: 1px solid #ccc; padding: 20px; } .awasete .awasete__list__item{ list-style: none; margin:0 0 20px 0; } .awasete .awasete__list__item:last-child{ margin-bottom: 0; } .awasete .awasete__list__item__link{ text-decoration: none; box-shadow: none; } .awasete .awasete__list__item__link__image{ width: 20%; } .awasete .awasete__list__item__link__image img{ height: auto; width: 100%; } .awasete .awasete__list__item__link__content{ width: 75%; } .awasete .awasete__list__item__link__content__title:before{ content: none; } .awasete .awasete__list__item__link__content__date{ color: #666; font-size: 14px; }
HTML・CSS、お好きなように修正してください。
管理画面で入力するショートコード
{related id=4175 label=これも読んでね}
ショートコードが実行されてしまうので「[]」ブラケットを変えています。
出力結果
コード解説
記事IDを引数に記事の内容を取得できる様にする
extract( shortcode_atts( array( 'id' => '', 'label' => '合わせて読みたい', ), $atts ) );
今回の引数は記事IDとボックスのラベルですので定義します。
- 記事ID:id
- ボックスラベル:label
としました。
記事IDをカンマ区切りで複数指定できる様にする
$ids = mb_split(",",$id);
引数に入力された値を「,」で分けて配列にしています。こちらを後ほどphpの「foreach」で配列の数だけ回します。
「合わせて読みたい」のラベルも引数で変更できるようにする
'label' => '合わせて読みたい',
前述の通り、「label」という引数を定義ました。こちらは引数の入力がない場合のデフォルト値を「合わせて読みたい」にしました。
取得する内容は記事へのパーマリンク、アイキャッチ画像、タイトル、日付
foreach($ids as $value): if(ctype_digit($value)): $link = get_permalink($value); $title = get_the_title($value); $date = get_the_time('Y.m.d',$value); if(get_post_thumbnail_id($value)){ $thmbnail_url = wp_get_attachment_url(get_post_thumbnail_id( $value )); }else{ $thmbnail_url = 'アイキャッチ画像がない場合の代替画像のパス'; } $outputTag .=' <li class="awasete__list__item"> <a class="awasete__list__item__link flex flex--bet" href="'. $link . '" target="_blank"> <figure class="awasete__list__item__link__image"> <img src="' . $thmbnail_url . '"> </figure> <div class="awasete__list__item__link__content"> <h6 class="awasete__list__item__link__content__title">' . $title . '</h6> <time class="awasete__list__item__link__content__date">' . $date . '<time> </div> </a> </li>'; else: $outputTag .='<li class="awasete__list__item">記事IDの指定が正しくありません</li>'; endif; endforeach;
変数「$ids」にはカンマで分けた引数が配列で入っていますので「foreach」で配列の数だけ処理を行っていきます。
- 21行目 記事のパーマリンクをIDから取得して変数「$link」に代入。
- 22行目 記事のタイトルをIDから取得して変数「$title」に代入。
- 23行目 記事の日付をIDから取得して変数「$date」に代入。
- 24〜28行目 アイキャッチ画像があるか判別し、あればアイキャッチ画像のパスを変数「$thmbnail_url」に代入。なければ代替画像のパスを「$thmbnail_url」に代入。(代替画像のパスは環境に合わせて変えてください)
引数の入力エラーをハンドリング
ここがとても重要です。自分のサイトであれば入力する引数の形式をしっかり守ればいいのですが、お客さんに納品する場合はそうはいきません。想定以外の引数を入力されることもありますので、エラーハンドリングしましょう。今回は下記のように入力エラーをハンドリングしました。
if($id)://記事IDの入力がある foreach($ids as $value): if(ctype_digit($value))://入力された記事IDが数値である //記事IDの入力が正しい場合の処理 else://入力された記事IDが数値ではない //記事IDが数値ではないエラーを出力 endif; endforeach; else://記事IDの入力がない //記事IDの入力がないエラーを出力 endif;
まず「if($id):」で引数である記事IDの入力があるか判別し、なければ記事IDの入力がない旨のエラーメッセージを出力します。
次に記事IDの入力はあるが正しく数値であるか「if(ctype_digit($value)):」で判別し、数値ではない場合はその旨のエラーメッセージを出力します。
まとめ
「合わせて読みたい」を記事内に入れるショートコードを作ってみましたがいかがだったでしょうか?長くなるので書きませんが、ラベルやボックスの色も引数で指定できるようにすれば、色々なバリエーションの「合わせて読みたい」ボックスの出力ができます。
そして引数が増えても行っても、プラグイン「AddQuicktag」でショートコードを登録しておけば、ボタンのクリックのみでショートコードを挿入できます。ショートコードと「AddQuicktag」のコンボは、私的にかなり使い勝手がよく助かっております。ぜひ「AddQuicktag」の使い方の記事もアップしたいと思います。
合わせて読みたい
それでは良いWEBデザイン日和を!Have a nice WEBDESIGNDAY!