この記事では、WordPressブログカードの埋め込み(iframe)を無効化して、自分でブログカードをカスタマイズする方法について解説しています。
WordPress標準のブログカードは埋め込み(iframe)形式となっていて、これをカスタマイズしようとするとfunction.phpだけではなかなか難しいんですね。また、ブログカードがiframe形式なのでそのままだとCSSも効かず、ちょっと面倒です。
また、プラグインあり・なしどちらでカスタムする場合でも、ショートコードを挿入することでブログカードを反映させるという方法が多く、これだと面倒です。理想は自分のサイトのURLを自動で判別し、ブログカードに反映させたいところ。
ということで、以下のコードではそれらを実現します。
・自分のサイトのURLを自動でブログカードにしたい。つまりショートコードで挿入は面倒
・プラグインなしで、自分でカスタマイズしたい
・埋め込み(iframe)を無効化して自作テーマのCSSをそのまま効かせたい
・function.php内の記述だけで完結したい
ここではブログカード自体をBootstrapでデザインしています。ブログカードのデザインについてはクラス名を付けるなどして自身のデザインに修正できます。
現在のデザインとしては以下のようになっています。左側にはアイキャッチ、右側にはタイトル、投稿日、カテゴリそして抜粋が表示されます。表示する内容や抜粋の最大文字数の変更も可能です。Bootstrapなのでレスポンシブ対応もしています。
目次
サンプルコード
このコードは、ブログカード(投稿のプレビューをカード形式で表示するリンク)をカスタムするためのWordPressコードです。以下で各部分の説明をします。
remove_filter と add_filter
1 2 |
remove_filter( 'the_content', array( $GLOBALS['wp_embed'], 'autoembed' ), 8 ); add_filter( 'the_content', 'my_autoembed', 8 ); |
WordPressではwp_embed クラスによって自動的にURLが埋め込み形式に変換されます。この部分でそのデフォルトの自動埋め込み機能を無効にし、代わりにカスタムの埋め込み処理をするためにフィルタをカスタマイズしています。remove_filter で元々の埋め込みフィルターを無効化し、add_filter で新しいカスタム関数 my_autoembed を追加しています。
my_autoembed 関数
1 2 3 4 5 6 7 8 |
function my_autoembed( $content ) { $content = wp_replace_in_html_tags( $content, array( "\n" => '<!-- wp-line-break -->' ) ); if ( preg_match( '#(^|\s|>)https?://#i', $content ) ) { $content = preg_replace_callback( '|^(\s*)(https?://[^\s<>"]+)(\s*)$|im', 'my_autoembed_callback', $content ); $content = preg_replace_callback( '|(<p(?: [^>]*)?>\s*)(https?://[^\s<>"]+)(\s*<\/p>)|i', 'my_autoembed_callback', $content ); } return str_replace( '<!-- wp-line-break -->', "\n", $content ); } |
この関数は、投稿内容に含まれるURLを検出し、特定のパターンに一致するURLを処理するための関数です。
preg_match で投稿のコンテンツにURLが含まれているかチェックし、preg_replace_callback を使ってURLを my_autoembed_callback 関数に渡し、カスタム埋め込みカードに変換します。
my_autoembed_callback 関数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function my_autoembed_callback( $match ) { $url = $match[2]; $url_host = str_replace( 'www.', '', parse_url( $url, PHP_URL_HOST ) ); $home_url_host = str_replace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ); if ( $url_host && $url_host == $home_url_host ) { // 一時的にフィルタを無効にする remove_filter( 'the_content', 'my_autoembed', 8 ); $custom_link = get_custom_link($url); add_filter( 'the_content', 'my_autoembed', 8 ); return $custom_link; } return $GLOBALS['wp_embed']->autoembed_callback( $match ); } |
この関数は、URLが自分のサイト内のリンクかどうかを確認し、それに基づいて埋め込み処理を分岐させます。
parse_url() でURLのホスト部分を取得し、自サイトのホストと一致する場合はカスタムのリンクを生成する関数 get_custom_link() を呼び出します。これにより、自分のサイト内の投稿がブログカードとして表示されます。それ以外の外部URLはデフォルトのWordPressの埋め込み処理に戻します。
つまりショートコードでURLを貼り付ける必要がなくなります。
get_custom_link 関数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
function get_custom_link($url) { // 投稿IDを取得 $post_id = url_to_postid($url); if (!$post_id) { return $url; // 投稿IDが取得できない場合は元のURLを返す } // 投稿のタイトル、投稿日、カテゴリー、サムネイル画像、抜粋を取得 $post_title = get_the_title($post_id); $post_permalink = get_permalink($post_id); $post_date = get_the_date('F j, Y', $post_id); $categories = get_the_category($post_id); $category_list = ''; $post_thumbnail = get_the_post_thumbnail_url($post_id, 'small'); // サムネイル画像 $post_excerpt = get_the_excerpt($post_id); // 投稿の抜粋 // モバイルかどうかで文字数制限を設定 $max_title_length = wp_is_mobile() ? 100 : 150; $trimmed_title = mb_strimwidth($post_title, 0, $max_title_length, '...', 'UTF-8'); $trimmed_excerpt = mb_strimwidth($post_excerpt, 0, $max_title_length, '...', 'UTF-8'); if (!empty($categories)) { $category_list = 'Category: ' . esc_html($categories[0]->name); } // タイトル、投稿日、カテゴリー、抜粋、画像をリンクとして表示 return ' <a href="' . esc_url($post_permalink) . '" target="_blank" class="card-container"> <div class="card mb-3"> <div class="row g-0"> <div class="col-md-5 d-flex align-items-center justify-content-center"> <img src="' . esc_url($post_thumbnail) . '" class="img-fluid post-img" alt="' . esc_attr($trimmed_title) . '"> </div> <div class="col-md-7 d-flex align-items-center justify-content-center"> <div class="card-body post-body"> <p class="card-title">' . esc_html($trimmed_title) . '</p> <p class="card-meta"> Posted on ' . esc_html($post_date) . ' | ' . $category_list . ' </p> <p class="card-excerpt">' . esc_html($trimmed_excerpt) . '</p> </div> </div> </div> </div> </a>'; } |
この関数は、投稿IDを基にブログカードを作成します。URLから投稿IDを取得し、投稿タイトル、リンク、投稿日、カテゴリー、サムネイル画像、抜粋を収集して、ブログカードのHTMLを返します。
タイトル、抜粋を短縮して表示する処理も行っており、モバイルかどうかによって最大文字数を調整します。HTML部分では、カード全体がリンクとなっており、Bootstrapのクラスを使ってスタイルが整えられています。
この箇所がブログカードのデザインとなります。クラス名を付与するなどして好みにカスタムしてください。
機能の概要
このコードは、自サイト内のリンクが投稿内に含まれている場合、そのリンクをカード形式に変換して表示します。カードには投稿のタイトル、サムネイル、投稿日、カテゴリー、抜粋が表示され、クリックすると投稿ページへ移動します。target=”_blankを設定しているので、新規タブで開くようになっています。
コード全文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
<?php //ブログカード if ( isset( $GLOBALS['wp_embed'] ) ) { remove_filter( 'the_content', array( $GLOBALS['wp_embed'], 'autoembed' ), 8 ); function my_autoembed( $content ) { $content = wp_replace_in_html_tags( $content, array( "\n" => '<!-- wp-line-break -->' ) ); if ( preg_match( '#(^|\s|>)https?://#i', $content ) ) { $content = preg_replace_callback( '|^(\s*)(https?://[^\s<>"]+)(\s*)$|im', 'my_autoembed_callback', $content ); $content = preg_replace_callback( '|(<p(?: [^>]*)?>\s*)(https?://[^\s<>"]+)(\s*<\/p>)|i', 'my_autoembed_callback', $content ); } return str_replace( '<!-- wp-line-break -->', "\n", $content ); } add_filter( 'the_content', 'my_autoembed', 8 ); function my_autoembed_callback( $match ) { $url = $match[2]; $url_host = str_replace( 'www.', '', parse_url( $url, PHP_URL_HOST ) ); $home_url_host = str_replace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) ); if ( $url_host && $url_host == $home_url_host ) { // 一時的にフィルタを無効にする remove_filter( 'the_content', 'my_autoembed', 8 ); $custom_link = get_custom_link($url); add_filter( 'the_content', 'my_autoembed', 8 ); return $custom_link; } return $GLOBALS['wp_embed']->autoembed_callback( $match ); } function get_custom_link($url) { // 投稿IDを取得 $post_id = url_to_postid($url); if (!$post_id) { return $url; // 投稿IDが取得できない場合は元のURLを返す } // 投稿のタイトル、投稿日、カテゴリー、サムネイル画像、抜粋を取得 $post_title = get_the_title($post_id); $post_permalink = get_permalink($post_id); $post_date = get_the_date('F j, Y', $post_id); $categories = get_the_category($post_id); $category_list = ''; $post_thumbnail = get_the_post_thumbnail_url($post_id, 'small'); // サムネイル画像 $post_excerpt = get_the_excerpt($post_id); // 投稿の抜粋 // モバイルかどうかで文字数制限を設定 $max_title_length = wp_is_mobile() ? 100 : 150; $trimmed_title = mb_strimwidth($post_title, 0, $max_title_length, '...', 'UTF-8'); $trimmed_excerpt = mb_strimwidth($post_excerpt, 0, $max_title_length, '...', 'UTF-8'); if (!empty($categories)) { $category_list = 'Category: ' . esc_html($categories[0]->name); } // タイトル、投稿日、カテゴリー、抜粋、画像をリンクとして表示 return ' <a href="' . esc_url($post_permalink) . '" target="_blank" class="card-container"> <div class="card mb-3"> <div class="row g-0"> <div class="col-md-5 d-flex align-items-center justify-content-center"> <img src="' . esc_url($post_thumbnail) . '" class="img-fluid post-img" alt="' . esc_attr($trimmed_title) . '"> </div> <div class="col-md-7 d-flex align-items-center justify-content-center"> <div class="card-body post-body"> <p class="card-title">' . esc_html($trimmed_title) . '</p> <p class="card-meta"> Posted on ' . esc_html($post_date) . ' | ' . $category_list . ' </p> <p class="card-excerpt">' . esc_html($trimmed_excerpt) . '</p> </div> </div> </div> </div> </a>'; } } |