Wordpressで投稿の本文中に別投稿タイプの記事の情報をショートコードで埋め込む
こんにちわ山崎です。
今回はショートコードを使って記事に他の投稿タイプの情報を埋め込むやり方をご紹介します。
例えばお知らせの中の本文中に同じくCMSで作成している別投稿タイプの内部リンクを貼りたいといったことがたまにあると思います。 それを埋め込むのにHTML手打ちではなく決められたフォーマットで記事のIDを埋め込むだけでモジュールを作れたらいいと思い、開発に至りました。
今回は、飲食店のブログの中にカスタム投稿タイプの店舗情報を埋め込むという程でサンプルを作りました。
店舗情報の作成
店舗情報のカスタム投稿タイプを定義
投稿タイプのregister_post_type
関数で定義します。テーマ内のfunctions.phpに以下を追加してください。
function create_post_type()
{
$supports = [
'title',
'editor',
'thumbnail',
'revisions',
'page-attributes'
];
register_post_type('store',
[
'labels' => [
'name' => '店舗情報',
'singular_name' => '店舗情報',
'menu_name' => '店舗情報',
'name_admin_bar' => '店舗情報',
'add_new' => '新規追加',
'add_new_item' => '新規店舗情報を追加',
'new_item' => '新規店舗情報を追加',
'edit_item' => '店舗情報を編集',
'view_item' => '店舗情報を表示',
'all_items' => '店舗情報',
'search_items' => '店舗情報を検索',
'not_found' => '店舗情報が見つかりませんでした。',
'not_found_in_trash' => 'ゴミ箱内にが店舗情報見つかりませんでした。'
],
'public' => true,
'has_archive' => true,
'menu_position' => 4,
'supports' => $supports,
]
);
}
add_action('init', 'create_post_type');
このあたりの詳しい説明は省略します。
店舗情報のカスタムフィールドを作成
次に店舗情報の中に詳しい情報が埋め込めるよう、カスタムフィールドを定義していきます。 「Advanced Custom Field」というプラグインをインストールして有効化してください。
有効化が完了したら、カスタムフィールドの新規作成から以下のフィールドを作成します。
フィールドラベル | フィールド名 | タイプ |
---|---|---|
電話番号 | tel | テキスト |
住所 | address | テキスト |
アクセス | access | テキストエリア |
コメント | comment | テキストエリア |
そしてこのフィールドを表示する条件のところを投稿タイプ、等しい、店舗情報にしてください。
ここまでで店舗情報が作成できるようになったので、適当に入力して店舗情報の投稿を1つ作ってください。
通常の投稿タイプから店舗情報を呼び出す。
ショートコードの作成
WordPressでショートコードを追加するには、add_shortcode
という関数を使用します。
add_shortcode('ショートコードのタグ', 'コールバック関数');
第一引数にショートコードを判別するためのタグの文字列を入れます。例えば、[some_shortcode]
でショートコードを呼び出したい場合、add_shortcode
の第一引数にsome_shortcode
と入れます。
そして第ニ引数でコールバック関数名の文字列を指定します。
ショートコードで呼び出すコールバック関数を定義していきます。
function get_store_info($attr)
{
$store = isset($attr['store_id']) ? get_post($attr['store_id']) : null;
if($store && $store->post_type === 'store') {
$thumbnail_id = get_post_thumbnail_id($store->ID);
$thumbnail_src = wp_get_attachment_image_src($thumbnail_id, 'thumbnail');
$html = '<div class="store-box"><h3>店舗情報</h3>';
$html .= '<div class="store-wrap">';
$html .= '<a href="' . get_permalink($store->ID) . '"><img src="' . $thumbnail_src[0] . '" alt=" ' . $store->post_title . ' ">';
$html .= '<div class="store-right">';
$html .= '<p class="store-name"><a href="' . get_permalink($store->ID) . '">' . $store->post_title . '</a></p>';
$html .= '<table>';
$html .= '<tr><th>電話</th><td>' . get_field('tel', $store->ID) . '</td></tr>';
$html .= '<tr><th>住所</th><td>' . get_field('address', $store->ID) . '</td></tr>';
$html .= '<tr><th>アクセス</th><td>' . get_field('access', $store->ID) . '</td></tr>';
$html .= '</table>';
$html .= '<p class="store-comment">' . get_field('comment', $store->ID) . '</p>';
$html .= '</div>';
$html .= '</div>';
$html .= '</div>';
return $html;
}
}
add_shortcode('store_info', 'get_store_info');
コールバックの第一引数にはショートコードで使用している属性の配列が入ってきます。
上記のコードの場合、$attr['属性名']
と記述すると、ショートコードの属性値が取れます。
$store = isset($attr['store_id']) ? get_post($attr['store_id']) : null;
if($store && $store->post_type === 'store') {
//以下略
}
ショートコードのstore_idという属性に店舗情報のIDを埋め込み、get_post
で対象IDの店舗情報を取得します。
念のため、$store
がnullだった場合や、別の投稿タイプの記事だった場合も考慮して条件分岐をしています。
$thumbnail_id = get_post_thumbnail_id($store->ID);
$thumbnail_src = wp_get_attachment_image_src($thumbnail_id, 'thumbnail');
$html = '<div class="store-box"><h3>店舗情報</h3>';
$html .= '<div class="store-wrap">';
$html .= '<a href="' . get_permalink($store->ID) . '"><img src="' . $thumbnail_src[0] . '" alt=" ' . $store->post_title . ' ">';
$html .= '<div class="store-right">';
$html .= '<p class="store-name"><a href="' . get_permalink($store->ID) . '">' . $store->post_title . '</a></p>';
$html .= '<table>';
$html .= '<tr><th>電話</th><td>' . get_field('tel', $store->ID) . '</td></tr>';
$html .= '<tr><th>住所</th><td>' . get_field('address', $store->ID) . '</td></tr>';
$html .= '<tr><th>アクセス</th><td>' . get_field('access', $store->ID) . '</td></tr>';
$html .= '</table>';
$html .= '<p class="store-comment">' . get_field('comment', $store->ID) . '</p>';
$html .= '</div>';
$html .= '</div>';
$html .= '</div>';
return $html;
あとは取得した投稿を元にHTMLを作ってそれを返す処理をしてあげればOKです。
ブログを投稿(店舗情報のIDが10の場合)
いつもOOをご利用いただきありがとうございます。 この度OO月OO日午前OO時に新店舗となるOO店をオープンすることになりました。 これからもOOをよろしくお願いします! 店舗の詳細はこちら [store_info store_id="10"]
プレビュー
店舗情報をブログに組み込むことができました!
今回省略しましたが、追加したCSSは以下になります。
.store-box {
display: inline-block;
border: 1px solid #ccc;
padding: 20px;
}
.store-box h3 {
text-align: center;
}
.store-box .store-wrap {
display: flex;
justify-content: center;
align-items: flex-start;
}
.store-box .store-right {
margin-left: 30px;
}
.store-box .store-name {
margin: 0 0 20px;
font-size: 16px;
font-weight: bold;
line-height: 1em;
}
.store-box table {
margin: 0 0 0;
}
.store-box th,
.store-box td {
font-size: 12px;
}
.store-box .store-comment {
margin: 0 0 5px;
font-size: 14px;
}
あまり使う機会は少ないかもしれませんが、とても簡単なので機会があったら試してみてください。