# 画面設計書 14-タグ別記事一覧画面

## 概要

本ドキュメントは、Legacy CMSのタグ別記事一覧画面の設計を記載する。

### 本画面の処理概要

タグ別記事一覧画面は、特定のタグが付けられた記事を一覧形式で表示する画面である。サイト訪問者は、この画面を通じて関連するトピックの記事をまとめて閲覧することができる。

**業務上の目的・背景**：
タグはカテゴリとは異なり、記事の横断的な分類を可能にする。複数のカテゴリに跨るトピック（例：「JavaScript」というタグが「技術」カテゴリと「チュートリアル」カテゴリの両方の記事に付く）を効率的に探せるようにすることで、コンテンツの発見性を高める。本画面はタグベースのナビゲーションを提供し、関連コンテンツへのアクセスを容易にする。

**画面へのアクセス方法**：
- 記事詳細画面からタグリンクをクリック
- 記事タグ一覧画面からタグをクリック
- タグ一覧画面（トップ）からタグをクリック
- URL直接入力: `/articles/tag/{tag}/`

**主要な操作・処理内容**：
1. タグパラメータを受け取り、該当タグが付いた公開済み記事を取得
2. ページネーションを用いて記事一覧を表示
3. 同一タグのページ一覧へのタブ切り替えリンクを提供
4. 各記事のタイトル、導入文、公開日、カテゴリ、タグを表示

**画面遷移**：
- 遷移元: 記事詳細画面、記事タグ一覧画面、タグ一覧画面
- 遷移先: 記事詳細画面、タグ別ページ一覧画面、カテゴリ別記事一覧画面、著者別記事一覧画面

**権限による表示制御**：
特になし。全ユーザー（匿名ユーザー含む）がアクセス可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | 記事一覧表示 | 主機能 | タグでフィルタした記事を表示 |
| 49 | タグ一覧表示 | 補助機能 | タグ情報の取得 |
| 62 | ページネーション | 補助機能 | 記事一覧のページ送り処理 |

## 画面種別

一覧

## URL/ルーティング

| パス | HTTPメソッド | アクション |
|------|--------------|------------|
| `/articles/tag/{variable}/` | GET | tagAction |
| `/articles/tag/{variable}/page/{page}/` | GET | tagAction（ページ指定） |

## 入出力項目

### 入力項目（URLパラメータ）

| 項目名 | パラメータ名 | 型 | 必須 | 説明 |
|--------|-------------|-----|------|------|
| タグ名 | variable | string | Yes | タグ文字列（URLエンコード） |
| ページ番号 | page | integer | No | ページネーションのページ番号（デフォルト: 1） |

## 表示項目

### タブナビゲーション

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| タグ見出し | $this->tag | 「Tag: {タグ名}」形式で表示 |
| Blogタブ | ATagCount | 現在のタブ（アクティブ）、記事数を表示 |
| Pagesタブ | PTagCount | タグ別ページ一覧へのリンク、ページ数を表示 |

### 記事一覧

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| 記事タイトル | article_title | 記事詳細画面へのリンク付き |
| 著者名 | user_alias | 設定により表示/非表示（著者別画面へのリンク付き） |
| 公開日 | article_published | ADateヘルパーでフォーマット |
| 導入文 | article_intro | HTML形式で表示 |
| 続きを読むリンク | - | article_contentがある場合のみ表示 |
| コメントリンク | - | article_commentsが'Y'の場合のみ表示 |
| コメント数 | - | CCountヘルパーで取得 |
| カテゴリ | acat_title | カテゴリ別記事一覧へのリンク付き |
| タグ一覧 | - | TListヘルパーで取得・表示 |

### ページネーション

| 項目名 | 説明 |
|--------|------|
| 現在ページ/総ページ | 「Page X of Y」形式 |
| 前へリンク | 前ページがある場合のみ活性化 |
| ページ番号リンク | ページ範囲内の番号を表示 |
| 次へリンク | 次ページがある場合のみ活性化 |

## イベント仕様

### 1-記事タイトルクリック

記事タイトルをクリックすると、該当記事の詳細画面に遷移する。

- 遷移先: `/articles/article/{article_id}/{article_title}/`

### 2-Pagesタブクリック

Pagesタブをクリックすると、同一タグのページ一覧画面に遷移する。

- 遷移先: `/pages/tag/{tag}/`

### 3-カテゴリリンククリック

カテゴリ名をクリックすると、該当カテゴリの記事一覧画面に遷移する。

- 遷移先: `/articles/category/{acat_title}/`

### 4-タグリンククリック

タグ名をクリックすると、該当タグの記事一覧画面に遷移する（現在のタグとは異なるタグの場合）。

- 遷移先: `/articles/tag/{tag_name}/`

### 5-著者名リンククリック

著者名をクリックすると、該当著者の記事一覧画面に遷移する。

- 遷移先: `/articles/author/{user_alias}/`
- 条件: showauthorがtrueの場合のみリンク表示

### 6-ページネーション操作

ページ番号や前へ/次へリンクをクリックすると、該当ページの記事一覧を表示する。

- 遷移先: `/articles/tag/{variable}/page/{page}/`

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | tags | SELECT | 指定タグの関連記事を検索 |
| 画面表示 | articles | SELECT | タグに紐づく記事データを取得 |
| 画面表示 | articles_categories | SELECT | 記事カテゴリ情報を取得 |
| 画面表示 | users | SELECT | 著者情報を取得 |

### テーブル別更新項目詳細

#### tags（SELECT）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | tag_slave | - | 関連記事ID |
| SELECT | tag_tag | tag_tag = {タグ名} | タグ文字列 |
| SELECT | tag_type | tag_type = 'A' | タグ種別（記事） |

#### articles（SELECT）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | article_id | JOIN ON tag_slave | 記事ID |
| SELECT | article_title | - | 記事タイトル |
| SELECT | article_intro | - | 導入文 |
| SELECT | article_content | - | 本文 |
| SELECT | article_published | - | 公開日 |
| SELECT | article_day | DAY(article_published) | 公開日（日） |
| SELECT | article_month | MONTH(article_published) | 公開日（月） |
| SELECT | article_year | YEAR(article_published) | 公開日（年） |
| SELECT | article_status | article_status = 'published' | 公開ステータス |
| SELECT | article_comments | - | コメント許可フラグ |
| SELECT | article_sticky | ORDER BY DESC | 固定記事フラグ |

#### articles_categories（SELECT）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | acat_title | - | カテゴリ名 |

#### users（SELECT）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | user_alias | - | 著者のエイリアス |

## メッセージ仕様

| メッセージID | 種別 | メッセージ | 表示条件 |
|-------------|------|----------|---------|
| MSG001 | 情報 | This tag has no associated articles | 該当タグの記事が0件の場合 |

## 例外処理

| 例外 | 処理 |
|------|------|
| タグパラメータ未指定 | 空の記事一覧を表示（MSG001を表示） |
| 該当タグの記事がない | 空の記事一覧を表示（MSG001を表示） |

## 備考

- 記事は固定記事（article_sticky）を優先し、公開日の降順でソートされる
- タグ名はURLエンコードされた状態でパラメータとして受け取り、urldecodeで復元する
- Blog/Pagesのタブナビゲーションにより、同一タグの記事とページを切り替え可能
- タグカウント（ATagCount, PTagCount）はビューヘルパーで取得

---

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

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

### 推奨読解順序

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

まず、タグと記事の関連構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | tags テーブル | DB Schema | tag_slave（関連ID）, tag_type（種別: A=記事, P=ページ）, tag_tag（タグ文字列） |
| 1-2 | articles テーブル | DB Schema | tagsテーブルとのJOIN関係 |
| 1-3 | articles_categories テーブル | DB Schema | acat_id, acat_title の関連 |

**読解のコツ**: tagsテーブルはポリモーフィック的な関連を持ち、tag_typeで記事('A')かページ('P')かを区別する。

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

処理の起点となるコントローラーアクションを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ArticlesController.php | `application/modules/default/controllers/ArticlesController.php` | tagActionメソッドがエントリーポイント |

**主要処理フロー**:
1. **383行目**: tagAction()メソッド開始
2. **385行目**: setRefer()でログイン後のリダイレクト先を設定
3. **389-394行目**: ページ番号の取得とデフォルト値設定
4. **396-397行目**: URLパラメータからタグ名を取得（urldecodeで復元）
5. **402-410行目**: SQLクエリ構築（tags, articles, articles_categories, usersのJOIN）
6. **412-416行目**: Zend_Paginatorでページネーション設定
7. **419行目**: ビューに記事配列を渡す

#### Step 3: ビューテンプレートを理解する

表示処理を担当するビューファイルを読み解く。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | tag.phtml | `application/modules/default/views/scripts/articles/tag.phtml` | メインテンプレート、タブナビゲーション |
| 3-2 | articlelist.phtml | `application/modules/default/views/scripts/_partials/articlelist.phtml` | 個別記事の表示テンプレート |
| 3-3 | default.phtml | `application/modules/default/views/scripts/_pagination/default.phtml` | ページネーション表示 |

**主要処理フロー**:
- **tag.phtml 27行目**: タグ名見出しの表示
- **tag.phtml 30-33行目**: Blog/Pagesタブナビゲーション
- **tag.phtml 37-47行目**: 記事存在チェックと条件分岐
- **tag.phtml 39行目**: partialLoopで各記事をarticlelist.phtmlで表示
- **tag.phtml 41行目**: paginationControlでページネーション表示

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

```
tagAction() [ArticlesController.php:383]
    │
    ├─ setRefer() - ログインリファラー設定
    │
    ├─ urldecode() - タグ名デコード
    │
    ├─ Zend_Registry::getInstance() - レジストリ取得
    │
    ├─ $registry->db->select() - SQLクエリ構築
    │      ├─ from('tags')
    │      ├─ join('articles', 'tag_slave = article_id')
    │      ├─ join('articles_categories')
    │      ├─ join('users')
    │      ├─ where('article_status = published')
    │      ├─ where('tag_tag = ?')
    │      ├─ where('tag_type = A')
    │      └─ order('article_sticky DESC, article_published DESC')
    │
    ├─ Zend_Paginator::factory($select) - ページネーター生成
    │
    └─ View rendering
           ├─ tag.phtml
           │      ├─ ATagCount() - 記事タグカウント
           │      ├─ PTagCount() - ページタグカウント
           │      ├─ partialLoop('_partials/articlelist.phtml')
           │      │      ├─ ADate() - 日付フォーマット
           │      │      ├─ CCount() - コメント数
           │      │      └─ TList() - タグ一覧
           │      └─ paginationControl()
           │             └─ _pagination/default.phtml
           └─ articles.phtml (layout)
```

### データフロー図

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

URLパラメータ
  ├─ variable(タグ名) ──▶ ArticlesController::tagAction()
  └─ page(ページ番号)           │
                              ▼
                    urldecode() - タグ名復元
                              │
                              ▼
                    Zend_Db_Select (クエリ構築)
                    tags -> articles JOIN
                              │
                              ▼
                    ┌─────────────────────┐
                    │     Database        │
                    │  ├─ tags            │
                    │  ├─ articles        │
                    │  ├─ articles_categories │
                    │  └─ users           │
                    └─────────────────────┘
                              │
                              ▼
                    Zend_Paginator (ページ分割)
                              │
                              ▼
                    View (tag.phtml)
                              │
                              ▼
                    ┌─────────────────────┐
                    │   HTML Response     │
                    │  ├─ タグ名見出し      │
                    │  ├─ タブナビゲーション │
                    │  ├─ 記事一覧         │
                    │  └─ ページネーション  │
                    └─────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ArticlesController.php | `application/modules/default/controllers/ArticlesController.php` | コントローラー | 記事関連アクションの制御 |
| tag.phtml | `application/modules/default/views/scripts/articles/tag.phtml` | ビュー | タグ別記事一覧画面のメインテンプレート |
| articlelist.phtml | `application/modules/default/views/scripts/_partials/articlelist.phtml` | パーシャル | 個別記事の表示テンプレート |
| default.phtml | `application/modules/default/views/scripts/_pagination/default.phtml` | パーシャル | ページネーションコンポーネント |
| info.phtml | `application/modules/default/views/scripts/_partials/info.phtml` | パーシャル | 情報メッセージ表示 |
| articles.phtml | `application/layouts/scripts/articles.phtml` | レイアウト | 記事セクション用レイアウト |
| articles.ini | `application/configs/articles.ini` | 設定 | 記事モジュールの設定ファイル |
| ATagCount.php | `library/CMS/View/Helper/ATagCount.php` | ヘルパー | 記事タグカウント取得 |
| PTagCount.php | `library/CMS/View/Helper/PTagCount.php` | ヘルパー | ページタグカウント取得 |
