Appearance
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 で任意位置に配置 |
| 特定機種結果の実装形態 | オプション meta | paid_article_section_smr_{instance_id}。旧固定 #7 からオプション化(#2553)。sections_order で任意位置 |
| セクション表示順 | _paid_article_sections_order + ドラッグ UI | 固定 7 本とオプションを混在して並べ替え(#2547) |
カスタム投稿タイプ仕様
基本設定
| 項目 | 値 |
|---|---|
| 投稿タイプ slug | paid_article |
| 表示名 | 有料記事 |
show_in_rest | true(WordPress MCP / REST API 必須) |
supports | title, 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_intro | string (HTML) | 手動 | — | 号数・今後予定・今号概要。WYSIWYG またはプレーンテキスト |
| 2 | 初週のデータ比較 | paid_article_new_machine_first_week | string (JSON) | 手動 + 自動 | SC-009 + SC-010(対応表) | 導入初日は SC-009 複数機種。初週サマリーは SC-010 × 機種数。考察は comment_before(グラフ前)と comment_after(グラフ後) |
| 3 | 来月の導入台と期待感 | paid_article_next_machine_comment | string (JSON) | 手動 + 自動 | db_new_machine_info(対象月の翌月 release_date) | 新台一覧は自動テーブル表示。期待感コメントは html で任意入力 |
| 4 | 月差枚数 | paid_article_month_diff | string (JSON) | 手動 + 自動 | SC-010 | 対象年月・ホール・機種。期間は月次で自動算出可 |
| 5 | 機種差枚数ランキング | paid_article_ranking | string (JSON) | 手動 + 自動 | SC-016(default_* 属性) | 対象期間・ホール。フォーム UI 残存は G-1 参照 |
| 6 | 増台・減台の結果 | paid_article_machine_count | string (JSON) | 手動 + 自動 | SC-015 + SC-010 | 台数変化一覧のあと、変化機種ごとの差枚結果を表示(下記「#6 表示構成」) |
| 7 | 新台出玉推移 | paid_article_new_machine_trend | string (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_master(is_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 | 必須フィールド | 説明 |
|---|---|---|
fixed | key(intro 等、meta_key 接尾辞) | 固定 7 セクション。各 key は 1 回のみ |
optional | section_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 要件
- CPT 登録:
register_post_type( 'paid_article', [ 'show_in_rest' => true, ... ] ) - 固定セクションメタ: 固定 7 本の
meta_keyをregister_post_metaでshow_in_rest: true登録(RestMetaRegistration.php を参考) - オプションセクション: 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_callbackはcurrent_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 README、DailyArticlePostType README
関連 Issue と引き継ぎ範囲
| Issue | 本設計からの引き継ぎ |
|---|---|
| #2387 | CPT 登録、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_key(
paid_article_intro等 7 本)を変更しない- 理由: 公開後の過去号メタ・MCP スクリプトがキー名に依存するため
- オプションセクション meta 接頭辞(
paid_article_section_vs_,paid_article_section_smr_)を変更しない- 理由: インスタンスごとの永続化キーとしてテンプレート・管理画面が依存するため
- 実装開始前に meta_key を確定し、変更時はマイグレーション Issue を別途起票する