WordPressでブロガー用に便利だった、読了時間の自動表示、古い投稿への注意ラベル、最近見た記事の記録など記述を6つ紹介します。大体コピペで使えます
自動的に古い投稿に「更新が必要」ラベルを追加
投稿から一定期間経過した記事に自動で以下の文言を出力する記述です
![]()
以下の場合 $years = 2; で2年を指定してます
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function add_outdated_notice($content) { global $post; $years = 2; // 何年で古いとみなすか $old_date = strtotime('-' . $years . ' years'); if (is_single() && get_post_time('U') < $old_date) { $notice = '<div class="outdated-notice">'; $notice .= '<p><strong>注意:</strong> この記事は最終更新から' . $years . '年以上経過しています。情報が古い可能性があります。</p>'; $notice .= '</div>'; $content = $notice . $content; } return $content; } add_filter('the_content', 'add_outdated_notice'); |
日数にしたい場合は 以下を参照
$years → $days
‘years’ → ‘days’
|
1 2 |
$days = 1; // 何日で古いとみなすか $old_date = strtotime('-' . $days . ' days'); |
読了時間の自動計算と表示
記事の冒頭に、”この記事は●●分で読めます” のようなテキストを自動で出力します
英語記事は1分あたり250単語で計算、日本語は1分あたり600文字として計算してます。英語と日本語では一度に読める語数が違うのでこの文字数です。
|
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 |
// 渡された本文コンテンツから読了時間のHTMLを生成して返す関数 function calculate_reading_time($content) { $word_count = str_word_count(strip_tags($content)); $reading_time = ceil($word_count / 250); // 1分あたり250単語として計算 if ($reading_time == 1) { $timer = '1分で読めます'; } else { $timer = $reading_time . '分で読めます'; } // 日本語向け $char_count = mb_strlen(strip_tags($content), 'UTF-8'); $jp_reading_time = ceil($char_count / 600); // 1分あたり600文字として計算 if ($jp_reading_time > $reading_time) { $timer = $jp_reading_time . '分で読めます'; } return '<div class="reading-time">' . $timer . '</div>'; } // 先頭に読了時間を差し込む関数 function display_reading_time($content) { if (is_single() && !is_admin()) { global $post; return calculate_reading_time($post->post_content) . $content; } return $content; } add_filter('the_content', 'display_reading_time'); |
$jp_reading_time > $reading_timeのように、日本語の読了時間が長ければ日本語、短い場合英語ベースで時間を表示
|
1 2 3 |
if ($jp_reading_time > $reading_time) { $timer = $jp_reading_time . '分で読めます'; } |
見出しに自動CSS用ID付与
the_content に含まれる見出しタグ <h2>〜<h6> に自動でID属性を付与するための関数です。
見出しタグに「ジャンプ先リンク用のID」を自動生成して追加するのでアンカーリンクが簡単にできます。
見出しタグに「ジャンプ先リンク用のID」を自動生成して追加するのでアンカーリンクが簡単にできます。
|
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 |
function add_id_to_headings($content) { $pattern = '/<h([2-6])>(.+?)<\/h[2-6]>/iu'; $content = preg_replace_callback($pattern, function ($matches) { $level = $matches[1]; $title = strip_tags($matches[2]); // 英数字が含まれるならそれを優先 $slug = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $title); $slug = strtolower($slug); $slug = preg_replace('/[^a-z0-9]+/', '-', $slug); $slug = trim($slug, '-'); // slugが空の場合は短いランダムIDをつける if (empty($slug)) { $rand = substr(md5(uniqid('', true)), 0, 5); // 5文字だけ $slug = 'h' . $level . '-' . $rand; } return '<h' . $level . ' id="' . esc_attr($slug) . '">' . $matches[2] . '</h' . $level . '>'; }, $content); return $content; } add_filter('the_content', 'add_id_to_headings'); |
以下のように id=”***” が自動出力されます。
|
1 |
<h3 id="css-id"> |
執筆者情報ボックスの自動表示
記事の最後に、管理画面で入力したユーザー情報が表示されます
|
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 |
function display_author_box($content) { if (is_single()) { $author_id = get_the_author_meta('ID'); $author_name = get_the_author_meta('display_name'); $author_description = get_the_author_meta('description'); $author_url = get_author_posts_url($author_id); $twitter = get_user_meta($author_id, 'twitter_url', true); $facebook = get_user_meta($author_id, 'facebook_url', true); $author_box = '<div class="author-box">'; $author_box .= '<div class="author-avatar">' . get_avatar($author_id, 100) . '</div>'; $author_box .= '<div class="author-info">'; $author_box .= '<h4 class="author-name"><a href="' . $author_url . '">' . $author_name . '</a></h4>'; if ($author_description) { $author_box .= '<p class="author-description">' . $author_description . '</p>'; } $author_box .= '<div class="author-links">'; if ($twitter) { $author_box .= '<a href="' . esc_url($twitter) . '" target="_blank" rel="nofollow" class="twitter-link">Twitter</a>'; } if ($facebook) { $author_box .= '<a href="' . esc_url($facebook) . '" target="_blank" rel="nofollow" class="facebook-link">Facebook</a>'; } $author_box .= '</div>'; // .author-links $author_box .= '</div>'; // .author-info $author_box .= '</div>'; // .author-box $content .= $author_box; } return $content; } add_filter('the_content', 'display_author_box'); |
ID、ユーザー名、プロフィール情報、著者IDを取得してます
|
1 2 3 4 |
$author_id = get_the_author_meta('ID'); $author_name = get_the_author_meta('display_name'); $author_description = get_the_author_meta('description'); $author_url = get_author_posts_url($author_id); |
SNSリンクを出力する場合、以下をfunctions.phpに書いてメタキーを確認しましょう。
|
1 2 3 4 5 6 7 8 |
add_action('wp_footer', function() { if (is_single()) { $author_id = get_the_author_meta('ID'); echo '<pre>'; print_r(get_user_meta($author_id)); echo '</pre>'; } }); |
twitter、facebookは以下を参考
|
1 2 |
$twitter = get_user_meta($author_id, 'twitter_url', true); $facebook = get_user_meta($author_id, 'facebook_url', true); |
ユーザーの訪問履歴を記録し、「最近見た記事」を表示
ショートコードを使って最近見た記事を出力します。
|
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 80 81 82 83 84 |
// 最近見た記事 function track_post_views() { if (!is_single()) return; global $post; $post_id = $post->ID; if (!isset($_COOKIE['viewed_posts'])) { $viewed_posts = array(); } else { $viewed_posts = json_decode(stripslashes($_COOKIE['viewed_posts']), true); } // 最大10件まで記録 if (is_array($viewed_posts)) { // 現在の投稿がすでに履歴にある場合は削除 $key = array_search($post_id, $viewed_posts); if ($key !== false) { unset($viewed_posts[$key]); } // 履歴の先頭に追加 array_unshift($viewed_posts, $post_id); // 最大件数を超えたら古いものを削除 if (count($viewed_posts) > 10) { $viewed_posts = array_slice($viewed_posts, 0, 10); } } else { $viewed_posts = array($post_id); } // Cookieに保存(30日間有効) setcookie('viewed_posts', json_encode($viewed_posts), time() + (86400 * 30), '/'); } add_action('wp', 'track_post_views'); // 最近見た記事を表示するショートコード function recently_viewed_posts_shortcode() { if (!isset($_COOKIE['viewed_posts'])) { return '<p>まだ記事の閲覧履歴がありません。</p>'; } $viewed_posts = json_decode(stripslashes($_COOKIE['viewed_posts']), true); if (!is_array($viewed_posts) || empty($viewed_posts)) { return '<p>まだ記事の閲覧履歴がありません。</p>'; } $output = '<div class="recently-viewed-posts">'; $output .= '<h3>最近見た記事</h3>'; $output .= '<ul>'; foreach ($viewed_posts as $post_id) { // 現在表示中の記事は除外 if (is_single() && get_the_ID() == $post_id) continue; $post = get_post($post_id); if ($post) { $output .= '<li>'; if (has_post_thumbnail($post_id)) { $output .= '<div class="recent-thumbnail">'; $output .= '<a href="' . get_permalink($post_id) . '">'; $output .= get_the_post_thumbnail($post_id, 'thumbnail'); $output .= '</a>'; $output .= '</div>'; } $output .= '<div class="recent-title">'; $output .= '<a href="' . get_permalink($post_id) . '">' . get_the_title($post_id) . '</a>'; $output .= '<span class="recent-date">' . get_the_date('Y/m/d', $post_id) . '</span>'; $output .= '</div>'; $output .= '</li>'; } } $output .= '</ul>'; $output .= '</div>'; return $output; } add_shortcode('recently_viewed', 'recently_viewed_posts_shortcode'); |
ショートコード
|
1 |
[recently_viewed] |
Cookieに保存された記事ID一覧をもとに表示します。ウィジェットなどで使うことが多いと思います。テーマに入れる場合は以下
|
1 |
<?php echo do_shortcode('[recently_viewed]'); ?> |
記事の末尾に出力したい場合は以下
|
1 2 3 4 5 6 |
add_filter('the_content', function($content) { if (is_single()) { $content .= do_shortcode('[recently_viewed]'); } return $content; }); |
見た目カスタマイズのCSS
|
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 |
.recent-title { display: flex; flex-direction: column; } .recently-viewed-posts ul { list-style: none; padding: 0; } .recently-viewed-posts li { display: flex; margin-bottom: 10px; gap: 5px; } .recent-thumbnail img { width: 80px; height: auto; margin-right: 10px; } .recent-title a { font-weight: bold; font-size: 14px; line-height: 1.4; } .recent-date { display: block; font-size: 12px; color: #666; } |
管理バーに下書き一覧ショートカットを追加
管理画面の上部にある管理バーに下書き一覧リンクを出力します。時短?
|
1 2 3 4 5 6 7 8 |
add_action('admin_bar_menu', function($wp_admin_bar) { $args = array( 'title' => '下書き一覧', 'href' => admin_url('edit.php?post_status=draft&post_type=post'), 'meta' => array('class' => 'my-drafts') ); $wp_admin_bar->add_node($args); }, 999); |
通常のテーマにはそのままコピペしても動くとおもいますが、中にはエラーになるテーマもあると思いますので、自己責任でfunctioins.phpに追加お願いします。