WordPressのショートコードを自作して記事カードを作成する方法
2020.11.09記事の中にサイト内から関連する別の記事の情報を案内するリンクを良く見かけると思いますが、あの機能はWordPressに元々備わっているWordPress(4.4以上)の記事カード機能であったり、テーマやプラグインの機能であったりします。プラグインの機能を使えば簡単に実装できそうですが、今後自身のテーマをカスタマイズするにあたってオリジナルで記事カードを作成しようと思いました。
仕組みとしてはショートコードを作成し、そこへ記事のidをセットしWordPressの中から記事の情報を取得、サムネイルやタイトルや本文の情報などを整形して出力し、cssでスタイルを整えるといったものになります。それでは行った作業を解説していきます。
目次
ショートコードの基本構成
まずはショートコードの作成を説明していきます。ショートコードは様々な用途に使用できるので覚えておくとブログカスタマイズの幅が広がります。ではまずショートコード作成するためにfunctions.phpへの基本的な記述を説明します。
/*-----------------------------------
基本ショートコード
-----------------------------------*/
function custom_sc_func() {
$sample_text = '<p>こんにちわ!</p>';
//echoでなくreturnで返す。
return $sample_text;
}
add_shortcode( 'add_custom_sc', 'custom_sc_func' );
//記事中に[add_custom_sc]を挿入
上記コードをfunctions.phpへ追記することによって記事内に[add_custom_sc]と挿入すれば公開側の記事ページには「こんにちわ!」という文章が出力されます。
基本的な構成は、ショートコード作成用のフック add_shortcode() を使ってタグ(WordPressで使用する関数)を作成していきます。
上記の例では記事内に[add_custom_sc]と入れることによって custom_sc_func() の関数が呼ばれ、結果$sample_textの変数がreturnで返されて「こんにちわ!」が表示されるというわけです。
ショートコードに引数をセットして処理する
今回は記事のidをショートコードで渡し、記事の情報を返してもらいので引数(パラメータ)を追加していきます。
//複数の値を引数で渡すショートコード
[add_custom_sc id1=100 id2=200 id3=300]
今回は複数の引数を変数付きでセットしました。引数の書き方は、それぞれスペースを空けます
function custom_sc_func( $atts ) {
$id01 = $atts['id1'];
$id02 = $atts['id2'];
$id02 = $atts['id3'];
$return_text = '取得したidは' . $id01 . 'と' . $id02 . 'と' . $id03 . 'です';
return $return_text;
}
add_shortcode( 'add_custom_sc', 'custom_sc_func' );
//取得したidは100と200と300です
ショートコードへセットした引数は一つだろうと複数だろうと配列として渡されます。ショートコードにセットした引数に上記のように変数を使用すれば、配列として受け取ったときに添え字として指定ができるので便利です。もし変数を指定しなかった場合はショートコードにセットされた引数の順に0.1.2…といった添え字になります。
ショートコードで記事idを受け取り必要な情報を取得
さて、ショートコードでの情報の受け渡しの基本が分かったところで、本題である記事情報の取得を行います。今回のショートコードで受け取る情報は記事idだけですので引数がひとつという事になります。
//記事idをセットして記事カードを作成する
[sc_post_card id=120]
上記のショートコードを記事内にショートコードとしてセットします。idが120の記事情報を取得し、必要な情報を抜き出して扱いやすいように生成して記事内に返します。
/*-----------------------------------
記事カード用ショートコード
-----------------------------------*/
function sc_post_add_func($values) {
//記事idを取得しサムネイル情報をセット
$add_post_id = $atts['id'];
if( get_the_post_thumbnail_url( $add_post_id, 'thumbnail' ) ) {
$thumbnail_url = get_the_post_thumbnail_url( $add_post_id, 'thumbnail' );
$img_class = '';
} else {
$thumbnail = '';
$img_class = ' noImg';
}
//リンク取得
$link = get_permalink( $add_post_id );
//タイトル取得
$title = get_the_title( $add_post_id );
//本文取得
$post_txt = strip_tags(strip_shortcodes( get_post( $add_post_id )->post_content ) );
//文字数
$num = 120;
if( mb_strlen( $post_txt, 'UTF-8' ) > $num ){
$post_text = mb_substr( $post_txt, 0, $num, 'UTF-8' ) . '...';
} else {
$post_text =$post_txt;
}
//出力用タグ生成
$post_card = '';
$post_card = '<div class="addPost"><a href="' . $link . '" target="_blank">';
$post_card .= '<div class="img' . $img_class . '"><img src="' . $thumbnail_url . '" width="180" height="auto" alt=""></div><div class="txt">';
$post_card .= '<dl><dt>' . $title . '</dt><dd>' . $post_text . '</dd></dl>';
$post_card .= '</div></a></div>';
return $post_card;
}
add_shortcode( 'sc_post_card', 'sc_post_add_func' );
今回取得して返す情報は、記事のURL、サムネイル、タイトル、本文の指定文字数です。それでは分割して説明していきます。
記事idからサムネイルを取得
//記事idを取得しサムネイル情報をセット
$add_post_id = $atts['id'];
if( get_the_post_thumbnail_url( $add_post_id, 'thumbnail' ) ) {
$thumbnail_url = get_the_post_thumbnail_url( $add_post_id, 'thumbnail' );
$img_class = '';
} else {
$thumbnail = '';
$img_class = ' noImg';
}
idが120の記事を記事カードとして表示させるために、記事の中に[sc_post_card id=120]といったショートコードを挿入しました。$add_post_id = $atts[‘id’];で記事idの引数(120)を受け取りましたので、get_the_post_thumbnail_url()にてサムネイルを取得します。
念のためアイキャッチが登録されておらずサムネイル情報が取得できなかったときの処理も記述しておきます。
リンク、タイトル、本文の取得
//リンク取得
$link = get_permalink( $add_post_id );
//タイトル取得
$title = get_the_title( $add_post_id );
//本文取得
$post_txt = strip_tags(strip_shortcodes( get_post( $add_post_id )->post_content ) );
//文字数
$num = 120;
if( mb_strlen( $post_txt, 'UTF-8' ) > $num ){
$post_text = mb_substr( $post_txt, 0, $num, 'UTF-8' ) . '...';
} else {
$post_text =$post_txt;
}
リンク、タイトル、本文の取得は上記のとおりですが、本文の場合文字数が多すぎるので返す文字数を指定します。また、文字数を指定する前にテキストの整形を行ってます。
strip_shortcodes()は記事内にショートコードが入っていた場合削除します。なおかつstrip_tags()によって文字列からHTMLやPHPなどのタグを取り除きなるべく文字情報だけにしていきます。
本文のテキストの整形が完了したら最大取得文字数を任意の文字数(ここでは120)を指定して$post_textにセットしてます。
HTMLタグとクラスの割り当て
//出力用タグ生成
$post_card = '';
$post_card = '<div class="addPost"><a href="' . $link . '" target="_blank">';
$post_card .= '<div class="img' . $img_class . '"><img src="' . $thumbnail_url . '" width="180" height="auto" alt=""></div><div class="txt">';
$post_card .= '<dl><dt>' . $title . '</dt><dd>' . $post_text . '</dd></dl>';
$post_card .= '</div></a></div>';
必要な情報を取得して整形しましたので、あとは返してスタイルをあてる為にHTMLタグにセットしてクラス名を割り当てました。
$post_cardの変数を一旦初期化して「.=」にて必要な情報を追加していってます。一気に記述しても良いですが、後々手を加えることを考えると分割した方が都合が良さそうでしたので上記のような記述になってます。ここは自身で書きやすいやり方で構いません。
最後にreturnで情報を返します。
スタイルの調整
<div class="addPost">
<a href="#" target="_blank">
<div class="img"><img src="#" width="180" height="auto" alt=""></div>
<div class="txt">
<dl>
<dt>取得したタイトル</dt>
<dd>120文字以内の本文...</dd>
</dl>
</div>
</a>
</div>
rerturnによって記事には上記のようなHTMLタグが返されました。そのままだただの羅列になってしまうのでスタイルをあてて見やすいように調整します。
/* addPost
----------------------------------------------------------------*/
.addPost {
margin: 20px 0;
}
.addPost a {
background-color: #f9f9f9;
border: solid 1px #EEE;
text-decoration: none;
color: #000;
display: -webkit-flex;
display: flex;
-webkit-justify-content: space-between;
justify-content: space-between;
padding: 20px;
position: relative;
}
.addPost a::after {
content: "";
position: absolute;
width: 0;
height: 0;
border: 15px solid transparent;
border-top: 15px solid #333;
transform: rotate(-45deg);
right: -16px;
bottom: -16px;
}
.addPost a:hover {
opacity: 0.7;
}
.addPost a .img {
margin-right: 20px;
}
.addPost a .txt dl dt {
font-weight: bold;
font-size: 2.0rem;
margin: 0 0 10px;
}
.addPost a .txt dl dd {
font-size: 1.4rem;
}
HTMLをスタイルで調整して一通り完了です。今回作成したショートコード機能を使って記事カードを表示させた結果が下記になります。
最後に
ショートコードを使って記事カードの作成を説明しました。今回は記事カードでしたが、ショートコードは、あらかじめ登録しておけば記事の中に広告を入れたりバナーを入れたりするときに少ない文字数で表示させることができるので大変便利です。また、
echo do_shortcode('[ショートコード]');
とすることによってテンプレートの中でも使用できるので、さらにカスタマイズの幅が広がります。WordPressをカスタマイズしている人は知っておいて損はありません。ぜひ使いこなして役に立ててください。