【初心者でも簡単】WordPressでお知らせ欄を作る完全ガイド|一覧表示・トップページ自動反映・プラグインなしで実装!

wp-news-section WordPress
記事内に広告が含まれています。

「WordPressで“お知らせ”欄を作りたいけれど、標準機能・固定ページ・カスタム投稿タイプ、どれが最適なのか分からない」「企業サイトのように最新のお知らせをトップページや一覧ページに自動表示する方法が知りたい」「見やすいレイアウトやスマホ対応、おしゃれなデザインも諦めたくない」——このように感じたことはありませんか?WordPressのお知らせ機能は使い方や実装方法が多岐にわたるため、初心者の方はもちろん、ある程度慣れている方でも迷う部分が多いです。

本記事では、なるべく専門用語はかみ砕きつつも、機能面・デザイン面ともに妥協しない情報を盛り込みました。プラグイン不要の方法はもちろん、PHPやCSSのコピペ用サンプル、カスタム投稿タイプやショートコードの具体例まで、読んだその日から実践できる手順を徹底解説します。「見出しだけで終わらない」本当に使える“お知らせ”欄の作り方を、ぜひ最後までご覧ください。

この記事を読んでわかること

  • 投稿・固定ページ・カスタム投稿タイプ、それぞれの特徴と具体的な使い分け
  • 固定ページを使った初心者向けお知らせ一覧の作成手順
  • functions.phpで作るカスタム投稿タイプ「お知らせ」の実装例と活用法
  • トップページや一覧ページに最新のお知らせを自動表示する具体的な方法(WP_Query/ショートコード活用)
  • お知らせ一覧のデザインをカスタマイズするCSSサンプルやレスポンシブ対応のコツ
  • 公開期間を設定してお知らせを自動非表示・分類・ラベル管理する応用術
  • REST API&SNS連携で外部にも通知できる最新運用ノウハウ
  • お問い合わせが多いFAQやつまずきやすいポイントもまとめて解説

WordPressで「お知らせ」機能を作る基本手順と選択肢

WordPressでお知らせ機能を実装する方法は、大きく分けて3つの選択肢があります。それぞれに明確なメリット・デメリットがあり、サイトの規模や運用体制によって最適な手法は異なります。ここでは各手法の特徴を詳しく解説し、あなたのサイトに最適な実装方法を選べるようにします。

投稿・固定ページ・カスタム投稿タイプの違いと使い分け

WordPressには標準で「投稿」と「固定ページ」という2つのコンテンツタイプがあり、さらに「カスタム投稿タイプ」を追加することができます。それぞれの特性を理解することが、適切なお知らせ機能構築の第一歩です。

1. 通常の「投稿」でお知らせを作る方法

メリット:

  • プラグインやコーディング不要で今すぐ使える
  • カテゴリー機能で「お知らせ」カテゴリを作成すればすぐに分類可能
  • RSSフィードに自動で含まれる

デメリット:

  • ブログ記事と混在してしまい管理画面が煩雑になる
  • お知らせとブログ記事で異なるデザインを適用しにくい
  • SEO上、ブログコンテンツとお知らせが同列に扱われてしまう

適したケース:

  • 小規模な個人サイトやブログ
  • お知らせの投稿頻度が月1回程度の少ないサイト
  • とにかく素早く実装したい初心者

2. 固定ページで「お知らせ一覧」を手動作成する方法

メリット:

  • 特別な設定なしで、HTMLエディタで自由にレイアウト可能
  • 他のページと同じテンプレートで統一感を出しやすい
  • 初心者でも直感的に編集できる

デメリット:

  • 新しいお知らせを追加するたびに手動で編集が必要
  • 古いお知らせの削除や並び替えが手間
  • 件数が増えると管理が非常に煩雑
  • 自動表示やフィルタリングなどの動的な機能が実装できない

適したケース:

  • お知らせが年に数回程度の更新頻度
  • 常に3〜5件程度の固定情報を表示するだけのサイト
  • プログラミング知識が全くなく、とにかくシンプルに済ませたい場合

3. カスタム投稿タイプで「お知らせ」専用の機能を作る方法【企業サイトに最適】

メリット:

  • お知らせとブログ記事を完全に分離して管理できる
  • 専用の一覧ページやアーカイブページを自動生成
  • お知らせ専用のカスタムフィールドやタクソノミー(分類)を追加可能
  • 管理画面に「お知らせ」専用メニューが表示され、運用効率が劇的に向上
  • デザインやURLスラッグを独立してカスタマイズ可能

デメリット:

  • functions.phpの編集やプラグイン導入が必要
  • 初期設定に多少の技術知識が必要
  • テーマによってはテンプレートファイルの追加が必要

適したケース:

  • 企業サイトやコーポレートサイト(最もおすすめ)
  • お知らせの投稿頻度が週1回以上あるサイト
  • 複数人でサイトを運用し、役割分担したい場合
  • お知らせに「重要度」「カテゴリ」「公開期限」などの独自項目を持たせたい場合

初心者でも簡単!固定ページで作る「お知らせ一覧」の基本手順

まずは最もシンプルな方法として、固定ページを使った手動のお知らせ一覧の作り方を解説します。プログラミング知識がなくても、今すぐ実装できる方法です。

ステップ1: 固定ページを新規作成

  1. WordPress管理画面から「固定ページ」→「新規追加」をクリック
  2. タイトルに「お知らせ」と入力
  3. パーマリンク(URL)を「news」などに設定

ステップ2: お知らせ内容をHTMLで記述

ビジュアルエディタではなく、**コードエディタ(またはHTMLブロック)**に切り替えて、以下のようなHTMLを記述します。

<div class="news-list">
  <article class="news-item">
    <time class="news-date">2025年10月3日</time>
    <h3 class="news-title"><a href="/news/sample-001/">年末年始の営業時間のお知らせ</a></h3>
  </article>

  <article class="news-item">
    <time class="news-date">2025年9月28日</time>
    <h3 class="news-title"><a href="/news/sample-002/">新サービス開始のご案内</a></h3>
  </article>

  <article class="news-item">
    <time class="news-date">2025年9月15日</time>
    <h3 class="news-title"><a href="/news/sample-003/">システムメンテナンスのお知らせ</a></h3>
  </article>
</div>

ステップ3: スタイルを追加(任意)

テーマのカスタムCSSまたは「追加CSS」機能で、以下のような基本的なスタイルを適用できます。

.news-list {
  max-width: 800px;
  margin: 0 auto;
}

.news-item {
  border-bottom: 1px solid #e0e0e0;
  padding: 20px 0;
}

.news-date {
  display: block;
  color: #666;
  font-size: 14px;
  margin-bottom: 8px;
}

.news-title {
  font-size: 18px;
  margin: 0;
}

.news-title a {
  color: #333;
  text-decoration: none;
}

.news-title a:hover {
  color: #0073aa;
}

この方法は簡単ですが、新しいお知らせを追加するたびに固定ページを編集する必要があるため、更新頻度が高い場合は非効率です。次のセクションで紹介するカスタム投稿タイプの方が、長期的には圧倒的に効率的です。

functions.phpで作るカスタム投稿タイプ「お知らせ」の設定例

企業サイトや更新頻度の高いサイトに最適な、カスタム投稿タイプによるお知らせ機能の実装方法を解説します。この方法なら、お知らせを「投稿」と同じように簡単に追加でき、管理画面も見やすく整理されます。

ステップ1: functions.phpにコードを追加

使用中のテーマのfunctions.phpファイル(子テーマがある場合は子テーマのfunctions.php)に、以下のコードを追加します。

重要: 必ずバックアップを取ってから編集してください。

<?php
function create_news_post_type() {
    $labels = array(
        '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'    => 'ゴミ箱にお知らせはありません'
    );

    $args = array(
        'labels'                => $labels,
        'public'                => true,
        'publicly_queryable'    => true,
        'show_ui'               => true,
        'show_in_menu'          => true,
        'query_var'             => true,
        'rewrite'               => array('slug' => 'news'), // URLを /news/ にする
        'capability_type'       => 'post',
        'has_archive'           => true, // 一覧ページを自動生成
        'hierarchical'          => false,
        'menu_position'         => 5, // 管理画面での表示位置
        'menu_icon'             => 'dashicons-megaphone', // アイコン
        'supports'              => array('title', 'editor', 'thumbnail', 'excerpt'),
        'show_in_rest'          => true, // ブロックエディタに対応
    );

    register_post_type('news', $args);
}
add_action('init', 'create_news_post_type');

コードの解説

  • 'rewrite' => array('slug' => 'news'):
    お知らせのURLを https://example.com/news/記事名/ にします
  • 'has_archive' => true:
    自動で一覧ページ(https://example.com/news/)を生成します
  • 'menu_icon' => 'dashicons-megaphone':
    管理画面のメニューアイコンを設定(Dashicons一覧から選択可能)
  • 'supports':
    タイトル、本文、アイキャッチ画像、抜粋に対応
  • 'show_in_rest' => true:
    ブロックエディタ(Gutenberg)で編集可能にします

ステップ2: パーマリンク設定を更新

コードを追加したら、必ずパーマリンク設定を更新してください。これをしないと404エラーが発生します。

  1. WordPress管理画面から「設定」→「パーマリンク設定」を開く
  2. 何も変更せず、ページ下部の「変更を保存」ボタンをクリック

これでパーマリンク構造が再生成され、カスタム投稿タイプが正しく機能するようになります。

ステップ3: お知らせを投稿してみる

管理画面の左メニューに「お知らせ」という項目が追加されているはずです。ここから通常の投稿と同じように、お知らせを投稿できます。

カテゴリー分類も追加する場合

お知らせを「重要」「イベント」「メンテナンス」などのカテゴリーで分類したい場合は、以下のコードもfunctions.phpに追加します。

<?php
function create_news_taxonomy() {
    $labels = array(
        'name'              => 'お知らせカテゴリー',
        'singular_name'     => 'カテゴリー',
        'search_items'      => 'カテゴリーを検索',
        'all_items'         => 'すべてのカテゴリー',
        'edit_item'         => 'カテゴリーを編集',
        'update_item'       => 'カテゴリーを更新',
        'add_new_item'      => '新規カテゴリーを追加',
        'new_item_name'     => '新しいカテゴリー名',
        'menu_name'         => 'カテゴリー',
    );

    $args = array(
        'hierarchical'      => true, // 階層構造を持たせる(親子関係)
        'labels'            => $labels,
        'show_ui'           => true,
        'show_admin_column' => true, // 管理画面の一覧に表示
        'query_var'         => true,
        'rewrite'           => array('slug' => 'news-category'),
        'show_in_rest'      => true,
    );

    register_taxonomy('news_category', array('news'), $args);
}
add_action('init', 'create_news_taxonomy');

このコードを追加すると、お知らせの編集画面に「お知らせカテゴリー」という項目が表示され、通常のブログ投稿と同じようにカテゴリー分類ができるようになります。

トップページや一覧ページに「お知らせ」を自動表示する実装方法

カスタム投稿タイプで「お知らせ」を作成したら、次はそれをサイトの目立つ場所に表示する必要があります。このセクションでは、WP_Queryを使った柔軟な表示方法から、簡単に使えるショートコードまで、実務で即活用できる実装方法を解説します。

WP_Query – Class | Developer.WordPress.org
The WordPress Query class.

最新3件をトップページに表示するPHPコード例(WP_Query)

トップページに最新のお知らせを自動表示する、最も汎用性の高い実装方法です。WP_QueryというWordPress標準の機能を使うことで、表示件数や並び順を自由にコントロールできます。

実装するファイルの選び方

お知らせを表示したい場所に応じて、編集するファイルが異なります。

  • トップページ(固定ページを使用): front-page.php
  • トップページ(最新投稿一覧を使用): home.php または index.php
  • 固定ページテンプレート: page.php または カスタムテンプレート
  • サイドバー: sidebar.php
  • フッター: footer.php

子テーマを使用している場合は、親テーマからファイルをコピーして子テーマで編集してください。

基本的な実装コード

以下のコードを、お知らせを表示したい位置に貼り付けます。

<?php
// お知らせを取得するクエリ
$args = array(
    'post_type'      => 'news',        // カスタム投稿タイプ「news」を指定
    'posts_per_page' => 3,             // 表示件数を3件に設定
    'orderby'        => 'date',        // 日付順で並べる
    'order'          => 'DESC',        // 新しい順(降順)
    'post_status'    => 'publish',     // 公開済みの投稿のみ
);

$news_query = new WP_Query($args);

// お知らせが存在するかチェック
if ($news_query->have_posts()) : ?>
    <section class="news-section">
        <h2 class="news-heading">お知らせ</h2>
        <ul class="news-list">
            <?php while ($news_query->have_posts()) : $news_query->the_post(); ?>
                <li class="news-item">
                    <time class="news-date" datetime="<?php echo get_the_date('Y-m-d'); ?>">
                        <?php echo get_the_date('Y.m.d'); ?>
                    </time>
                    <h3 class="news-title">
                        <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
                    </h3>
                </li>
            <?php endwhile; ?>
        </ul>
        <a href="<?php echo get_post_type_archive_link('news'); ?>" class="news-more">
            すべてのお知らせを見る
        </a>
    </section>
    <?php
    // クエリをリセット(重要!)
    wp_reset_postdata();
endif;
?>

コードの詳細解説

$args配列の重要なパラメータ:

  • post_type:
    取得する投稿タイプを指定。ここでは前のセクションで作成した'news'を指定
  • posts_per_page:
    表示する件数。1にすると全件表示
  • orderby:
    並び順の基準(date=日付、title=タイトル、rand=ランダムなど)
  • order:
    DESC(降順=新しい順)またはASC(昇順=古い順)
  • post_status:
    publishで公開済みのみ取得

重要な注意点:

  • wp_reset_postdata()は必ず記述する:
    これを忘れると、ページ内の他のループに影響が出る可能性があります

カテゴリーで絞り込む応用例

特定のカテゴリー(例: 「重要なお知らせ」)だけを表示したい場合は、$argsに以下を追加します。

$args = array(
    'post_type'      => 'news',
    'posts_per_page' => 3,
    'orderby'        => 'date',
    'order'          => 'DESC',
    'tax_query'      => array(  // タクソノミーで絞り込み
        array(
            'taxonomy' => 'news_category',     // 前のセクションで作成したタクソノミー
            'field'    => 'slug',              // スラッグで指定
            'terms'    => 'important',         // カテゴリーのスラッグを指定
        ),
    ),
);

アイキャッチ画像も表示する場合

<?php while ($news_query->have_posts()) : $news_query->the_post(); ?>
    <li class="news-item">
        <?php if (has_post_thumbnail()) : ?>
            <div class="news-thumbnail">
                <a href="<?php the_permalink(); ?>">
                    <?php the_post_thumbnail('thumbnail'); // サムネイルサイズで表示 ?>
                </a>
            </div>
        <?php endif; ?>
        <div class="news-content">
            <time class="news-date" datetime="<?php echo get_the_date('Y-m-d'); ?>">
                <?php echo get_the_date('Y.m.d'); ?>
            </time>
            <h3 class="news-title">
                <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
            </h3>
        </div>
    </li>
<?php endwhile; ?>

固定ページに「お知らせ一覧」を埋め込むショートコードの作り方

PHPファイルを編集せずに、ショートコードを使って任意の固定ページや投稿にお知らせ一覧を挿入する方法です。この方法なら、プログラミング知識のない担当者でも簡単にお知らせを表示できます。

ステップ1: functions.phpにショートコードを登録

子テーマのfunctions.phpに以下のコードを追加します。

<?php
function display_news_list_shortcode($atts) {
    // ショートコードの属性を設定(デフォルト値)
    $atts = shortcode_atts(array(
        'count' => 5,           // 表示件数(デフォルト5件)
        'category' => '',       // カテゴリー指定(オプション)
    ), $atts);

    // お知らせ取得のクエリ設定
    $args = array(
        'post_type'      => 'news',
        'posts_per_page' => intval($atts['count']),
        'orderby'        => 'date',
        'order'          => 'DESC',
    );

    // カテゴリー指定がある場合
    if (!empty($atts['category'])) {
        $args['tax_query'] = array(
            array(
                'taxonomy' => 'news_category',
                'field'    => 'slug',
                'terms'    => $atts['category'],
            ),
        );
    }

    $news_query = new WP_Query($args);

    // 出力用の変数を初期化
    $output = '';

    if ($news_query->have_posts()) {
        $output .= '<div class="shortcode-news-list">';
        $output .= '<ul class="news-items">';

        while ($news_query->have_posts()) {
            $news_query->the_post();

            $output .= '<li class="news-item">';
            $output .= '<time class="news-date" datetime="' . get_the_date('Y-m-d') . '">';
            $output .= get_the_date('Y.m.d');
            $output .= '</time>';
            $output .= '<h3 class="news-title">';
            $output .= '<a href="' . get_permalink() . '">' . get_the_title() . '</a>';
            $output .= '</h3>';
            $output .= '</li>';
        }

        $output .= '</ul>';
        $output .= '</div>';

        wp_reset_postdata();
    } else {
        $output .= '<p class="no-news">現在、お知らせはありません。</p>';
    }

    return $output;
}
add_shortcode('news_list', 'display_news_list_shortcode');
?>

ステップ2: ショートコードを固定ページに挿入

固定ページの編集画面で、お知らせを表示したい場所に以下のショートコードを記述します。

基本的な使い方(最新5件を表示):

[news_list]

表示件数を指定する場合(10件表示):

[news_list count="10"]

特定のカテゴリーのみ表示する場合:

[news_list category="important" count="3"]

複数の属性を組み合わせる:

[news_list count="8" category="event"]

ブロックエディタでの挿入方法

  1. 「+」ボタンをクリックして「ショートコード」ブロックを追加
  2. ショートコードを入力(例: [news_list count="5"]
  3. プレビューで表示を確認

クラシックエディタでの挿入方法

テキストエディタに直接ショートコードを記述すればOKです。

表示件数・並び順を自由にカスタマイズする方法

お知らせの表示をさらに柔軟にコントロールするための、実用的なカスタマイズ例を紹介します。

1. 表示件数を動的に変更する

トップページには3件、お知らせページには10件表示したい場合、条件分岐を使います。

<?php
// 現在のページによって表示件数を変更
if (is_front_page()) {
    $count = 3;  // トップページは3件
} elseif (is_page('news')) {
    $count = 10; // お知らせページは10件
} else {
    $count = 5;  // その他は5件
}

$args = array(
    'post_type'      => 'news',
    'posts_per_page' => $count,
    'orderby'        => 'date',
    'order'          => 'DESC',
);

$news_query = new WP_Query($args);
?>

2. カスタムフィールドで「重要」フラグを立てた投稿を優先表示

まず、お知らせ投稿にカスタムフィールド「important」を追加します(値は1で重要とする)。

<?php
$args = array(
    'post_type'      => 'news',
    'posts_per_page' => 5,
    'meta_key'       => 'important',  // カスタムフィールドのキー
    'orderby'        => array(
        'meta_value_num' => 'DESC',   // important順(1が上に来る)
        'date'           => 'DESC',   // 同じimportant値なら日付順
    ),
);

$news_query = new WP_Query($args);
?>

3. 公開日が新しい順+更新日でも並べ替え

<?php
$args = array(
    'post_type'      => 'news',
    'posts_per_page' => 5,
    'orderby'        => array(
        'modified' => 'DESC',  // 更新日で並べる
        'date'     => 'DESC',  // 同じ更新日なら公開日順
    ),
);

$news_query = new WP_Query($args);
?>

4. 過去30日間のお知らせのみ表示

<?php
$args = array(
    'post_type'      => 'news',
    'posts_per_page' => 10,
    'date_query'     => array(
        array(
            'after' => '30 days ago', // 30日前以降
        ),
    ),
    'orderby'        => 'date',
    'order'          => 'DESC',
);

$news_query = new WP_Query($args);
?>

5. 月別アーカイブを実装する

お知らせの月別アーカイブリンクを作成する場合:

<div class="news-archive">
    <h3>月別アーカイブ</h3>
    <ul>
        <?php
        wp_get_archives(array(
            'type'      => 'monthly',
            'limit'     => 12,          // 最新12ヶ月分
            'post_type' => 'news',      // お知らせのアーカイブ
            'show_post_count' => true,  // 投稿数を表示
        ));
        ?>
    </ul>
</div>

6. ページネーション(ページ送り)を追加する

お知らせ一覧ページで、複数ページに分割する場合:

<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

$args = array(
    'post_type'      => 'news',
    'posts_per_page' => 10,
    'paged'          => $paged,  // 現在のページ番号
);

$news_query = new WP_Query($args);

if ($news_query->have_posts()) :
    while ($news_query->have_posts()) : $news_query->the_post();
        // お知らせの表示
    endwhile;

    // ページネーション表示
    echo '<div class="pagination">';
    echo paginate_links(array(
        'total'   => $news_query->max_num_pages,
        'current' => $paged,
    ));
    echo '</div>';

    wp_reset_postdata();
endif;
?>

7. Ajax読み込みで「もっと見る」ボタンを実装

HTML部分(テンプレートファイル):

<div id="news-container">
    <?php
    $args = array(
        'post_type'      => 'news',
        'posts_per_page' => 5,
        'paged'          => 1,
    );
    $news_query = new WP_Query($args);

    if ($news_query->have_posts()) :
        while ($news_query->have_posts()) : $news_query->the_post();
            // お知らせ表示
        endwhile;
        wp_reset_postdata();
    endif;
    ?>
</div>

<?php if ($news_query->max_num_pages > 1) : ?>
    <button id="load-more-news" data-page="1" data-max="<?php echo $news_query->max_num_pages; ?>">
        もっと見る
    </button>
<?php endif; ?>

JavaScript部分(別途記述):

jQuery(document).ready(function($) {
    $('#load-more-news').on('click', function() {
        var button = $(this);
        var page = button.data('page');
        var maxPages = button.data('max');

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'load_more_news',
                page: page + 1
            },
            success: function(response) {
                $('#news-container').append(response);
                button.data('page', page + 1);

                if (page + 1 >= maxPages) {
                    button.hide();
                }
            }
        });
    });
});

Ajax処理(functions.php):

<?php
function load_more_news_callback() {
    $paged = $_POST['page'];

    $args = array(
        'post_type'      => 'news',
        'posts_per_page' => 5,
        'paged'          => $paged,
    );

    $news_query = new WP_Query($args);

    if ($news_query->have_posts()) :
        while ($news_query->have_posts()) : $news_query->the_post();
            // お知らせのHTMLを出力
        endwhile;
        wp_reset_postdata();
    endif;

    wp_die();
}
add_action('wp_ajax_load_more_news', 'load_more_news_callback');
add_action('wp_ajax_nopriv_load_more_news', 'load_more_news_callback');
?>

これらの実装方法を組み合わせることで、企業サイトに求められる柔軟で高機能なお知らせシステムを構築できます。次のセクションでは、さらにユーザー体験を向上させるデザインとレスポンシブ対応について解説します。

お知らせ一覧のデザインとレスポンシブ対応

お知らせ機能を実装したら、次に重要なのが見やすく、使いやすいデザインです。特に企業サイトでは、プロフェッショナルな印象を与えながら、スマートフォンでも快適に閲覧できることが求められます。このセクションでは、すぐに使える実用的なCSSサンプルと、モバイル対応のベストプラクティスを紹介します。

企業サイト風に整えるCSSレイアウトサンプル

企業サイトで一般的な、シンプルで洗練されたお知らせデザインを3パターン紹介します。すべてコピペで使用可能です。

パターン1: シンプルなリスト型レイアウト

最もスタンダードで使いやすい、一覧形式のデザインです。

/* お知らせセクション全体 */
.news-section {
    max-width: 1200px;
    margin: 60px auto;
    padding: 0 20px;
}

/* 見出し */
.news-heading {
    font-size: 32px;
    font-weight: 700;
    margin-bottom: 40px;
    padding-bottom: 15px;
    border-bottom: 3px solid #0066cc;
    color: #333;
}

/* お知らせリスト */
.news-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

/* 各お知らせアイテム */
.news-item {
    display: flex;
    align-items: center;
    padding: 24px 0;
    border-bottom: 1px solid #e5e5e5;
    transition: background-color 0.3s ease;
}

.news-item:hover {
    background-color: #f8f9fa;
}

/* 日付表示 */
.news-date {
    flex-shrink: 0;
    width: 120px;
    font-size: 14px;
    color: #666;
    font-weight: 500;
}

/* タイトル */
.news-title {
    flex: 1;
    font-size: 16px;
    font-weight: 500;
    margin: 0;
    line-height: 1.6;
}

.news-title a {
    color: #333;
    text-decoration: none;
    transition: color 0.3s ease;
}

.news-title a:hover {
    color: #0066cc;
}

/* 「すべて見る」リンク */
.news-more {
    display: inline-block;
    margin-top: 30px;
    padding: 12px 30px;
    background-color: #0066cc;
    color: #fff;
    text-decoration: none;
    border-radius: 4px;
    font-weight: 500;
    transition: background-color 0.3s ease;
}

.news-more:hover {
    background-color: #0052a3;
}

実際の表示

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

パターン2: カード型レイアウト(アイキャッチ画像付き)

視覚的に訴求力の高い、カード形式のデザインです。

/* お知らせセクション */
.news-section {
    max-width: 1200px;
    margin: 60px auto;
    padding: 0 20px;
}

.news-heading {
    font-size: 32px;
    font-weight: 700;
    margin-bottom: 40px;
    text-align: center;
    color: #333;
}

/* グリッドレイアウト */
.news-list {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 30px;
    list-style: none;
    padding: 0;
    margin: 0;
}

/* カード */
.news-item {
    background: #fff;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.news-item:hover {
    transform: translateY(-5px);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}

/* アイキャッチ画像 */
.news-thumbnail {
    width: 100%;
    height: 200px;
    overflow: hidden;
}

.news-thumbnail img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.3s ease;
}

.news-item:hover .news-thumbnail img {
    transform: scale(1.05);
}

/* コンテンツエリア */
.news-content {
    padding: 20px;
}

.news-date {
    display: block;
    font-size: 13px;
    color: #999;
    margin-bottom: 10px;
}

.news-title {
    font-size: 16px;
    font-weight: 600;
    margin: 0;
    line-height: 1.5;
}

.news-title a {
    color: #333;
    text-decoration: none;
}

.news-title a:hover {
    color: #0066cc;
}

/* 抜粋文(オプション) */
.news-excerpt {
    font-size: 14px;
    color: #666;
    line-height: 1.6;
    margin-top: 10px;
}

実際の表示

See the Pen wp-news-section-02 by watashi-xyz (@watashi-xyz) on CodePen.

パターン3: タイムライン風レイアウト

時系列を強調したい場合に効果的なデザインです。

/* お知らせセクション */
.news-section {
    max-width: 800px;
    margin: 60px auto;
    padding: 0 20px;
}

.news-heading {
    font-size: 32px;
    font-weight: 700;
    margin-bottom: 50px;
    color: #333;
}

/* タイムラインリスト */
.news-list {
    list-style: none;
    padding: 0;
    margin: 0;
    position: relative;
    padding-left: 40px;
}

/* 縦線 */
.news-list::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 2px;
    background: linear-gradient(to bottom, #0066cc, #00cc99);
}

/* 各お知らせアイテム */
.news-item {
    position: relative;
    padding: 0 0 40px 20px;
}

/* ドット */
.news-item::before {
    content: '';
    position: absolute;
    left: -44px;
    top: 5px;
    width: 12px;
    height: 12px;
    background: #0066cc;
    border: 3px solid #fff;
    border-radius: 50%;
    box-shadow: 0 0 0 2px #0066cc;
}

.news-date {
    display: block;
    font-size: 13px;
    color: #0066cc;
    font-weight: 600;
    margin-bottom: 8px;
}

.news-title {
    font-size: 18px;
    font-weight: 600;
    margin: 0 0 10px 0;
    line-height: 1.5;
}

.news-title a {
    color: #333;
    text-decoration: none;
    transition: color 0.3s ease;
}

.news-title a:hover {
    color: #0066cc;
}

.news-excerpt {
    font-size: 14px;
    color: #666;
    line-height: 1.7;
}

実際の表示

See the Pen Untitled by watashi-xyz (@watashi-xyz) on CodePen.

モバイルでも見やすい「お知らせ欄」デザインのコツ

スマートフォンでの閲覧が主流となった現在、レスポンシブ対応は必須です。以下のベストプラクティスを実装することで、どのデバイスでも快適な閲覧体験を提供できます。

基本的なレスポンシブCSS

上記のパターン1(リスト型)をモバイル対応させる例です。

/* タブレット以下(768px未満) */
@media (max-width: 767px) {
    .news-section {
        margin: 40px auto;
        padding: 0 15px;
    }

    .news-heading {
        font-size: 24px;
        margin-bottom: 30px;
        padding-bottom: 10px;
    }

    /* リストアイテムを縦並びに */
    .news-item {
        flex-direction: column;
        align-items: flex-start;
        padding: 20px 0;
    }

    .news-date {
        width: auto;
        margin-bottom: 8px;
        font-size: 13px;
    }

    .news-title {
        font-size: 15px;
    }

    .news-more {
        width: 100%;
        text-align: center;
        padding: 14px 20px;
    }
}

/* スマートフォン(480px未満) */
@media (max-width: 479px) {
    .news-heading {
        font-size: 20px;
    }

    .news-title {
        font-size: 14px;
    }
}

カード型レイアウトのレスポンシブ対応

/* タブレット(768px未満) */
@media (max-width: 767px) {
    .news-list {
        grid-template-columns: repeat(2, 1fr);
        gap: 20px;
    }

    .news-thumbnail {
        height: 150px;
    }

    .news-content {
        padding: 15px;
    }
}

/* スマートフォン(480px未満) */
@media (max-width: 479px) {
    .news-list {
        grid-template-columns: 1fr;
        gap: 20px;
    }

    .news-thumbnail {
        height: 180px;
    }
}

モバイルファーストの設計原則

より効率的なアプローチとして、モバイルファーストで記述する方法もおすすめです。

/* モバイル(デフォルト) */
.news-list {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.news-item {
    flex-direction: column;
}

/* タブレット以上(768px以上) */
@media (min-width: 768px) {
    .news-item {
        flex-direction: row;
        align-items: center;
    }

    .news-date {
        width: 120px;
        margin-bottom: 0;
    }
}

/* デスクトップ(1024px以上) */
@media (min-width: 1024px) {
    .news-section {
        padding: 0 40px;
    }
}

タッチターゲットの最適化

スマートフォンでは、タップしやすいサイズを確保することが重要です。

/* モバイルでのリンク領域を広げる */
@media (max-width: 767px) {
    .news-item {
        position: relative;
    }

    /* アイテム全体をクリッカブルに */
    .news-title a::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
    }

    /* 最低タップサイズを確保(48px推奨) */
    .news-item {
        min-height: 60px;
        padding: 15px 10px;
    }
}

アイキャッチ・日付・ラベルで視覚的に伝えるUI改善術

お知らせの内容を一目で理解できるようにする、実用的なUI改善テクニックを紹介します。

1. カテゴリーラベルの実装

お知らせの種類を視覚的に区別できるラベルを追加します。

HTML例:

<li class="news-item">
    <?php
    // カテゴリーを取得
    $terms = get_the_terms(get_the_ID(), 'news_category');
    if ($terms && !is_wp_error($terms)) :
        $term = array_shift($terms);
        $term_slug = $term->slug;
    ?>
        <span class="news-label news-label-<?php echo esc_attr($term_slug); ?>">
            <?php echo esc_html($term->name); ?>
        </span>
    <?php endif; ?>

    <time class="news-date"><?php echo get_the_date('Y.m.d'); ?></time>
    <h3 class="news-title">
        <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
    </h3>
</li>

CSS例:

/* ラベルの基本スタイル */
.news-label {
    display: inline-block;
    padding: 4px 12px;
    font-size: 12px;
    font-weight: 600;
    border-radius: 3px;
    margin-right: 10px;
    color: #fff;
}

/* カテゴリーごとの色分け */
.news-label-important {
    background-color: #dc3545; /* 赤:重要 */
}

.news-label-event {
    background-color: #28a745; /* 緑:イベント */
}

.news-label-maintenance {
    background-color: #ffc107; /* 黄:メンテナンス */
    color: #333;
}

.news-label-general {
    background-color: #6c757d; /* グレー:一般 */
}

2. NEW・更新アイコンの自動表示

公開から7日以内の記事に「NEW」バッジを表示します。

PHP例:

<li class="news-item">
    <?php
    // 公開日からの経過日数を計算
    $days_ago = floor((time() - get_the_time('U')) / (60 * 60 * 24));

    if ($days_ago <= 7) :
    ?>
        <span class="badge-new">NEW</span>
    <?php endif; ?>

    <time class="news-date"><?php echo get_the_date('Y.m.d'); ?></time>
    <h3 class="news-title">
        <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
    </h3>
</li>

CSS例:

.badge-new {
    display: inline-block;
    padding: 3px 8px;
    background: linear-gradient(135deg, #ff6b6b, #ee5a6f);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    border-radius: 3px;
    margin-right: 8px;
    animation: pulse 2s infinite;
}

@keyframes pulse {
    0%, 100% {
        opacity: 1;
    }
    50% {
        opacity: 0.7;
    }
}

3. アイキャッチ画像の最適表示

アイキャッチ画像を効果的に表示する実装例です。

/* アイキャッチのアスペクト比を固定 */
.news-thumbnail {
    position: relative;
    width: 100%;
    padding-top: 56.25%; /* 16:9の比率 */
    overflow: hidden;
    background-color: #f0f0f0;
}

.news-thumbnail img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* 画像がない場合のプレースホルダー */
.news-thumbnail.no-image::after {
    content: 'NO IMAGE';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: #999;
    font-size: 14px;
    font-weight: 600;
}

4. ホバーエフェクトで操作性を向上

/* カード全体のホバーエフェクト */
.news-item {
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.news-item:hover {
    transform: translateY(-4px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}

/* 画像のズームエフェクト */
.news-thumbnail {
    overflow: hidden;
}

.news-thumbnail img {
    transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}

.news-item:hover .news-thumbnail img {
    transform: scale(1.1);
}

/* タイトルのアンダーラインアニメーション */
.news-title a {
    position: relative;
    display: inline-block;
}

.news-title a::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: -2px;
    width: 0;
    height: 2px;
    background-color: #0066cc;
    transition: width 0.3s ease;
}

.news-item:hover .news-title a::after {
    width: 100%;
}

5. アクセシビリティを考慮したデザイン

視覚障害のあるユーザーにも配慮した実装例です。

/* コントラスト比を確保 */
.news-date {
    color: #555; /* 最低でも4.5:1のコントラスト比 */
}

/* フォーカス時のアウトライン */
.news-title a:focus {
    outline: 2px solid #0066cc;
    outline-offset: 2px;
}

/* スクリーンリーダー用のテキスト */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

HTML例(スクリーンリーダー対応):

<a href="<?php the_permalink(); ?>">
    <?php the_title(); ?>
    <span class="sr-only">の詳細を見る</span>
</a>

6. ローディング状態の表示(Ajax使用時)

/* ローディングスピナー */
.news-loading {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 40px;
}

.spinner {
    width: 40px;
    height: 40px;
    border: 4px solid #f3f3f3;
    border-top: 4px solid #0066cc;
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* スケルトンスクリーン(読み込み中のプレースホルダー) */
.news-skeleton {
    background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
    background-size: 200% 100%;
    animation: loading 1.5s infinite;
}

@keyframes loading {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

これらのデザインテクニックとレスポンシブ対応を実装することで、プロフェッショナルで使いやすいお知らせ機能が完成します。次のセクションでは、さらに高度な機能を追加して、運用効率を劇的に向上させる方法を解説します。

応用編|動的で便利なお知らせ機能を実現するカスタマイズ

基本的なお知らせ機能が実装できたら、次は運用効率を劇的に向上させる高度な機能を追加しましょう。このセクションで紹介する機能を実装すれば、手動更新の手間を大幅に削減し、より戦略的な情報発信が可能になります。

公開期間を設定して自動で非表示にする方法(期限付き表示)

「キャンペーンのお知らせを3日間だけ表示したい」「イベント終了後は自動で非表示にしたい」といったニーズに応える、公開期限機能の実装方法です。この機能があれば、毎回手動で削除する手間が一切不要になります。

ステップ1: カスタムフィールドを追加する

まず、お知らせの編集画面に「公開終了日」を入力できるフィールドを追加します。プラグインを使わずに実装する方法を紹介します。

functions.phpに追加:

<?php
// カスタムフィールドのメタボックスを追加
function add_news_expiration_meta_box() {
    add_meta_box(
        'news_expiration',           // メタボックスID
        '公開期間設定',              // タイトル
        'render_news_expiration_meta_box', // コールバック関数
        'news',                      // 投稿タイプ
        'side',                      // 表示位置(サイドバー)
        'high'                       // 優先度
    );
}
add_action('add_meta_boxes', 'add_news_expiration_meta_box');

// メタボックスの内容を表示
function render_news_expiration_meta_box($post) {
    // nonceフィールドを追加(セキュリティ対策)
    wp_nonce_field('news_expiration_nonce', 'news_expiration_nonce_field');

    // 既存の値を取得
    $expiration_date = get_post_meta($post->ID, '_news_expiration_date', true);

    ?>
    <p>
        <label for="news_expiration_date">公開終了日時:</label><br>
        <input type="datetime-local"
               id="news_expiration_date"
               name="news_expiration_date"
               value="<?php echo esc_attr($expiration_date); ?>"
               style="width: 100%;">
    </p>
    <p class="description">
        この日時を過ぎると、お知らせは自動的に非表示になります。<br>
        空欄の場合は無期限で表示されます。
    </p>
    <?php
}

// カスタムフィールドの値を保存
function save_news_expiration_meta($post_id) {
    // nonce検証
    if (!isset($_POST['news_expiration_nonce_field']) ||
        !wp_verify_nonce($_POST['news_expiration_nonce_field'], 'news_expiration_nonce')) {
        return;
    }

    // 自動保存の場合は処理をスキップ
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }

    // 権限チェック
    if (!current_user_can('edit_post', $post_id)) {
        return;
    }

    // データを保存
    if (isset($_POST['news_expiration_date'])) {
        $expiration_date = sanitize_text_field($_POST['news_expiration_date']);
        update_post_meta($post_id, '_news_expiration_date', $expiration_date);
    } else {
        delete_post_meta($post_id, '_news_expiration_date');
    }
}
add_action('save_post_news', 'save_news_expiration_meta');
?>

ステップ2: 期限切れのお知らせを自動で除外する

表示時に期限をチェックして、期限切れのお知らせを除外します。

表示用のPHPコード:

<?php
// 現在の日時を取得
$current_datetime = current_time('Y-m-d\\TH:i');

$args = array(
    'post_type'      => 'news',
    'posts_per_page' => 10,
    'orderby'        => 'date',
    'order'          => 'DESC',
    'meta_query'     => array(
        'relation' => 'OR',
        array(
            'key'     => '_news_expiration_date',
            'value'   => $current_datetime,
            'compare' => '>=',
            'type'    => 'DATETIME',
        ),
        array(
            'key'     => '_news_expiration_date',
            'compare' => 'NOT EXISTS', // 期限が設定されていない投稿も含める
        ),
    ),
);

$news_query = new WP_Query($args);

if ($news_query->have_posts()) :
    while ($news_query->have_posts()) : $news_query->the_post();
        // お知らせを表示
    endwhile;
    wp_reset_postdata();
endif;
?>

ステップ3: 管理画面の一覧に期限を表示する

管理画面でひと目で期限が分かるようにします。

<?php
// 管理画面の一覧カラムに「公開終了日」を追加
function add_news_expiration_column($columns) {
    $columns['expiration'] = '公開終了日';
    return $columns;
}
add_filter('manage_news_posts_columns', 'add_news_expiration_column');

// カラムの内容を表示
function display_news_expiration_column($column, $post_id) {
    if ($column === 'expiration') {
        $expiration_date = get_post_meta($post_id, '_news_expiration_date', true);

        if ($expiration_date) {
            // 日時を読みやすい形式に変換
            $datetime = DateTime::createFromFormat('Y-m-d\\TH:i', $expiration_date);
            echo $datetime->format('Y年m月d日 H:i');

            // 期限切れかチェック
            $current_datetime = current_time('Y-m-d\\TH:i');
            if ($expiration_date < $current_datetime) {
                echo '<br><span style="color: #dc3545; font-weight: bold;">期限切れ</span>';
            }
        } else {
            echo '無期限';
        }
    }
}
add_action('manage_news_posts_custom_column', 'display_news_expiration_column', 10, 2);

// カラムをソート可能にする
function make_news_expiration_sortable($columns) {
    $columns['expiration'] = 'expiration';
    return $columns;
}
add_filter('manage_edit-news_sortable_columns', 'make_news_expiration_sortable');
?>

応用: 公開開始日も設定する

公開開始日と終了日の両方を管理したい場合は、以下のように拡張できます。

<?php
function render_news_schedule_meta_box($post) {
    wp_nonce_field('news_schedule_nonce', 'news_schedule_nonce_field');

    $start_date = get_post_meta($post->ID, '_news_start_date', true);
    $end_date = get_post_meta($post->ID, '_news_end_date', true);
    ?>
    <p>
        <label for="news_start_date">公開開始日時:</label><br>
        <input type="datetime-local"
               id="news_start_date"
               name="news_start_date"
               value="<?php echo esc_attr($start_date); ?>"
               style="width: 100%;">
    </p>
    <p>
        <label for="news_end_date">公開終了日時:</label><br>
        <input type="datetime-local"
               id="news_end_date"
               name="news_end_date"
               value="<?php echo esc_attr($end_date); ?>"
               style="width: 100%;">
    </p>
    <?php
}

// 表示時のクエリ
$current_datetime = current_time('Y-m-d\\TH:i');

$args = array(
    'post_type'      => 'news',
    'posts_per_page' => 10,
    'meta_query'     => array(
        'relation' => 'AND',
        array(
            'relation' => 'OR',
            array(
                'key'     => '_news_start_date',
                'value'   => $current_datetime,
                'compare' => '<=',
                'type'    => 'DATETIME',
            ),
            array(
                'key'     => '_news_start_date',
                'compare' => 'NOT EXISTS',
            ),
        ),
        array(
            'relation' => 'OR',
            array(
                'key'     => '_news_end_date',
                'value'   => $current_datetime,
                'compare' => '>=',
                'type'    => 'DATETIME',
            ),
            array(
                'key'     => '_news_end_date',
                'compare' => 'NOT EXISTS',
            ),
        ),
    ),
);
?>

お知らせを「重要」「通常」で分類しラベル表示する方法

重要度の高いお知らせを目立たせることで、ユーザーに確実に情報を届けられます。

方法1: カスタムフィールドで重要度を設定

functions.phpに追加:

<?php
// 重要度設定のメタボックスを追加
function add_news_priority_meta_box() {
    add_meta_box(
        'news_priority',
        '重要度設定',
        'render_news_priority_meta_box',
        'news',
        'side',
        'high'
    );
}
add_action('add_meta_boxes', 'add_news_priority_meta_box');

// メタボックスの内容
function render_news_priority_meta_box($post) {
    wp_nonce_field('news_priority_nonce', 'news_priority_nonce_field');

    $priority = get_post_meta($post->ID, '_news_priority', true);
    if (empty($priority)) {
        $priority = 'normal';
    }
    ?>
    <p>
        <label>
            <input type="radio" name="news_priority" value="high"
                   <?php checked($priority, 'high'); ?>>
            重要
        </label><br>
        <label>
            <input type="radio" name="news_priority" value="normal"
                   <?php checked($priority, 'normal'); ?>>
            通常
        </label>
    </p>
    <?php
}

// 重要度を保存
function save_news_priority_meta($post_id) {
    if (!isset($_POST['news_priority_nonce_field']) ||
        !wp_verify_nonce($_POST['news_priority_nonce_field'], 'news_priority_nonce')) {
        return;
    }

    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }

    if (!current_user_can('edit_post', $post_id)) {
        return;
    }

    if (isset($_POST['news_priority'])) {
        update_post_meta($post_id, '_news_priority', sanitize_text_field($_POST['news_priority']));
    }
}
add_action('save_post_news', 'save_news_priority_meta');
?>

表示時に重要度で並び替え&ラベル表示

<?php
$args = array(
    'post_type'      => 'news',
    'posts_per_page' => 10,
    'meta_key'       => '_news_priority',
    'orderby'        => array(
        'meta_value' => 'DESC',  // 重要度順(highが先)
        'date'       => 'DESC',  // 同じ重要度なら新しい順
    ),
);

$news_query = new WP_Query($args);

if ($news_query->have_posts()) : ?>
    <ul class="news-list">
        <?php while ($news_query->have_posts()) : $news_query->the_post();
            $priority = get_post_meta(get_the_ID(), '_news_priority', true);
        ?>
            <li class="news-item news-item-<?php echo esc_attr($priority); ?>">
                <?php if ($priority === 'high') : ?>
                    <span class="news-badge news-badge-important">重要</span>
                <?php endif; ?>

                <time class="news-date"><?php echo get_the_date('Y.m.d'); ?></time>
                <h3 class="news-title">
                    <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
                </h3>
            </li>
        <?php endwhile; ?>
    </ul>
    <?php
    wp_reset_postdata();
endif;
?>

CSS(重要なお知らせを目立たせる):

/* 重要なお知らせの背景色を変更 */
.news-item-high {
    background-color: #fff8f0;
    border-left: 4px solid #ff6b00;
}

/* 重要バッジ */
.news-badge-important {
    display: inline-block;
    padding: 4px 10px;
    background: linear-gradient(135deg, #ff6b00, #ff8c42);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    border-radius: 3px;
    margin-right: 10px;
    animation: attention 2s ease-in-out infinite;
}

@keyframes attention {
    0%, 100% {
        transform: scale(1);
    }
    50% {
        transform: scale(1.05);
    }
}

方法2: カスタムタクソノミーで重要度を管理

より柔軟に管理したい場合は、タクソノミーを使う方法もあります。

<?php
function create_news_priority_taxonomy() {
    $labels = array(
        'name'          => '重要度',
        'singular_name' => '重要度',
        'menu_name'     => '重要度',
    );

    $args = array(
        'hierarchical'      => true,
        'labels'            => $labels,
        'show_ui'           => true,
        'show_admin_column' => true,
        'query_var'         => true,
        'rewrite'           => array('slug' => 'priority'),
        'show_in_rest'      => true,
    );

    register_taxonomy('news_priority', array('news'), $args);
}
add_action('init', 'create_news_priority_taxonomy');

// デフォルトのタームを自動作成
function create_default_news_priority_terms() {
    if (!term_exists('重要', 'news_priority')) {
        wp_insert_term('重要', 'news_priority', array('slug' => 'high'));
    }
    if (!term_exists('通常', 'news_priority')) {
        wp_insert_term('通常', 'news_priority', array('slug' => 'normal'));
    }
}
add_action('init', 'create_default_news_priority_terms');
?>

REST API・RSS配信・SNS連携で多方面に通知する仕組み

お知らせを複数のチャネルで自動配信することで、より多くのユーザーにリーチできます。

1. REST APIでお知らせをJSON形式で取得

WordPressのREST APIを活用すれば、外部アプリやサービスからお知らせを取得できます。

カスタム投稿タイプ作成時にREST API対応を有効化:

<?php
function create_news_post_type() {
    $args = array(
        'public'        => true,
        'show_in_rest'  => true,  // REST API対応を有効化
        'rest_base'     => 'news', // エンドポイント名
        // その他の設定...
    );

    register_post_type('news', $args);
}
?>

REST APIエンドポイント:

お知らせ一覧を取得:

<https://example.com/wp-json/wp/v2/news>

最新5件のみ取得:

<https://example.com/wp-json/wp/v2/news?per_page=5>

カスタムフィールドも含めて取得:

<https://example.com/wp-json/wp/v2/news?_fields=id,title,date,meta>

JavaScriptでお知らせを取得する例:

fetch('<https://example.com/wp-json/wp/v2/news?per_page=3>')
  .then(response => response.json())
  .then(data => {
    data.forEach(news => {
      console.log(news.title.rendered);
      console.log(news.date);
      console.log(news.link);
    });
  });

2. RSSフィードのカスタマイズ

お知らせ専用のRSSフィードを作成します。

functions.phpに追加:

<?php
// お知らせ用のカスタムフィードを追加
function add_news_feed() {
    add_feed('news', 'generate_news_feed');
}
add_action('init', 'add_news_feed');

// フィードの内容を生成
function generate_news_feed() {
    header('Content-Type: application/rss+xml; charset=UTF-8');

    $args = array(
        'post_type'      => 'news',
        'posts_per_page' => 20,
        'orderby'        => 'date',
        'order'          => 'DESC',
    );

    $news_query = new WP_Query($args);

    echo '<?xml version="1.0" encoding="UTF-8"?>';
    ?>
    <rss version="2.0">
        <channel>
            <title><?php bloginfo('name'); ?> - お知らせ</title>
            <link><?php bloginfo('url'); ?></link>
            <description>最新のお知らせ情報</description>
            <language>ja</language>

            <?php while ($news_query->have_posts()) : $news_query->the_post(); ?>
                <item>
                    <title><?php the_title_rss(); ?></title>
                    <link><?php the_permalink_rss(); ?></link>
                    <pubDate><?php echo get_post_time('D, d M Y H:i:s +0000', true); ?></pubDate>
                    <description><?php the_excerpt_rss(); ?></description>
                    <guid isPermaLink="true"><?php the_permalink_rss(); ?></guid>
                </item>
            <?php endwhile; ?>

        </channel>
    </rss>
    <?php
    wp_reset_postdata();
    exit;
}
?>

フィードURL:

<https://example.com/feed/news/>

このURLをRSSリーダーに登録すれば、自動でお知らせを受信できます。

3. 新規投稿時にSlackへ自動通知

functions.phpに追加:

<?php
// お知らせ公開時にSlackへ通知
function notify_slack_on_news_publish($post_id, $post) {
    // 自動保存や下書きの場合はスキップ
    if (wp_is_post_revision($post_id) || $post->post_status !== 'publish') {
        return;
    }

    // Slack Webhook URL(各自で取得する必要があります)
    $webhook_url = '<https://hooks.slack.com/services/YOUR/WEBHOOK/URL>';

    // 送信するメッセージを作成
    $message = array(
        'text' => '新しいお知らせが投稿されました',
        'attachments' => array(
            array(
                'color' => '#0066cc',
                'title' => get_the_title($post_id),
                'title_link' => get_permalink($post_id),
                'text' => wp_trim_words(get_the_excerpt($post_id), 20),
                'footer' => get_bloginfo('name'),
                'ts' => current_time('timestamp'),
            ),
        ),
    );

    // Slackに送信
    wp_remote_post($webhook_url, array(
        'body' => json_encode($message),
        'headers' => array('Content-Type' => 'application/json'),
    ));
}
add_action('publish_news', 'notify_slack_on_news_publish', 10, 2);
?>

4. TwitterへOGP画像付きで自動投稿

Jetpackプラグインを使用する方法(推奨):

  1. Jetpackプラグインをインストール・有効化
  2. 「設定」→「共有」→「パブリサイズ共有」でTwitterアカウントを連携
  3. お知らせ投稿タイプで自動共有を有効化

プログラムで実装する場合(Twitter API v2使用):

<?php
function auto_tweet_news($post_id, $post) {
    if ($post->post_status !== 'publish') {
        return;
    }

    // Twitter API設定(各自で取得する必要があります)
    $bearer_token = 'YOUR_BEARER_TOKEN';

    // ツイート内容を作成
    $tweet_text = get_the_title($post_id) . "\\n" . get_permalink($post_id);

    // Twitter APIにリクエスト
    $response = wp_remote_post('<https://api.twitter.com/2/tweets>', array(
        'headers' => array(
            'Authorization' => 'Bearer ' . $bearer_token,
            'Content-Type' => 'application/json',
        ),
        'body' => json_encode(array(
            'text' => $tweet_text,
        )),
    ));
}
add_action('publish_news', 'auto_tweet_news', 10, 2);
?>

5. メールマガジンへの自動連携

MailChimp API連携の例:

<?php
function add_news_to_mailchimp($post_id, $post) {
    if ($post->post_status !== 'publish') {
        return;
    }

    // MailChimp API設定
    $api_key = 'YOUR_API_KEY';
    $list_id = 'YOUR_LIST_ID';
    $campaign_id = 'YOUR_CAMPAIGN_ID';

    // キャンペーンのコンテンツを更新
    $content = '<h2>' . get_the_title($post_id) . '</h2>';
    $content .= '<p>' . get_the_excerpt($post_id) . '</p>';
    $content .= '<a href="' . get_permalink($post_id) . '">続きを読む</a>';

    // API経由でMailChimpに送信
    // 実装の詳細はMailChimpのドキュメントを参照
}
add_action('publish_news', 'add_news_to_mailchimp', 10, 2);
?>

これらの高度なカスタマイズを実装することで、お知らせ機能が単なる情報掲載から、戦略的なコミュニケーションツールへと進化します。手動での更新作業を最小限に抑えながら、複数のチャネルで効果的に情報を届けられるようになります。

よくある質問(FAQ)

お知らせ機能の実装や運用において、多くの方が疑問に感じる点を詳しく解説します。技術的なトラブルシューティングから、SEO戦略まで網羅しています。

お知らせページはSEO的にインデックスさせるべきですか?

ケースバイケースですが、一般的には「重要なお知らせはインデックス、一時的な情報はnoindex」が推奨です。

インデックスさせるべきお知らせ

以下のような、ユーザーにとって長期的に価値のある情報はインデックスさせることでSEO効果が期待できます。

  • 新サービス・新商品の発表
  • 業界のトレンドに関する解説記事的なお知らせ
  • 企業の重要な方針変更やリブランディング
  • ユーザーの検索意図と合致する可能性が高い情報

実装方法(インデックスさせる):

特別な設定は不要です。通常通り公開すれば自動的にインデックスされます。

noindexにすべきお知らせ

以下のような、一時的で検索価値の低い情報はnoindexを設定してクローラーの無駄遣いを防ぎましょう。

  • 臨時休業やメンテナンス情報
  • 期間限定キャンペーン(終了後は価値がない)
  • 社内イベントの報告
  • 年末年始の営業時間変更

実装方法(noindexにする):

カスタムフィールドでnoindexフラグを設定します。

<?php
// functions.phpに追加
function add_news_noindex_option() {
    add_meta_box(
        'news_seo',
        'SEO設定',
        'render_news_noindex_meta_box',
        'news',
        'side',
        'default'
    );
}
add_action('add_meta_boxes', 'add_news_noindex_option');

function render_news_noindex_meta_box($post) {
    wp_nonce_field('news_noindex_nonce', 'news_noindex_nonce_field');
    $noindex = get_post_meta($post->ID, '_news_noindex', true);
    ?>
    <label>
        <input type="checkbox" name="news_noindex" value="1" <?php checked($noindex, '1'); ?>>
        この記事を検索エンジンにインデックスさせない(noindex)
    </label>
    <?php
}

function save_news_noindex_meta($post_id) {
    if (!isset($_POST['news_noindex_nonce_field']) ||
        !wp_verify_nonce($_POST['news_noindex_nonce_field'], 'news_noindex_nonce')) {
        return;
    }

    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }

    if (!current_user_can('edit_post', $post_id)) {
        return;
    }

    if (isset($_POST['news_noindex'])) {
        update_post_meta($post_id, '_news_noindex', '1');
    } else {
        delete_post_meta($post_id, '_news_noindex');
    }
}
add_action('save_post_news', 'save_news_noindex_meta');

// headにnoindexタグを出力
function output_news_noindex_tag() {
    if (is_singular('news')) {
        $noindex = get_post_meta(get_the_ID(), '_news_noindex', true);
        if ($noindex === '1') {
            echo '<meta name="robots" content="noindex, follow">' . "\\n";
        }
    }
}
add_action('wp_head', 'output_news_noindex_tag', 1);
?>

お知らせ一覧ページのSEO対策

お知らせアーカイブページ(/news/)については、以下の判断基準を参考にしてください。

  • インデックスさせる場合: サイト内で重要なコンテンツハブとして機能させたいとき
  • noindexにする場合: 個々のお知らせページだけで十分なとき
<?php
// お知らせアーカイブをnoindexにする
function noindex_news_archive() {
    if (is_post_type_archive('news')) {
        echo '<meta name="robots" content="noindex, follow">' . "\\n";
    }
}
add_action('wp_head', 'noindex_news_archive', 1);
?>

SEOプラグインとの連携

Yoast SEOやAll in One SEOなどのプラグインを使用している場合、各お知らせの編集画面で個別にnoindex設定ができます。プラグインの設定が優先されるため、上記のコードとの併用には注意が必要です。

カスタム投稿タイプ作成時に404エラーが出た場合の対処法は?

A: パーマリンク設定の更新(フラッシュ)で99%解決します。

原因

WordPressはURL構造の情報を.htaccessファイル(Apacheの場合)やデータベースにキャッシュしています。カスタム投稿タイプを新規作成しても、この情報が更新されないため404エラーが発生します。

解決方法1: パーマリンク設定の更新(最も簡単)

  1. WordPress管理画面にログイン
  2. 「設定」→「パーマリンク設定」を開く
  3. 何も変更せず、ページ下部の「変更を保存」ボタンをクリック

これだけで、URLの再書き込みルールが更新され、404エラーが解消されます。

解決方法2: プログラムで自動的にフラッシュする

テーマやプラグインの有効化時に自動的にパーマリンクをフラッシュする方法です。

<?php
// functions.phpに追加
function flush_rewrite_on_activation() {
    // カスタム投稿タイプを登録
    create_news_post_type();

    // パーマリンクをフラッシュ
    flush_rewrite_rules();
}

// テーマ有効化時に実行
add_action('after_switch_theme', 'flush_rewrite_on_activation');

// 注意: flush_rewrite_rules()は負荷が高いため、init時には実行しないこと
?>

重要な注意点:

flush_rewrite_rules()は処理が重いため、毎回のページ読み込み時(initフックなど)に実行してはいけません。必ずテーマやプラグインの有効化時など、限定的なタイミングで実行してください。

解決方法3: .htaccessファイルの確認(Apache使用時)

上記の方法で解決しない場合、.htaccessファイルに書き込み権限がない可能性があります。

  1. FTPまたはサーバーのファイルマネージャーで.htaccessファイルを確認
  2. ファイルのパーミッションを644に設定
  3. WordPressディレクトリの書き込み権限を確認

Nginxを使用している場合

Nginxではrewriteルールを手動で設定する必要があります。サーバー設定ファイル(通常は/etc/nginx/sites-available/内)に以下を追加してください。

location /news/ {
    try_files $uri $uri/ /index.php?post_type=news;
}

設定後、Nginxを再起動します。

sudo systemctl restart nginx

それでも解決しない場合のチェックリスト

  • カスタム投稿タイプのスラッグ('rewrite' => array('slug' => 'news'))が既存のページと重複していないか
  • プラグインの競合がないか(すべてのプラグインを一時的に無効化して確認)
  • テーマのfunctions.phpにPHPエラーがないか(デバッグモードで確認)
  • マルチサイト環境の場合、ネットワーク管理者権限でパーマリンクを更新しているか

既存の投稿記事を「お知らせ」に移行する方法はありますか?

はい、プラグインまたはSQLクエリで一括移行できます。

方法1: Post Type Switcherプラグインを使う(推奨・初心者向け)

最も簡単で安全な方法です。

手順:

  1. Post Type Switcherプラグインをインストール・有効化
  2. 管理画面の「投稿」一覧を開く
  3. 移行したい投稿にチェックを入れる
  4. 「一括操作」から「編集」を選択して「適用」をクリック
  5. 「投稿タイプ」のドロップダウンから「お知らせ(news)」を選択
  6. 「更新」ボタンをクリック

これで、選択した投稿が一括でお知らせに変換されます。

方法2: SQLクエリで直接変換(上級者向け)

データベースに直接アクセスして一括変換する方法です。必ずバックアップを取ってから実行してください。

phpMyAdminまたはSQLクライアントで実行:

-- 特定のカテゴリーIDの投稿をお知らせに変換
UPDATE wp_posts
SET post_type = 'news'
WHERE post_type = 'post'
AND ID IN (
    SELECT object_id
    FROM wp_term_relationships
    WHERE term_taxonomy_id = 5  -- カテゴリーIDを指定
);

-- または、特定の日付範囲の投稿を変換
UPDATE wp_posts
SET post_type = 'news'
WHERE post_type = 'post'
AND post_date >= '2024-01-01'
AND post_date <= '2024-12-31';

WP-CLIを使う方法(コマンドライン):

# 特定のカテゴリーの投稿を変換
wp post list --post_type=post --category=5 --format=ids | xargs -d ' ' -I % wp post update % --post_type=news

# 確認
wp post list --post_type=news --format=table

方法3: functions.phpで自動変換スクリプトを実行

一時的にfunctions.phpに以下のコードを追加して、管理画面にアクセスすることで変換できます。

<?php
// functions.phpに一時的に追加(変換後は必ず削除すること)
function convert_posts_to_news() {
    // 既に実行済みかチェック
    if (get_option('posts_converted_to_news')) {
        return;
    }

    // 特定のカテゴリーの投稿を取得
    $args = array(
        'post_type'      => 'post',
        'posts_per_page' => -1,
        'category_name'  => 'news',  // カテゴリースラッグを指定
        'post_status'    => 'any',
    );

    $posts = get_posts($args);

    foreach ($posts as $post) {
        // 投稿タイプを変更
        wp_update_post(array(
            'ID'        => $post->ID,
            'post_type' => 'news',
        ));
    }

    // 実行済みフラグを設定
    update_option('posts_converted_to_news', true);

    // 管理画面に通知
    add_action('admin_notices', function() {
        echo '<div class="notice notice-success"><p>投稿をお知らせに変換しました。</p></div>';
    });
}
add_action('admin_init', 'convert_posts_to_news');
?>

実行後の注意:

  1. 変換が完了したら、必ず上記のコードをfunctions.phpから削除してください
  2. パーマリンク設定を更新(「設定」→「パーマリンク設定」→「変更を保存」)
  3. 変換された投稿のURLが変わるため、リダイレクト設定を検討してください

カテゴリーやタグの移行

投稿のカテゴリーをお知らせのタクソノミーに変換したい場合:

<?php
function migrate_categories_to_news_taxonomy() {
    $args = array(
        'post_type'      => 'news',
        'posts_per_page' => -1,
    );

    $news_posts = get_posts($args);

    foreach ($news_posts as $post) {
        // 旧カテゴリーを取得
        $old_categories = wp_get_post_categories($post->ID, array('fields' => 'names'));

        // 新しいタクソノミーにセット
        wp_set_object_terms($post->ID, $old_categories, 'news_category');
    }
}
?>

お知らせの表示速度を改善する方法はありますか?

キャッシュの活用とクエリの最適化で大幅に改善できます。

対策1: Transient APIでクエリ結果をキャッシュ

<?php
function get_cached_news_list() {
    // キャッシュキー
    $cache_key = 'news_list_cache';

    // キャッシュを確認
    $cached_news = get_transient($cache_key);

    if ($cached_news !== false) {
        return $cached_news;
    }

    // キャッシュがない場合はクエリ実行
    $args = array(
        'post_type'      => 'news',
        'posts_per_page' => 5,
    );

    $news_query = new WP_Query($args);

    // 結果を保存(12時間キャッシュ)
    set_transient($cache_key, $news_query, 12 * HOUR_IN_SECONDS);

    return $news_query;
}

// 使用例
$news_query = get_cached_news_list();
?>

お知らせ更新時にキャッシュをクリア:

<?php
function clear_news_cache($post_id) {
    if (get_post_type($post_id) === 'news') {
        delete_transient('news_list_cache');
    }
}
add_action('save_post', 'clear_news_cache');
add_action('delete_post', 'clear_news_cache');
?>

対策2: 不要なデータを取得しない

<?php
$args = array(
    'post_type'      => 'news',
    'posts_per_page' => 5,
    'no_found_rows'  => true,  // ページネーション不要なら高速化
    'update_post_meta_cache' => false,  // カスタムフィールド不要なら
    'update_post_term_cache' => false,  // タクソノミー不要なら
    'fields'         => 'ids',  // IDのみ取得する場合
);
?>

対策3: オブジェクトキャッシュの導入

RedisMemcachedを使用することで、さらなる高速化が可能です。レンタルサーバーによっては標準で利用可能な場合があります。

複数の管理者で役割分担してお知らせを管理したい

WordPressの権限管理機能を活用すれば、柔軟な役割分担が可能です。

カスタム投稿タイプに独自の権限を設定

<?php
function create_news_post_type() {
    $args = array(
        'capability_type' => array('news_item', 'news_items'),
        'map_meta_cap'    => true,
        // その他の設定...
    );

    register_post_type('news', $args);
}

// 特定のユーザーロールに権限を付与
function add_news_capabilities() {
    // 編集者にお知らせの全権限を付与
    $editor = get_role('editor');
    $editor->add_cap('edit_news_items');
    $editor->add_cap('edit_others_news_items');
    $editor->add_cap('publish_news_items');
    $editor->add_cap('read_private_news_items');
    $editor->add_cap('delete_news_items');

    // 寄稿者には投稿のみ許可(公開権限なし)
    $contributor = get_role('contributor');
    $contributor->add_cap('edit_news_items');
    $contributor->add_cap('read_news_items');
}
add_action('admin_init', 'add_news_capabilities');
?>

これにより、お知らせ専用の権限管理が可能になり、ブログ記事とは独立して役割分担できます。

まとめ

ここまで、WordPressでお知らせ機能を実装するための方法を、基礎から応用まで徹底的に解説してきました。この記事で紹介した内容を実践すれば、もう外部の制作会社に頼る必要はありません。あなた自身の手で、企業サイトに求められるプロフェッショナルなお知らせシステムを構築できます。

重要ポイント

  • カスタム投稿タイプの活用が最適解:
    企業サイトでお知らせを運用するなら、通常の投稿ではなくカスタム投稿タイプで独立させることで、管理効率が劇的に向上します。ブログ記事との混在を避け、専用の管理画面で運用できるメリットは計り知れません。
  • コードを追加したらパーマリンク更新を忘れずに:
    functions.phpにカスタム投稿タイプのコードを追加した後は、必ず「設定」→「パーマリンク設定」→「変更を保存」を実行してください。これを忘れると404エラーが発生します。
  • WP_Queryで柔軟な表示制御:
    ショートコードやWP_Queryを使いこなせば、トップページ・固定ページ・サイドバーなど、どこにでも自由にお知らせを表示できます。表示件数やカテゴリー絞り込みも思いのままです。
  • レスポンシブ対応は必須:
    スマートフォンでの閲覧が主流の現在、モバイルでの見やすさは絶対に妥協できません。この記事で紹介したCSSサンプルをそのまま使えば、すぐにプロレベルのデザインを実現できます。
  • 公開期限機能で運用を自動化:
    カスタムフィールドで公開終了日を設定すれば、キャンペーンや期間限定のお知らせを手動で削除する手間が完全になくなります。一度設定すれば、あとは自動で非表示になる仕組みは運用効率を大幅に改善します。
  • SEO対策は選択的に:
    すべてのお知らせをインデックスさせる必要はありません。長期的な価値のある情報はインデックスし、一時的なメンテナンス情報などはnoindexを設定することで、Googleからの評価を最適化できます。
  • 多チャンネル配信で情報到達率アップ:
    REST APIやRSSフィード、Slack・Twitter連携を活用すれば、お知らせを複数のチャネルで同時配信できます。ユーザーがどこにいても情報を届けられる体制を整えましょう。

お知らせ機能は、企業サイトにとって「顧客とのコミュニケーションの要」となる重要な機能です。この記事を参考に、更新しやすく、見やすく、そして運用効率の高いお知らせシステムを構築してください。

サイト運営の効率化と、ユーザーへの確実な情報発信。その両方を実現できるお知らせ機能が、あなたのサイトに確実に価値をもたらすはずです。

タイトルとURLをコピーしました