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 と固定セクション 9 本のメタを show_in_rest: true で公開する。
  • AI 考察生成が使うデータ取得ツールの契約は 有料記事 AI データ取得ツール を参照する。

テンプレート方式の選定 ​

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

カスタム投稿タイプ仕様 ​

基本設定 ​

項目値
投稿タイプ slugpaid_article
表示名有料記事
show_in_resttrue(WordPress MCP / REST API 必須)
権限capability_type: [ 'paid_article', 'paid_articles' ] + map_meta_cap: true(edit_paid_articles 等の専用 Capability。通常投稿の edit_posts では編集できない)
supportstitle, editor, thumbnail, custom-fields, revisions, comments(管理画面では editor を非表示にし、本文はオプション meta で編集。新規は comment_status: open)
公開public: true(編集権限者・購入済みユーザーは全文。一般訪問者はリード + 購入/ログイン CTA)
リライトpaid-article

投稿データの管理方式 ​

データ種別格納先編集 UI
タイトル(号数・タイトル)post_title基本情報メタボックス(自動生成)
広告表示paid_article_show_ads('1' / 空)基本情報メタボックス。既定は非表示。Cocoon 広告枠と [random_adsense_ad] に効く
固定セクション(9 本)post_meta(下表参照)専用メタボックス
オプションセクションpost_meta(インスタンスごと、下記「オプションセクション仕様」)専用メタボックス
セクション表示順_paid_article_sections_orderセクション管理メタボックス
アイキャッチ_thumbnail_id標準アイキャッチ(未設定時は PAID_ARTICLE_DEFAULT_THUMBNAIL_ID を自動設定)

固定セクション仕様 ​

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

#見出しmeta_key型入力方式連携先(既存資産)備考
1冒頭挨拶paid_article_introstring (HTML)手動—号数・今後予定・今号概要に加え、今号のオプション(可変・特定機種結果など固定以外)で扱う内容の紹介。WYSIWYG またはプレーンテキスト
2月差枚数paid_article_month_diffstring (JSON)手動 + 自動SC-010対象年月・ホール・機種。期間は月次で自動算出可
3初週のデータ比較paid_article_new_machine_first_weekstring (JSON)手動 + 自動SC-009 + SC-010(対応表)導入初日は SC-009 複数機種。初週サマリーは SC-010 × 機種数。考察は comment_before(グラフ前)と comment_after(グラフ後)
4来月の導入台と期待感paid_article_next_machine_commentstring (JSON)手動 + 自動db_new_machine_info(対象月の翌月 release_date)新台一覧は自動テーブル表示。期待感コメントは html で任意入力
5機種差枚数ランキングpaid_article_rankingstring (JSON)手動 + 自動SC-016(default_* 属性)対象期間・ホール。フォーム UI 残存は G-1 参照
6増台・減台の結果paid_article_machine_countstring (JSON)手動 + 自動SC-015 + SC-023台数変化一覧のあと、変化機種ごとの増台前後差枚比較を表示(下記「#6 表示構成」)
7新台出玉推移paid_article_new_machine_trendstring (JSON)手動 + 自動period_kishu_samai_ranking_snapshot display="graph"(対応表)対象期間・機種(kishu カンマ区切り)
8ホール差枚数ランキングpaid_article_hall_samai_rankingstring (JSON)手動 + 自動SC-019 hall_samai_ranking(対応表)対象月・ホール。合算ランキングは 2 ホール以上で表示
9イベント別成績paid_article_event_samai_summarystring (JSON)手動 + 自動SC-020 event_samai_summary(対応表)ホールごと event=all。ピックアップ=対象月、累計=直近 6 暦月

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

実装時に 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)。#3 は候補機種をすべて kishu_list に含める。
  • 日付形式は既存ショートコードに合わせ YYYYMMDD を基本とし、変換は Converter 層で行う。

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

#4 来月の導入台と期待感 の meta は {"enabled": bool, "html": string}(期待感コメントのみ html に格納)。新台一覧は db_new_machine_info から自動生成する。紐付け済みは機種マスタ表示名、未紐付けは machine_name を表示する。重複排除キーは kishu_id 優先(未紐付けは machine_name)、同一キーは最も早い導入日を採用する。

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

「増減台」は 台数の変化 と その機種の結果(差枚) の両方を読者に示すセクション。SC-015 単体では前日比のみのため、変化機種ごとに SC-023(対象期間全体/増台前/増台後)を併記する。

ブロック連携先内容
台数変化一覧SC-015対象期間・全選択ホールを layout=merged で 1 テーブル表示(日付・機種名・ホールアイコン列)
機種別結果SC-023 × N上記で検出した機種(または kishu_list 指定)ごとに、月間/増台前/増台後の累計・平均差枚を1表表示
  • 台数変化テーブル: halls で選択したホールをカンマ区切りで SC-015 に渡す。同一ホール・同一機種の複数日変化は 1 行に統合(改行表示)。変化ホールが複数の場合は日付ごとに行を分ける。列ヘッダーは HallEnum アイコン、表下にアイコンとホール名の注釈。折りたたみ時は増台行のみ表示し、減台があるとき「すべて表示」で全件モーダル。台数セルは増台/減台で背景色を分ける。

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

  • 変化日(change_date): JSON の result_period_start(未入力時は対象月 period_start)を渡す。SC-015 の機種ごと最古 period_key の自動解決は将来拡張とする。

  • 集計期間: 対象月の period_start〜period_end を SC-023 に渡し、行内で全体/増台前/増台後に分割する。

  • 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-023 を出力する。

セクション表示順 ​

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

sections_order エントリ形式 ​

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

固定 9 セクションの key 一覧(既定順): intro, month_diff, new_machine_first_week, next_machine_comment, ranking, machine_count, new_machine_trend, hall_samai_ranking, event_samai_summary

既定表示順 ​

sections_order 未保存の新規投稿は、固定 9 セクションを上表の番号順(#1〜#9)で並べた配列を既定とする(PaidArticleMetaKeys::fixed_section_labels() と同順。冒頭挨拶の直後が月差枚数)。オプションセクションは追加時に任意位置へ挿入する。既存投稿の保存済み sections_order は維持し、#9 はセクション管理から追加・並べ替え可能とする。

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

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

固定 9 本に加え、号ごとに任意個数追加できるセクション。いずれも 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 をオプション化したセクション。データ連携中心で、公開表題・機種選択・期間をインスタンスごとに設定する。

ブロック連携先内容
公開表題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 本文)を可変セクションの正本とする方式は 廃止 した。考察・特集は上記「オプションセクション仕様」の variable_section を使用する。CPT 登録時の editor サポートは REST 互換のため残すが、管理画面では非表示とし、標準本文エディタ経由の編集は行わない。

フロント表示・URL ​

項目方針
単体表示テンプレートmyTemplate/single-paid-article-template.php(ラッパー)+ core_src 内 Twig 本体(DailyArticle と同パターン)
一覧ページ月 1 配信のため本設計の対象外
有料エリアのプレビュー編集権限者は WP で全文プレビュー。編集画面から paid_article_preview=visitor 付き URL で一般訪問者相当(intro + codoc 境界)も確認可
パーマリンク/paid-article/{year}-{issue}/ 形式

WordPress MCP 対応設計 ​

目的 ​

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

経路の区別 ​

経路役割
CPT REST(show_in_rest)固定セクション meta の読み書き口。汎用 WordPress MCP や REST クライアントが利用可能
Cursor paid-article-tools差枚等のデータ取得 + 既存 draft への固定セクション書き戻し(update_paid_article_draft)。接続先はローカル WP 前提
考察の持ち運び(管理画面)ローカル↔本番の考察移し。Markdown コピー/ダウンロード/貼り付け/アップロード(EP-024 / EP-025)。MCP・本番 REST 直結は使わない
週次更新スクリプト公開済み記事の固定セクション meta だけを REST で更新(create-paid-article-draft.mjs --allow-published。有料記事編集bot で接続)
汎用 WordPress MCP サーバー本リポジトリでは必須導入としない。REST 口があれば同等操作が可能
オプションセクション管理画面で追加・並べ替え(REST / MCP 一括作成の対象外)

REST API 要件 ​

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

エンドポイント ​

操作メソッドパス
一覧取得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 以上、または daily_article_editor_bot(日別記事編集bot。日別記事・有料記事の編集・公開のみ。削除不可)を付与する。
  • daily_article_editor_bot には unfiltered_html を付与しない。bot が保存する HTML は WordPress の KSES で許可タグに制限される(iframe 等の埋め込みは editor 以上で保存する)。

有料記事編集bot(週次更新) ​

公開済み記事の固定セクションを週次で更新する bot には、専用ロール paid_article_editor_bot(有料記事編集bot)を付与する(Issue #3932)。手順は 有料記事 会話執筆 + WP 下書き投稿 を参照。

項目内容
有料記事 Capabilityedit_paid_articles / edit_others_paid_articles / edit_published_paid_articles(PaidArticleCapabilityConstants::PAID_BOT_CAPS)。publish・削除・unfiltered_html なし
REST で書き込めるルートPOST /wp/v2/paid_article と POST /wp/v2/paid_article/{id} だけ(BotWriteGuardHooks)。プロフィール編集・アプリケーションパスワードの自己発行・XML-RPC・wp-admin は使えない
公開済み記事への更新下書き・承認待ち以外の記事には meta(と id / context / _ 始まりの共通パラメータ)だけ送れる。status・title・content・slug 等や、meta 内の号数・対象月(パーマリンク解決に使う)を含むと 403(paid_article_bot_published_meta_only。PaidArticleBotPublishedMetaOnlyHooks)
対象 metaRestMetaRegistration で登録済みの固定セクション 9 本。可変セクションと sections_order は REST 未登録のため対象外
本文・codoc への反映REST 更新では save_post が meta 保存より先に走るため、meta を含む REST 更新の後に PaidArticleCodocSyncHooks が投稿を保存し直し、新しい meta で codoc 同期用本文を組み直して codoc へ同期する

管理画面 UI ​

UI 要素概要
基本情報メタボックス号数・対象年月・販売価格・無料配信・広告表示・プレビュー URL 案内。広告は既定オフ(paid_article_show_ads)。無料配信とは独立
固定セクションメタボックス固定 9 セクション分の入力フォーム
セクション管理全セクションの一覧・ドラッグ並べ替え・オプション追加・削除
オプションセクションメタボックス可変セクション・特定機種結果のインスタンスごと入力フォーム
プレビュー編集者: WP 全文。編集画面から一般訪問者相当プレビュー可。一般: intro + codoc 境界
AI 文章生成各考察欄直下に欄ごとボタン(EP-021)。基本情報の直下(本文下メタボックス先頭)に全考察一括生成(EP-022)。どちらもエディタへ下書きを入れるだけで post meta へは自動保存しない
考察の持ち運び編集画面メタボックス。考察 Markdown のコピー/ダウンロード(EP-024)と、貼り付け/アップロードによる draft へのマージ保存(EP-025)。グラフ用データ meta は上書きしない。公開ステータスは変更しない

編集画面の AI 考察生成 ​

  • 未保存(auto-draft)または対象月未設定ではボタンを出さず案内する。
  • 欄ごと生成は対象欄の下書きだけをプロンプトに入れる。同一号の他欄・過去号はツール(有料記事 AI データ取得ツール)で参照する。
  • 一括生成は画面上の全考察欄(固定セクションとオプションセクション)を 1 回の LLM 呼び出しで書き、調子の一貫と重複回避を指示する。既存本文の上書きは確認ダイアログの対象。生成中は欄ごと・一括ボタンを同時に押せない。返った欄が足りないときは部分成功の案内を出す。経過秒数上限は 150 秒(1 回の LLM HTTP 上限 90 秒、次 HTTP は残り予算、PHP 実行上限 270 秒)。出力トークンは欄数に応じて最大 32768。途中切れは失敗とする。

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

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

参考: DailyArticleTemplate README、DailyArticlePostType README

更新不可とみなすもの ​

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