# 機能設計書 32-コードインジェクション

## 概要

本ドキュメントは、Ghostのコードインジェクション機能に関する設計仕様を定義する。この機能により、サイト管理者はカスタムHTML、CSS、JavaScriptコードをサイトのヘッダー（`<head>`タグ内）およびフッター（`</body>`タグ直前）に挿入できる。

### 本機能の処理概要

コードインジェクションは、サイト全体に適用するカスタムコードを管理する機能である。設定された内容はsettingsテーブルに保存され、テーマのレンダリング時に`{{ghost_head}}`および`{{ghost_foot}}`ヘルパーを通じて出力される。

**業務上の目的・背景**：サイト運営者がテーマファイルを直接編集することなく、Google Analytics、カスタムスタイル、外部ウィジェット、トラッキングスクリプトなどを追加できるようにする。これにより、テーマのアップデート時にカスタマイズが失われることを防ぎ、技術的な知識が限られたユーザーでも高度なカスタマイズが可能になる。

**機能の利用シーン**：
- Google Analytics/Tag Managerなどのトラッキングコードを設置したい場合
- カスタムCSSでサイトの外観を微調整したい場合
- サードパーティのウィジェット（チャットボット、ポップアップなど）を追加したい場合
- カスタムフォントの読み込みを追加したい場合
- OGPメタタグやStructured Dataを追加したい場合

**主要な処理内容**：
1. 管理画面からヘッダー/フッター用コードの入力・保存
2. settingsテーブルへの値の保存（codeinjection_head, codeinjection_foot）
3. テーマレンダリング時にテンプレートヘルパーを通じてコードを出力
4. 設定値のキャッシュ管理

**関連システム・外部連携**：
- テーマエンジン：`{{ghost_head}}`/`{{ghost_foot}}`ヘルパーでコードを出力
- settingsキャッシュ：設定値の高速参照

**権限による制御**：管理者（Administrator）以上のロールを持つスタッフユーザーのみが設定を編集できる。コードインジェクションはセキュリティリスクを伴うため、権限が制限されている。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 60 | コードインジェクション | 主画面 | カスタムHTML/CSS/JavaScriptの挿入設定 |

## 機能種別

設定管理 / コンテンツ挿入

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| codeinjection_head | String | No | ヘッダーに挿入するコード（`<head>`内） | 文字列型、長さ制限なし |
| codeinjection_foot | String | No | フッターに挿入するコード（`</body>`直前） | 文字列型、長さ制限なし |

### 入力データソース

- 管理画面（Ghost Admin > Settings > Code injection）からの入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| codeinjection_head | String | ヘッダー挿入用コード |
| codeinjection_foot | String | フッター挿入用コード |

### 出力先

- settingsテーブル（データベース）
- settingsキャッシュ
- フロントエンドHTML（`{{ghost_head}}`/`{{ghost_foot}}`経由）

## 処理フロー

### 処理シーケンス

```
1. 管理画面でのコード入力
   └─ テキストエリアにHTML/CSS/JavaScriptを入力

2. 保存処理
   └─ Settings API (edit) を呼び出し
   └─ settingsテーブルに保存
   └─ settingsキャッシュを更新
   └─ サイト全体のキャッシュを無効化

3. フロントエンド表示
   └─ テーマテンプレートで {{ghost_head}} / {{ghost_foot}} を呼び出し
   └─ settingsキャッシュから値を取得
   └─ HTMLとして出力
```

### フローチャート

```mermaid
flowchart TD
    A[管理画面でコード入力] --> B[保存ボタンクリック]
    B --> C[Settings API edit呼び出し]
    C --> D[settingsテーブルに保存]
    D --> E[settingsキャッシュ更新]
    E --> F[キャッシュ無効化ヘッダー設定]
    F --> G[保存完了]

    H[フロントエンドリクエスト] --> I[テーマテンプレートレンダリング]
    I --> J{ghost_head/ghost_foot呼び出し}
    J --> K[settingsキャッシュから取得]
    K --> L[HTMLとして出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-32-01 | 未設定時の出力 | 値が空文字の場合、何も出力しない | ghost_head/ghost_foot呼び出し時 |
| BR-32-02 | サニタイズなし | 入力されたコードはそのまま出力される（エスケープなし） | 全ての出力時 |
| BR-32-03 | サイト全体適用 | 設定されたコードはサイト全ページに適用される | フロントエンドレンダリング時 |
| BR-32-04 | 保存時キャッシュ無効化 | 設定変更時はサイト全体のキャッシュが無効化される | 設定保存時 |

### 計算ロジック

特になし（単純な文字列の保存・出力）

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定保存 | settings | UPDATE | codeinjection_head/footの値を更新 |
| 設定取得 | settings | SELECT | 設定値の取得（通常はキャッシュ経由） |

### テーブル別操作詳細

#### settings

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | value | ユーザー入力コード | key = 'codeinjection_head' または 'codeinjection_foot' |
| SELECT | value | key = 'codeinjection_head' / 'codeinjection_foot' | settingsキャッシュ経由 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | NoPermissionError | 権限のないユーザーが設定を変更しようとした | 管理者権限を持つユーザーでログインする |

### リトライ仕様

リトライは不要。権限エラーの場合は適切な権限を持つユーザーで再試行。

## トランザクション仕様

- 設定保存は単一レコードの更新のため、トランザクション制御は標準的なものを使用

## パフォーマンス要件

- 設定値はsettingsキャッシュに保存されるため、フロントエンドでのDBアクセスは不要
- 設定変更時のみキャッシュ更新処理が発生

## セキュリティ考慮事項

- **XSS対策注意**：コードはエスケープされずにそのまま出力されるため、信頼できる管理者のみがアクセス可能
- **権限制限**：Ownerおよび Administrator ロールのみが設定可能
- **悪意のあるコード**：第三者のコードを挿入する際はセキュリティリスクを考慮する必要がある

## 備考

- Ghost Adminの設定画面では、コードエディタ（シンタックスハイライト付き）が提供される
- 記事個別のコードインジェクションは記事モデルの`codeinjection_head`/`codeinjection_foot`フィールドで管理される（本機能とは別）
- デフォルト値は空文字

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、コードインジェクション設定のデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | default-settings.json | `ghost/core/core/server/data/schema/default-settings/default-settings.json` | **137-144行目**: codeinjection_head/footのデフォルト設定定義 |
| 1-2 | settings.js | `ghost/core/core/server/models/settings.js` | **98-163行目**: Settingsモデルの基本構造、emitChange/formatメソッド |

**読解のコツ**:
- default-settings.jsonの`site`カテゴリ内にcodeinjection設定が定義されている
- type: "string"で定義され、バリデーションは設定されていない

#### Step 2: API エンドポイントを理解する

設定の読み書きを行うAPIエンドポイントを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | settings.js | `ghost/core/core/server/api/endpoints/settings.js` | **24-148行目**: browse/read/editエンドポイント |

**主要処理フロー**:
1. **28-37行目**: `browse` - 設定一覧の取得
2. **124-147行目**: `edit` - 設定の更新、キャッシュ無効化ヘッダー設定

#### Step 3: テーマヘルパーを理解する

フロントエンドでコードを出力するヘルパーを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ghost_head.js | `ghost/core/core/frontend/helpers/ghost_head.js` | ghost_headヘルパーの実装、codeinjection_headの出力 |
| 3-2 | ghost_foot.js | `ghost/core/core/frontend/helpers/ghost_foot.js` | ghost_footヘルパーの実装、codeinjection_footの出力 |

#### Step 4: 設定キャッシュを理解する

設定値のキャッシュ機構を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | settings-cache | `ghost/core/core/shared/settings-cache/` | 設定キャッシュの実装 |

### プログラム呼び出し階層図

```
[管理画面]
    │
    ├─ Settings API (edit)
    │      ├─ settingsBREADService.edit()
    │      │      └─ Settings Model
    │      │             └─ settings table (UPDATE)
    │      └─ settingsCache.set()
    │             └─ キャッシュ更新
    │
    └─ X-Cache-Invalidate: /* ヘッダー設定

[フロントエンド]
    │
    ├─ テーマテンプレート
    │      ├─ {{ghost_head}}
    │      │      └─ settingsCache.get('codeinjection_head')
    │      │             └─ HTML出力
    │      │
    │      └─ {{ghost_foot}}
    │             └─ settingsCache.get('codeinjection_foot')
    │                    └─ HTML出力
```

### データフロー図

```
[入力]                    [処理]                           [出力]

管理画面入力 ───────▶ Settings API edit
                              │
                              ▼
                      settingsテーブル UPDATE
                              │
                              ▼
                      settingsキャッシュ更新
                              │
                              │
フロントエンドリクエスト ──▶ テーマレンダリング
                              │
                              ▼
                      ghost_head/ghost_foot
                              │
                              ▼
                      settingsキャッシュ参照 ───▶ HTML出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| default-settings.json | `ghost/core/core/server/data/schema/default-settings/default-settings.json` | 設定 | 設定のデフォルト値定義 |
| settings.js | `ghost/core/core/server/models/settings.js` | ソース | Settingsモデル |
| settings.js | `ghost/core/core/server/api/endpoints/settings.js` | ソース | Settings APIエンドポイント |
| settings-bread-service.js | `ghost/core/core/server/services/settings/settings-bread-service.js` | ソース | 設定のBREADサービス |
| settings-cache | `ghost/core/core/shared/settings-cache/` | ソース | 設定キャッシュ |
| ghost_head.js | `ghost/core/core/frontend/helpers/ghost_head.js` | ソース | ヘッダーコード出力ヘルパー |
| ghost_foot.js | `ghost/core/core/frontend/helpers/ghost_foot.js` | ソース | フッターコード出力ヘルパー |
