# 画面設計書 2-カテゴリページ

## 概要

本ドキュメントは、Shopware 6 Storefrontにおけるカテゴリページの画面設計書である。カテゴリナビゲーションによる商品一覧表示やCMSコンテンツの表示を担う主要な画面である。

### 本画面の処理概要

カテゴリページは、商品をカテゴリ別に分類・表示するための画面である。CMSシステムと連携し、商品リスティングブロックを含む柔軟なレイアウトを提供する。

**業務上の目的・背景**：カテゴリページは商品を論理的にグループ化し、顧客が目的の商品を効率的に見つけられるようにするナビゲーションの要である。階層構造のカテゴリにより、大量の商品を体系的に整理し、ユーザビリティを向上させる。また、カテゴリごとにカスタマイズ可能なCMSレイアウトにより、マーケティング訴求も可能である。

**画面へのアクセス方法**：ヘッダーのナビゲーションメニューからカテゴリ名をクリック、パンくずリストからの選択、URLへの直接アクセス（例: `/navigation/{navigationId}`または SEO URL）でアクセスする。

**主要な操作・処理内容**：
1. カテゴリ情報とCMSページの読み込み（NavigationPageLoader）
2. 商品リスティングの表示（フィルター、ソート、ページネーション対応）
3. サブカテゴリへのナビゲーション
4. 商品カードからの商品詳細への遷移
5. オフキャンバスメニューの表示（モバイル対応）

**画面遷移**：
- 遷移元：ホームページ、他のカテゴリページ、検索結果ページ、商品詳細ページのパンくず
- 遷移先：子カテゴリページ、商品詳細ページ、カートページ（商品追加時）、検索結果ページ

**権限による表示制御**：基本的に全ユーザーがアクセス可能。リンクタイプのカテゴリは外部URLまたは内部ページへリダイレクトされる。非公開カテゴリは表示されない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 58 | カテゴリページ表示 | 主機能 | カテゴリナビゲーションと商品一覧の表示（NavigationController::index） |
| 59 | オフキャンバスメニュー | 補助機能 | モバイル用メニュー表示（NavigationController::offcanvas） |

## 画面種別

一覧 / CMS表示

## URL/ルーティング

| 項目 | 値 |
|------|-----|
| URL | `/navigation/{navigationId}` |
| SEO URL | カテゴリ設定に基づく（例: `/clothing/`） |
| ルート名 | `frontend.navigation.page` |
| HTTPメソッド | GET |
| HTTPキャッシュ | 有効 |

## 入出力項目

### 入力項目

| 項目名 | パラメータ名 | 必須 | 型 | 説明 |
|--------|-------------|------|-----|------|
| ナビゲーションID | navigationId | 必須 | string(UUID) | カテゴリのID |
| ソート順 | order | 任意 | string | 商品の並び順（例: name-asc, price-desc） |
| ページ番号 | p | 任意 | int | ページネーション用 |
| フィルター | properties, manufacturer, price など | 任意 | mixed | 商品フィルター条件 |

### 出力データ

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| page | NavigationPageLoader | ページ全体のデータオブジェクト |
| page.cmsPage | CMS設定 | CMSページレイアウト情報 |
| page.category | カテゴリテーブル | 現在のカテゴリ情報 |
| page.listing | ProductListingResult | 商品一覧データ（CMSブロック経由） |

## 表示項目

| セクション | 表示項目 | 説明 |
|-----------|---------|------|
| ヘッダー | 共通ヘッダー | ロゴ、ナビゲーション、検索、カート |
| コンテンツ | パンくずリスト | 現在のカテゴリ階層 |
| コンテンツ | CMSブロック | バナー、テキスト等のCMSコンテンツ |
| コンテンツ | フィルターパネル | 価格、メーカー、プロパティ等のフィルター |
| コンテンツ | ソート選択 | 並び順の選択ドロップダウン |
| コンテンツ | 商品一覧 | 商品カードのグリッド/リスト表示 |
| コンテンツ | ページネーション | ページ切り替えナビゲーション |
| フッター | 共通フッター | フッターリンク、ニュースレター |

## イベント仕様

### 1-カテゴリページ表示

カテゴリURLにアクセスすると、NavigationController::indexメソッドが実行される。

**処理フロー**：
1. NavigationPageLoaderがリクエストとSalesChannelContextを受け取る
2. navigationIdからカテゴリエンティティを取得
3. カテゴリタイプを判定：
   - TYPE_LINK: 外部/内部URLへリダイレクト
   - その他: CMSページを取得して表示
4. NavigationPageLoadedHookを発火
5. Twigテンプレートでレンダリング

### 2-リンクタイプカテゴリの処理

カテゴリタイプがTYPE_LINKの場合、設定されたURLへリダイレクトされる。

```
if ($category->getType() === CategoryDefinition::TYPE_LINK)
    -> RedirectResponse
```

### 3-オフキャンバスメニュー表示

モバイル表示時にハンバーガーメニューをタップすると、オフキャンバスメニューが表示される。

**エンドポイント**: `/widgets/menu/offcanvas`
**ルート名**: `frontend.menu.offcanvas`

### 4-フィルター/ソート操作

フィルターやソートを変更すると、AJAX経由で商品一覧が更新される。

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ表示 | category, cms_page, product | SELECT | データ参照のみ |

本画面は表示専用であり、データベースへの書き込み操作は発生しない。

## メッセージ仕様

| メッセージ種別 | 条件 | メッセージ内容 |
|--------------|------|--------------|
| - | - | 本画面固有のメッセージなし |

## 例外処理

| 例外条件 | 対応 |
|---------|------|
| カテゴリ未発見 | CategoryException::categoryNotFound発生、404エラー |
| リンクカテゴリでURL未設定 | CategoryException発生 |
| CMSページ未設定 | 空のコンテンツエリアが表示される |

## 備考

- カテゴリタイプによって表示が異なる（ページ、リンク、フォルダ）
- SEO URLはカテゴリ設定で個別に設定可能
- 商品リスティングはCMSの「商品リスティング」ブロックで表示される
- レスポンシブ対応により、モバイルではオフキャンバスメニューに切り替わる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | NavigationPage.php | `src/Storefront/Page/Navigation/NavigationPage.php` | ページオブジェクトの構造 |
| 1-2 | CategoryEntity.php | `src/Core/Content/Category/CategoryEntity.php` | カテゴリのtype属性（ページ/リンク/フォルダ）を確認 |
| 1-3 | CategoryDefinition.php | `src/Core/Content/Category/CategoryDefinition.php` | TYPE_PAGE, TYPE_LINK, TYPE_FOLDER定数 |

**読解のコツ**: CategoryEntityのgetType()メソッドの戻り値がカテゴリの振る舞いを決定する。TYPE_LINKの場合はリダイレクト処理が走る。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | NavigationController.php | `src/Storefront/Controller/NavigationController.php` | indexメソッド（72-93行目）がメイン処理 |

**主要処理フロー**:
1. **74行目**: NavigationPageLoaderを呼び出し
2. **76行目**: NavigationPageLoadedHookでフック処理
3. **78-79行目**: カテゴリオブジェクト取得
4. **81-90行目**: TYPE_LINKの場合のリダイレクト処理
5. **92行目**: 通常表示の場合はテンプレートをレンダリング

#### Step 3: リダイレクト処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AbstractCategoryUrlGenerator.php | `src/Core/Content/Category/Service/AbstractCategoryUrlGenerator.php` | カテゴリURLの生成ロジック |

**主要処理フロー**:
- **83-84行目**: CategoryUrlGeneratorでリダイレクト先URL生成
- **89行目**: SEO URLプレースホルダーを実際のURLに置換

#### Step 4: テンプレート構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.html.twig | `src/Storefront/Resources/views/storefront/page/content/index.html.twig` | ホームページと同じテンプレートを使用 |

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

```
NavigationController::index()
    |
    +-- NavigationPageLoader::load()
    |       |
    |       +-- CategoryRoute::load()
    |       |
    |       +-- CmsPageLoader::load()
    |               +-- ProductListingCmsElementResolver (商品一覧)
    |
    +-- [TYPE_LINK の場合]
    |       +-- CategoryUrlGenerator::generate()
    |       +-- SeoUrlPlaceholderHandler::replace()
    |       +-- RedirectResponse
    |
    +-- [通常表示の場合]
            +-- NavigationPageLoadedHook
            +-- renderStorefront()
                    +-- index.html.twig
```

### データフロー図

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

navigationId      -->  NavigationController
    |                       |
    v                       v
Request params        NavigationPageLoader
(sort, filter)              |
                           v
                      CategoryRoute
                           |
                     +-----+-----+
                     |           |
                TYPE_LINK    TYPE_PAGE
                     |           |
                     v           v
              RedirectResponse  CmsPageLoader
                                    |
                                    v
                              NavigationPage
                                    |
                                    v
                              HTML Response
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| NavigationController.php | `src/Storefront/Controller/NavigationController.php` | コントローラー | ルーティングエントリーポイント |
| NavigationPageLoader.php | `src/Storefront/Page/Navigation/NavigationPageLoader.php` | ページローダー | ページデータの構築 |
| CategoryDefinition.php | `src/Core/Content/Category/CategoryDefinition.php` | 定義 | カテゴリタイプ定数 |
| index.html.twig | `src/Storefront/Resources/views/storefront/page/content/index.html.twig` | テンプレート | メインテンプレート |
| navigation-pagelet.html.twig | `src/Storefront/Resources/views/storefront/layout/navigation/offcanvas/navigation-pagelet.html.twig` | テンプレート | オフキャンバスメニュー |
| listing.html.twig | `src/Storefront/Resources/views/storefront/component/product/listing.html.twig` | テンプレート | 商品一覧表示 |
| filter-panel.html.twig | `src/Storefront/Resources/views/storefront/component/listing/filter-panel.html.twig` | テンプレート | フィルターパネル |
