Concrete CMS 8.5.x|既存ページを404にして安全に公開予約する方法

2026/02/17
Concrete CMS 8.5.xで、既存ページを安全に公開予約したい方向けの技術解説。権限を変更せず、未来日時の間は404を返し、公開日時を過ぎると自動表示させる実践的な実装方法を紹介します。

■  権限をいじらずに「公開予約」を安全に実現する実践ノウハウ

Concrete CMS では、ページに「公開日時」を設定できますが、
新規作成時にしか未来日時を指定できず、既存ページでは「非公開に戻す」ことができない
という仕様上の制約があります。

そのため、通常は当該ページを権限付きにする措置をとりますが、一般ユーザーが閲覧すると、
ログイン画面にリダイレクトされてしまうという問題が発生します。

これはセキュリティ上も UX 上も望ましくありません。

  • ログイン画面が出ることで「この URL に何かある」と気づかれる
  • 未公開ページの存在が推測される
  • 公開予約の運用が複雑になる
  • 権限をいじると事故が起きやすい

本記事では、これらの問題を 権限を一切変更せずに解決する方法を紹介します。


■ Concrete CMS の「不条理」:既存ページは未来公開できない

Concrete CMS の標準仕様では:

  • 新規ページ作成時 → 公開日時を未来に設定できる
  • 既存ページ → 公開日時は「更新日時」扱いになり、未来日時を入れても非公開にならない

つまり、一度公開したページを「未来公開」に戻すことができません。

この仕様のため、未公開状態を作るには:

  • 閲覧権限を「管理者のみ」にする
  • しかしその状態で一般ユーザーがアクセスするとログイン画面が出る

という、運用上の不便が発生します。


■ 解決策:未来日時のページは「404」にする

そこで本記事では、
ページ属性に「公開予定日時」を作り、未来日時なら 404 を返す
という仕組みを追加します。

これにより:

  • 権限はゲストのまま
  • 未来日時の間は 404
  • 公開日時を過ぎた瞬間に自動で表示される
  • ログイン画面は出ない
  • ページの存在を隠せる(セキュリティ的に自然)

という、非常に美しい運用が実現します。


■ 必要な準備

1. ページ属性「公開予定日時」を作成

ハンドル例:

scheduled_publish_datetime

タイプ:日時

2. 404 ページ(/page_not_found)が一般公開されていることを確認

Concrete CMS 標準の 404 ページで問題ありません。


■ Concrete CMS の例外ハンドリング設定(重要)

Concrete CMS が 404 ページにフォールバックできるように、
以下の設定を /application/config/concrete.php に追加します。

<?php

return [
    'debug' => [
        'display_errors' => false,
        'log_errors' => true,
    ],
];

● なぜ必要なのか?

  • display_errors = true のままだと Symfony の例外画面が出てしまう
  • display_errors = false にすることで Concrete CMS が 404 ページに切り替える
  • log_errors = true にすると内部エラーがログに残る

この設定がないと、
NotFoundHttpException が 500 や「予期せぬエラー」に化けることがあります。


■ 実装コード

以下を /application/bootstrap/app.php の末尾に追加します。

use Concrete\Core\Page\Page;
use Concrete\Core\User\User;
use Concrete\Core\Support\Facade\Events;
use Concrete\Core\Routing\Redirect;

Events::addListener('on_start', function() {
    $page = Page::getCurrentPage();

    // 管理者は除外(編集できなくなるため)
    $u = new User();
    if ($u->isSuperUser()) {
        return;
    }

    // 公開予定日時属性を取得(DateTimeValue)
    $dt = $page->getAttribute('scheduled_publish_datetime');

    if ($dt) {
        $timestamp = $dt->getTimestamp();

        // 未来日時なら 404 ページへ内部リダイレクト
        if ($timestamp > time()) {
            Redirect::page(Page::getByPath('/page_not_found'))->send();
            exit;
        }
    }
});

● この方式のポイント

  • 例外を投げず、Concrete CMS の公式 API で 404 に内部リダイレクト
  • テーマやブロックの影響を受けない
  • 500 や「予期せぬエラー」にならない
  • 権限は触らないので安全

■ 動作確認

● 公開予定日時を未来に設定

→ 404(Page Not Found)が表示される
→ ログイン画面には飛ばない

● 公開予定日時を過去に設定

→ 通常通りページが表示される

● 公開日時を過ぎた瞬間に自動公開

→ cron も権限トグルも不要


■ この方法のメリットまとめ

メリット 内容
権限を触らない Concrete CMS の権限地雷を完全回避
404 で隠せる 未公開ページの存在を推測されない
公開予約がシンプル 公開日時を過ぎたら自動で表示
既存ページでも未来公開が可能 Concrete CMS の仕様の穴を補完
例外画面が出ない 404 ページに確実にフォールバック

■ まとめ

Concrete CMS の「既存ページは未来公開できない」「未公開ページはログイン画面に飛ぶ」という仕様は、
運用現場で大きなストレスになります。

本記事の方法を使えば:

  • 権限をいじらず
  • 未来日時は 404
  • 公開日時を過ぎたら自動公開

という、現場にとって理想的な運用が実現します。

Concrete CMS を使ったサイト運用で同じ課題に悩んでいる方は、
ぜひこの方法を取り入れてみてください。