Yii 內建 CLinkPager 功能完整但樣式固定。當專案需要獨特的分頁 UI(如數字按鈕樣式、省略號邏輯、AJAX 分頁)時,最佳做法是繼承 CListPager 基類並覆寫核心渲染方法。本文完整示範從複製基類到註冊 CSS、覆寫 run() 的全流程。
# 複製核心類別 cp framework/web/widgets/pagers/CListPager.php protected/components/ZPager.php # 複製預設樣式 cp framework/web/widgets/pagers/pager.css protected/components/css/pager.css
// protected/components/ZPager.php
class ZPager extends CListPager {
// 修改 CSS 註冊路徑指向專案自訂樣式
public static function registerCssFile($url = null) {
if ($url === null) {
$url = CHtml::asset(Yii::getPathOfAlias('application.components.css.pager') . '.css');
}
Yii::app()->getClientScript()->registerCssFile($url);
}
// 核心:覆寫 run() 實作自訂 HTML 結構
public function run() {
// ... 參考父類邏輯,輸出自訂 widget('zii.widgets.grid.CGridView', array(
'id' => 'news-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'template' => '{items}{summary}{pager}',
'pager' => 'ZPager', // 關鍵:指定自訂分頁器類別名稱
'summaryText' => '頁數:{pages}/{page}頁',
'columns' => array(
array(
'class' => 'CCheckBoxColumn',
'footer' => ' ',
'footerHtmlOptions' => array('colspan' => 5),
'selectableRows' => 2,
),
'id',
array('name' => 'title', 'htmlOptions' => array('width' => '20%'),
'value' => 'mb_substr($data->title, 0, 10, "UTF-8")'),
array('name' => 'content', 'htmlOptions' => array('width' => '20%'),
'value' => 'mb_substr(strip_tags($data->content), 0, 10, "UTF-8")'),
array('name' => 'type', 'value' => 'News::model()->getNewsType($data->type)'),
'user',
array('name' => 'status', 'value' => 'News::model()->getNewsStatus($data->status)'),
array(
'class' => 'CButtonColumn',
'buttons' => array('view' => array('visible' => 'false')),
),
),
)); ?>
修改 framework/zii/widgets/grid/CGridView.php 第 152 行 renderFooterCell(),允許 footer 為空時仍渲染 <td>:
public function renderFooterCell() {
// 原版:if(trim($this->footer)!=='') return;
// 修改:移除判斷,直接渲染
echo CHtml::openTag('td', $this->footerHtmlOptions);
$this->renderFooterCellContent();
echo '';
}
視圖中即可在 CCheckBoxColumn 設定 footer 為功能按鈕:
array(
'class' => 'CCheckBoxColumn',
'footer' => ' ',
'footerHtmlOptions' => array('colspan' => 5),
'selectableRows' => 2,
),
/* protected/components/css/pager.css */
.pagination { display: flex; gap: 4px; justify-content: center; margin: 20px 0; }
.pagination a, .pagination span { padding: 8px 12px; border: 1px solid #ddd; border-radius: 4px; text-decoration: none; color: #333; }
.pagination .current { background: #007bff; color: #fff; border-color: #007bff; cursor: default; }
.pagination .disabled { color: #999; pointer-events: none; border-color: #eee; }
.pagination .ellipsis { pointer-events: none; border: none; padding: 8px 4px; }
.pagination a:hover:not(.current):not(.disabled) { background: #f5f5f5; }
透過繼承而非修改核心,你獲得了完全可控的分頁 UI,且未來升級 Yii 核心不會衝突。建議將 ZPager 納入專案共用元件庫,所有 GridView/ListView 統一使用,保持介面一致性。