WordPressで新着情報・更新履歴・お知らせ案内の作り方

タイトルで「新着情報」とか「更新履歴」とか「お知らせ案内」と言っていますが、内容は同じです。
呼び名が異なるだけで「記事の一覧を取ってきて投稿順に表示」というようにやっていることは同じです。

本ページでは「新着情報」で呼び名を統一したいと思います。

WordPressで新着情報を掲載するのは簡単です。

新着情報ってなに?

いきなりですが「新着情報」が何かはご存知でしょうか。

当サイトのトップページにも「更新案内」として掲載していますが、下図のようなコンテンツです。

年月日があって、何を行ったか、を簡単にリストにしたものです。

上図を見て「見慣れたものと違う」って思ったりしますか?

そうです。ただの新着情報ではなくひとてま加えたものになっています。

新着情報の仕様

本ページで案内する新着情報について簡単に仕様をまとめます。

ちなみによく見かけるのは「年月日」「ページタイトル」「ページタイトルに記事へのリンク」の3点セットだと思います。

それだけでは物足りないと思いますので次のような要件を盛り込みます。

  • プラグインは使わない
  • ショートコードとして作る
  • お知らせのための記事を作らなくても自動で更新
  • 初投稿した日時
  • 最後に更新した日時
  • 「公開」なのか「更新」なのか
  • 「投稿」と「固定ページ」が対象
  • 「固定ページ」は階層化している親のタイトル(または任意の祖先)

ざっくりとこんな感じです。

完成形は「新着情報ってなに?」に入れているスクショです。

そういえば「投稿」のほうで「カテゴリ」を含めたら良いな、と思いました。
もし「カテゴリ付も教えて!」って方がいましたらお問い合わせよりリクエストください。
※なぜ今しないかというとモチベーションの問題でして・・・モチベください

編集する場所

新着情報をトップページにしか置かないならショートコードにせずに対象ファイルにそのまま記述したら良いのですが、有料テーマを使っていたりなどそのまま記述するのが難しいケースがあります。

ということで、まずはショートコードとして作る方法をご案内いたします。

管理画面から行う場合

あまりお勧めしませんが、Wordpress 管理画面 > 外観 > テーマエディター から編集することができます。

FTPでPHPファイルを編集

FTPでPHPファイルを触れるならこっちのほうが安全でおすすめです。

作られている方の状況によって異なるかもしれませんが、Wordpressの作法・セオリー通りにやっているなら下記のディレクトリを見ることになります。

公開ディレクトリ / wp-content / themes / 自身のテーマ

ショートコードを作成する

編集対象のファイルは functions.php です。

functions.php の最後にでも下記をコピペします。

<?php
add_shortcode('aulta_notice', aulta_notice);

function aulta_notice()
{
    global $wpdb;

    $sql =<<<'EOT'
        SELECT
            wp_posts.ID,
            CASE
                WHEN wp_posts.post_type = 'post' THEN '投稿'
                WHEN wp_parent_posts2.post_title IS NOT NULL THEN wp_parent_posts2.post_title
                WHEN wp_parent_posts.post_title IS NOT NULL THEN wp_parent_posts.post_title
                ELSE wp_posts.post_title
                END AS parent_title,
            CASE
                WHEN wp_posts.post_type = 'page' AND wp_parent_posts.ID IS NULL THEN 'トップページ'
                ELSE wp_posts.post_title
                END AS post_title,
            wp_posts.post_date,
            wp_posts.post_modified,
            CASE
                WHEN DATE_FORMAT(wp_posts.post_date, '%Y-%m-%d') = DATE_FORMAT(wp_posts.post_modified, '%Y-%m-%d') THEN '公開'
                ELSE '更新'
                END AS status,
            CHAR_LENGTH(wp_posts.post_content) AS char_len,
            wp_posts.post_type,
            wp_parent_posts.ID AS parent_id1,
            wp_parent_posts.post_title AS parent_title1,
            wp_parent_posts2.ID AS parent_id2,
            wp_parent_posts2.post_title AS parent_title2
        FROM wp_posts
        LEFT JOIN wp_posts wp_parent_posts
            ON  wp_parent_posts.ID = wp_posts.post_parent
            AND wp_parent_posts.post_status = 'publish'
            AND wp_parent_posts.post_type = 'page'
        LEFT JOIN wp_posts wp_parent_posts2
            ON  wp_parent_posts2.ID = wp_parent_posts.post_parent
            AND wp_parent_posts2.post_status = 'publish'
            AND wp_parent_posts2.post_type = 'page'
        WHERE
              wp_posts.post_type IN ( 'post', 'page' )
          AND wp_posts.post_status = 'publish'
          AND CHAR_LENGTH(wp_posts.post_content) > 500
        ORDER BY
            wp_posts.post_modified DESC
        LIMIT 0, 10
EOT;

    $result = $wpdb->get_results($sql, ARRAY_A);

    // 対象記事がないとき
    if (empty($result)) {
        ob_start();
        ?>
            <p>
                新着はありません
            </p>
        <?php
        return ob_get_clean();
    }

    // 表示内容
    ob_start();
    ?>
        <div>
            <h2>更新案内</h2>
            <dl>
                <?php foreach($result as $row): ?>
                    <dt><?= \date('Y/m/d', strtotime($row['post_modified'])) ?></dt>
                    <dd>
                        <a href="<?= get_permalink($row['ID']) ?>">
                            <?= esc_html($row['parent_title']) ?>
                            <?= esc_html($row['post_title']) ?>
                        </a>
                        を<?= $row['status'] ?>しました。
                    </dd>
                <?php endforeach; ?>
            </dl>
        </div>
    <?php
    return ob_get_clean();
}
?>

これでショートコード [aulta_notice] として使えるようになります。

ショートコードを埋め込む

次は新着情報を埋め込みたい場所を決めます。
トップページなのか下層のページなのか色々あると思います。

今回はトップページということにします。

ですが、ここでまた問題が出るかもしれません。

管理画面から挿入できる場合

新着情報を挿入したい場所はWordpress管理画面の「投稿」とか「固定ページ」から編集できるようになっていますか?

編集できる場合は埋め込みたい場所に [aulta_notice] を入れて保存します。
ちなみに [aulta_notice] の前後の [ と ] も必要です。

管理画面からできない場合

管理画面から出来ない場合は、PHPファイルに直接書かれているってことですよね。

その場合、ご自身(もしくは近い関係者)がどのPHPファイルを編集すれば良いか分かっていると思います。

ということで次のように do_shortcode() を使います。

<section>
    なにか1
</section>

<?php echo do_shortcode( '[aulta_notice]' ); ?>

<section>
    なにか2
</section>

見た目のカスタマイズ

新着情報の表示のしかたを変えたい場合は、ショートコード内のHTML部分を編集してください。

本記事では説明の分かりやすさのため、不必要な装飾(cssやHTML)は省略しています。

運用が始まってしまえば「対象記事がない」なんてことはないと思いますので、次の部分はとりあえず形だけ入れてれば良いと思います。

<?php
    // 対象記事がないとき
    if (empty($result)) {
        ob_start();
        ?>
            <p>
                新着はありません
            </p>
        <?php
        return ob_get_clean();
    }
?>

次の部分で注意するのは、<?php から ?> で囲まれた部分です。

ここ以外はただのHTMLです。

<?php
    // 表示内容
    ob_start();
    ?>
        <div>
            <h2>更新案内</h2>
            <dl>
                <?php foreach($result as $row): ?>
                    <dt><?= \date('Y/m/d', strtotime($row['post_modified'])) ?></dt>
                    <dd>
                        <a href="<?= get_permalink($row['ID']) ?>">
                            <?= esc_html($row['parent_title']) ?>
                            <?= esc_html($row['post_title']) ?>
                        </a>
                        を<?= $row['status'] ?>しました。
                    </dd>
                <?php endforeach; ?>
            </dl>
        </div>
    <?php
    return ob_get_clean();
}
?>

ここにない項目を表示したいとかなら、SQLの SELECT を増やして調整します。

取得件数を変える

新着 10件分としていますが、件数を変えたい場合は SQL の数字を変えます。

SQLの最後にある数字を調整してください。

-- 取得する件数 (0件目から10件分)
LIMIT 0, 10

0, 10 の最初の 0 は「0件目から」を意味します。
次の 10 は「10件分」を意味します。「10件目まで」でないことに注意です。

SQLの説明

新着情報を取得するのに使ったSQLを少し説明します。

次は、コメントを追加したものです。

SELECT
    wp_posts.ID,

    -- グループ名
    -- 「投稿」のときは「投稿」
    -- 「固定ページ」のときはグループのトップになるタイトル
    CASE
        WHEN wp_posts.post_type = 'post' THEN '投稿'
        WHEN wp_parent_posts2.post_title IS NOT NULL THEN wp_parent_posts2.post_title
        WHEN wp_parent_posts.post_title IS NOT NULL THEN wp_parent_posts.post_title
        ELSE wp_posts.post_title
        END AS parent_title,

    -- ページタイトル
    CASE
        WHEN wp_posts.post_type = 'page' AND wp_parent_posts.ID IS NULL THEN 'トップページ'
        ELSE wp_posts.post_title
        END AS post_title,

    -- 投稿日時
    wp_posts.post_date,

    -- 更新日時
    wp_posts.post_modified,

    -- 公開 or 更新
    CASE
        WHEN DATE_FORMAT(wp_posts.post_date, '%Y-%m-%d') = DATE_FORMAT(wp_posts.post_modified, '%Y-%m-%d') THEN '公開'
        ELSE '更新'
        END AS status,

    -- 文字数
    CHAR_LENGTH(wp_posts.post_content) AS char_len,

    -- ページの種類
    wp_posts.post_type,

    -- 1つ上の親
    wp_parent_posts.ID AS parent_id1,
    wp_parent_posts.post_title AS parent_title1,

    -- 2つ上の親
    wp_parent_posts2.ID AS parent_id2,
    wp_parent_posts2.post_title AS parent_title2

FROM wp_posts

-- 1つ上の親
LEFT JOIN wp_posts wp_parent_posts
    ON  wp_parent_posts.ID = wp_posts.post_parent
    AND wp_parent_posts.post_status = 'publish'
    AND wp_parent_posts.post_type = 'page'

-- 2つ上の親
LEFT JOIN wp_posts wp_parent_posts2
    ON  wp_parent_posts2.ID = wp_parent_posts.post_parent
    AND wp_parent_posts2.post_status = 'publish'
    AND wp_parent_posts2.post_type = 'page'

WHERE
      -- ページの種類
      wp_posts.post_type IN ( 'post', 'page' )

      -- 公開状態
  AND wp_posts.post_status = 'publish'

      -- 本文が 500 文字以上
  AND CHAR_LENGTH(wp_posts.post_content) > 500

-- 表示する順 (更新日時の降順)
ORDER BY
    wp_posts.post_modified DESC

-- 取得する件数 (0件目から10件分)
LIMIT 0, 10

ざっくりとこんな感じです。

固定ページの先祖ページは2階層まで辿ってますが、3階層、4階層になった場合でも想像つくかと思います。

開発・技術入サポート

ということで宣伝です。

弊社では有償でWordpress案件も行っていますので、お気軽にお問い合わせください。
WordPressは2007年(バージョン2.2)頃から触り続けてきていることもあり得意中の得意です。

特にプログラム開発が必要になるようなカスタマイズは遠慮なくご相談ください。

デザイナーの方、広告業の方、ディレクター専門の方などお互いの得意分野を生かして長いお付き合いの出来る方を募集しています。

お気軽にお問い合わせください。