Skip to content

CPT-002 有料記事テンプレート構成設計

概要

  • 月 1 回更新の有料記事向けに、固定セクション(データ連携中心)オプションセクション(可変・特定機種結果) を組み合わせたテンプレート構成を定義する。
  • カスタム投稿タイプ paid_article を新設し、日別記事(daily_article)の CPT + メタボックス + Twig テンプレート パターンを流用する。
  • 固定セクションは post_meta で入力し、フロント表示時に既存ショートコードを動的生成する(日別記事の DailyArticleTemplate と同様の「メタ → ショートコード」方式)。
  • 可変セクション・特定機種結果は オプションセクション として post_meta(インスタンスごと)に格納し、_paid_article_sections_order で固定セクションと混在して並べ替え可能とする。
  • WordPress MCP(WP REST API 経由)で AI エージェントが記事骨子を下書きできるよう、CPT と固定セクション 8 本のメタを show_in_rest: true で公開する。

関連 Issue

Issue内容
#2381親 Issue(有料記事の体制を整える)
#2383本設計(テンプレート構成)
#2385固定セクションと既存データ機能の対応整理(対応表
#2387実装: 基盤(投稿タイプ・テンプレート・管理画面)
#2388実装: 月次固定セクションのテンプレート実装
#2389実装: 都度更新セクションの編集 UI

テンプレート方式の選定

観点採用方針理由
投稿タイプ新規 CPT paid_article通常投稿との混在を避け、有料エリア専用のテンプレート・権限・URL を独立管理できる
日別記事パターンの流用流用するDailyArticlePostType の CPT 登録・メタボックス・Twig テンプレート・single_template フックの構成が実績あり
固定セクションの実装形態post_meta + Twig テンプレート(ショートコード動的生成)月次更新の定型化・データ連携の一元化。過去号の表示安定化は #2386(画像スナップショット)で補完
可変セクションの実装形態オプション meta + 埋め込みブロックエディタpaid_article_section_vs_{instance_id}title / content を JSON 保存。複数インスタンス追加・sections_order で任意位置に配置
特定機種結果の実装形態オプション metapaid_article_section_smr_{instance_id}。旧固定 #7 からオプション化(#2553)。sections_order で任意位置
セクション表示順_paid_article_sections_order + ドラッグ UI固定 7 本とオプションを混在して並べ替え(#2547)

カスタム投稿タイプ仕様

基本設定

項目
投稿タイプ slugpaid_article
表示名有料記事
show_in_resttrue(WordPress MCP / REST API 必須)
supportstitle, editor, thumbnail, custom-fields, revisions(管理画面では editor を非表示にし、本文はオプション meta で編集)
公開public: true(編集権限者・購入済みユーザーは全文。一般訪問者はリード + 購入/ログイン CTA)
リライトpaid-article(詳細は #2387 で確定)

投稿データの管理方式

データ種別格納先編集 UI
タイトル(号数・タイトル)post_title基本情報メタボックス(自動生成)
固定セクション(7 本)post_meta(下表参照)専用メタボックス
オプションセクションpost_meta(インスタンスごと、下記「オプションセクション仕様」)専用メタボックス
セクション表示順_paid_article_sections_orderセクション管理メタボックス
アイキャッチ_thumbnail_id標準アイキャッチ

固定セクション仕様

固定セクションは 号ごとにほぼ同じ見出し・構成 で、データ連携が中心。入力方式を 自動(ショートコード生成)/手動(テキスト)/条件付き(空なら非表示) に分類する。

#見出しmeta_key入力方式連携先(既存資産)備考
1冒頭挨拶paid_article_introstring (HTML)手動号数・今後予定・今号概要。WYSIWYG またはプレーンテキスト
2初週のデータ比較paid_article_new_machine_first_weekstring (JSON)手動 + 自動SC-009 + SC-010対応表導入初日は SC-009 複数機種。初週サマリーは SC-010 × 機種数。考察は comment_before(グラフ前)と comment_after(グラフ後)
3来月の導入台と期待感paid_article_next_machine_commentstring (JSON)手動 + 自動db_new_machine_info(対象月の翌月 release_date新台一覧は自動テーブル表示。期待感コメントは html で任意入力
4月差枚数paid_article_month_diffstring (JSON)手動 + 自動SC-010対象年月・ホール・機種。期間は月次で自動算出可
5機種差枚数ランキングpaid_article_rankingstring (JSON)手動 + 自動SC-016default_* 属性)対象期間・ホール。フォーム UI 残存は G-1 参照
6増台・減台の結果paid_article_machine_countstring (JSON)手動 + 自動SC-015 + SC-010台数変化一覧のあと、変化機種ごとの差枚結果を表示(下記「#6 表示構成」)
7新台出玉推移paid_article_new_machine_trendstring (JSON)手動 + 自動period_kishu_samai_ranking_snapshot display="graph"対応表対象期間・機種(kishu カンマ区切り)

JSON 型メタの共通スキーマ(たたき台)

実装時(#2388)に DTO・バリデーションを定義する。設計段階では以下の共通構造を想定する。

json
{
  "period_start": "20260101",
  "period_end": "20260131",
  "hall": "アイランド秋葉原",
  "kishu_list": [101, 202],
  "enabled": true
}
  • 新規投稿では各固定セクションの enabled 既定値は true(管理画面の「このセクションを表示する」チェック ON)。enabled: false を明示保存した場合、または必須フィールド欠落時は、当該セクションをフロントで非表示とする。
  • ホール選択肢は db_paid_article_hall_masteris_show = 1)から取得する。初期データはアイランド・エスパスのみ表示。
  • 新規投稿の JSON 既定値: 可視ホールはすべて選択済み(halls)。#2 は候補機種をすべて kishu_list に含める。
  • 日付形式は既存ショートコードに合わせ YYYYMMDD を基本とし、変換は Converter 層で行う。

#2 初週のデータ比較 は上記共通に加え、comment_before / comment_after(HTML 可)で前半・後半考察を分離する(詳細は固定セクション-ショートコード対応表)。

#3 来月の導入台と期待感 の meta は {"enabled": bool, "html": string}(期待感コメントのみ html に格納)。新台一覧は db_new_machine_info から自動生成し、機種名(machine_name)で重複排除する(同名レコードは最も早い導入日を採用)。

#6 増台・減台の結果(表示構成)

#2381 メモの「増減台」は 台数の変化その機種の結果(差枚) の両方を読者に示すセクション。SC-015 単体では前日比のみのため、変化機種ごとに SC-010 を併記する。

ブロック連携先内容
台数変化一覧SC-015対象期間・全選択ホールを layout=merged で 1 テーブル表示(日付・機種名・ホールアイコン列)
機種別結果SC-010 × N上記で検出した機種(または kishu_list 指定)ごとに、変化日以降〜period_end の差枚サマリー
  • 台数変化テーブル: halls で選択したホールをカンマ区切りで SC-015 に渡す。同一ホール・同一機種の複数日変化は 1 行に統合(改行表示)。変化ホールが複数の場合は日付ごとに行を分ける。列ヘッダーは HallEnum アイコン、表下にアイコンとホール名の注釈。折りたたみなし。

  • 機種の抽出: 既定は SC-015 の表示行から機種名を重複排除して取得。手動で絞り込む場合は JSON の kishu_list を使用する。

  • 結果の集計期間: 各機種の変化日(SC-015 の period_key)を result_period_start とし、period_end までを SC-010 に渡す。変化日が複数ある機種は 最も古い変化日 を起点とする。

  • 0 件時: SC-015 が 0 件ならセクション全体を非表示(enabled: false と同義)。

paid_article_machine_count の JSON 例:

json
{
  "period_start": "20260101",
  "period_end": "20260131",
  "hall": "アイランド秋葉原",
  "kishu_list": [],
  "enabled": true
}
  • kishu_list が空配列のときは SC-015 から機種を自動抽出。非空のときは列挙機種のみ SC-010 を出力する。

セクション表示順

フロント表示順は _paid_article_sections_order(JSON 配列)で管理する。管理画面の「セクション管理」メタボックスでドラッグ並べ替え・オプションセクションの追加・削除ができる(#2547)。

sections_order エントリ形式

type必須フィールド説明
fixedkeyintro 等、meta_key 接尾辞)固定 7 セクション。各 key は 1 回のみ
optionalsection_type, instance_idオプションセクション(複数インスタンス可)

固定 8 セクションの key 一覧: intro, new_machine_first_week, next_machine_comment, month_diff, ranking, machine_count, new_machine_trend, hall_samai_ranking

既定表示順

sections_order 未保存の新規投稿は、固定 7 セクションを上表の番号順(#1〜#7)で並べた配列を既定とする。オプションセクションは追加時に任意位置へ挿入する。

json
[
  { "type": "fixed", "key": "intro" },
  { "type": "fixed", "key": "new_machine_first_week" },
  { "type": "optional", "section_type": "variable_section", "instance_id": "vs_abc123" },
  { "type": "fixed", "key": "next_machine_comment" },
  { "type": "optional", "section_type": "specific_machine_results", "instance_id": "smr_def456" },
  { "type": "fixed", "key": "month_diff" }
]

オプションセクション仕様

固定 7 本に加え、号ごとに任意個数追加できるセクション。いずれも sections_order に登録されたインスタンスのみフロント表示する。

種別一覧

section_type用途meta キー接頭辞instance_id 接頭辞
variable_section可変(考察・特集)paid_article_section_vs_vs_
specific_machine_results特定機種結果paid_article_section_smr_smr_

可変セクション(variable_section

項目仕様
meta キーpaid_article_section_vs_{instance_id}
JSON スキーマ{"title": string, "content": string}
title公開画面 h2 表題(任意。空のときは見出し非表示)
contentブロックエディタ HTML(見出し・本文・画像・ショートコード等)
編集 UI専用メタボックス内の埋め込みブロックエディタ(日別記事と同系統)
複数インスタンス可。号ごとに複数の考察・特集ブロックを追加可能

想定コンテンツ例: 特定機種の導入結果、中古機価格からみる市場評価、旧メイン機種の扱い、狙い方考察 等。

JSON 例:

json
{
  "title": "今月の特集",
  "content": "<!-- wp:heading --><h2>乙女5 導入結果</h2><!-- /wp:heading --><!-- wp:paragraph --><p>考察本文...</p><!-- /wp:paragraph -->"
}

特定機種結果(specific_machine_results

旧固定 #7 をオプション化したセクション(#2553)。データ連携中心で、公開表題・機種選択・期間をインスタンスごとに設定する。

ブロック連携先内容
公開表題section_title(必須)フロント h2 に表示。新規投稿は既定値「特定機種結果」を付与。欠損時は空のまま表示
導入初日データSC-009 kishudata選択機種の導入初日(intro_day)の台別データカード
期間差枚サマリーSC-010 period_samai_summary × 機種数各機種の期間合計・平均差枚
累計差枚数グラフperiod_kishu_samai_ranking_snapshot display="graph" intro_day全選択機種を1グラフに重ね表示(相対日軸の累計折れ線)
  • meta キー: paid_article_section_smr_{instance_id}
  • 表示: 新規投稿では enabled 既定 true
  • 機種選択(管理画面): 直近4か月の導入台(db_new_machine_info・紐付け済み)をチェックボックスで選択。それ以外は機種マスタ(db_kishu_master・有効のみ)を 検索可能プルダウン(1行1機種・「+ 追加」で行を増やす) で選択(日別記事のデータ検索 UI と共通の Choices.js コンポーネントを流用)。
  • 機種の複数選択: kishu_list に機種マスタ ID 配列を保存。グラフはカンマ区切り機種名で1ショートコードにまとめる。
  • 0 件時: ホール未選択・機種未選択・enabled: false のいずれかでセクション非表示。

JSON 例:

json
{
  "section_title": "特定機種結果",
  "period_start": "20260101",
  "period_end": "20260131",
  "halls": ["island"],
  "kishu_list": [101, 202],
  "enabled": true,
  "comment": "<p>考察・コメント</p>"
}
  • section_title は公開画面 h2 の表題(必須)。管理画面保存時に空は不可。

可変セクション仕様(廃止)

post_content(Gutenberg 本文)を可変セクションの正本とする方式は #2545 以降廃止 した。考察・特集は上記「オプションセクション仕様」の variable_section を使用する。CPT 登録時の editor サポートは REST 互換のため残すが、管理画面では非表示とし、標準本文エディタ経由の編集は行わない。

フロント表示・URL

項目方針
単体表示テンプレートmyTemplate/single-paid-article-template.php(ラッパー)+ core_src 内 Twig 本体(DailyArticle と同パターン)
一覧ページ月 1 配信のため本設計の対象外
有料エリアのプレビュー編集権限者・購入済みユーザーは WP で全文プレビュー。一般訪問者は intro セクション(リード)+ 購入/ログイン CTA
パーマリンク/paid-article/{year}-{issue}/ 形式

WordPress MCP 対応設計

目的

AI エージェント(Cursor 等)が WordPress MCP 経由で有料記事の下書きを作成・更新し、人間が管理画面で確認・公開するワークフローを成立させる。

REST API 要件

  1. CPT 登録: register_post_type( 'paid_article', [ 'show_in_rest' => true, ... ] )
  2. 固定セクションメタ: 固定 7 本の meta_keyregister_post_metashow_in_rest: true 登録(RestMetaRegistration.php を参考)
  3. オプションセクション: MCP 経由での更新は固定 7 本 + 基本メタを対象とし、オプションセクションの追加・並べ替えは管理画面で行う

エンドポイント

操作メソッドパス
一覧取得GET/wp-json/wp/v2/paid_article
単体取得GET/wp-json/wp/v2/paid_article/{id}
新規作成POST/wp-json/wp/v2/paid_article
更新POST/PUT/wp-json/wp/v2/paid_article/{id}

リクエスト例(下書き作成)

json
{
  "title": "有料記事 第3号(2026年2月号)",
  "status": "draft",
  "meta": {
    "paid_article_intro": "今号は〇〇を中心に解説します。",
    "paid_article_month_diff": "{\"period_start\":\"20260201\",\"period_end\":\"20260228\",\"hall\":\"アイランド秋葉原\",\"enabled\":true}"
  }
}

可変セクション・特定機種結果は管理画面の「セクション管理」からインスタンスを追加し、各オプションメタボックスで編集する(REST 経由の一括下書きは固定セクション中心)。

MCP ワークフロー(月次更新)

認証・権限

  • REST API 書き込みには Application Password または OAuth 等、WordPress 標準の認証が必要。
  • auth_callbackcurrent_user_can( 'edit_post', $post_id ) を返す(DailyArticle と同様)。
  • MCP 用サービスアカウントは editor 以上の権限を付与する。

管理画面 UI

UI 要素担当 Issue概要
基本情報メタボックス#2387号数・対象年月・プレビュー URL 案内
固定セクションメタボックス#2388固定 7 セクション分の入力フォーム
セクション管理#2547全セクションの一覧・ドラッグ並べ替え・オプション追加・削除
オプションセクションメタボックス#2545 / #2553可変セクション・特定機種結果のインスタンスごと入力フォーム
プレビュー#2599編集者・購入済み: WP 全文。一般: リード + CTA

日別記事テンプレートとの差分表

観点DailyArticle (daily_article)PaidArticle (paid_article)
更新頻度毎日月 1 回
固定セクションホール別考察 6 件 + 絵文字 3 件データ連携中心 7 本(固定)+ オプション(可変・特定機種結果)
可変セクションmanual_content(テンプレート関数引数)オプション meta paid_article_section_vs_*(埋め込みブロックエディタ)
セクション表示順テンプレート固定_paid_article_sections_order + ドラッグ UI
テンプレート生成generate_daily_article_template()generate_paid_article_template()(新規、#2388)
REST API メタ3 件のみ(kousatsu_date, halls, daily_article_events全固定セクション show_in_rest: true
WordPress MCP対象外設計に組み込み
DB 同期db_Link_day 等へ同期初版は不要(対応表 で確定)
自動作成 Cronあり(DailyArticleAutoCreateRunner初版は不要(手動 + MCP で十分)
画像スナップショットなし方針 #2386(過去号の表示安定化)

参考: DailyArticleTemplate READMEDailyArticlePostType README

関連 Issue と引き継ぎ範囲

Issue本設計からの引き継ぎ
#2387CPT 登録、show_in_rest、ラッパーテンプレート、RestMetaRegistration 相当
#2388固定 7 セクションのメタボックス UI、PaidArticleTemplate + Twig、ショートコード動的生成(#6 は SC-015 → SC-010 連鎖)
#2545可変セクションのオプション meta 化、複数インスタンス対応
#2547セクション表示順(_paid_article_sections_order)とドラッグ UI
#2553特定機種結果のオプションセクション化
#2390決済完了後の購入記録 INSERT、Stripe Checkout / Webhook 連携
#2386画像スナップショット方針
#2391固定セクション出力の画像スナップショット保存(方針は #2386)

更新不可とみなすもの

  • 投稿タイプ slug paid_article を変更しない
    • 理由: REST エンドポイント・パーマリンク・MCP 設定が依存するため
  • 固定セクション meta_keypaid_article_intro 等 7 本)を変更しない
    • 理由: 公開後の過去号メタ・MCP スクリプトがキー名に依存するため
  • オプションセクション meta 接頭辞paid_article_section_vs_, paid_article_section_smr_)を変更しない
    • 理由: インスタンスごとの永続化キーとしてテンプレート・管理画面が依存するため
  • 実装開始前に meta_key を確定し、変更時はマイグレーション Issue を別途起票する