まいける's Tech Blog

LAMP関係のメモなどを不定期に掲載します

Smarty3 x Bootstrap3 用のページャープラグインを作ってみた

 都度都度ページャー作るのも面倒なので、作ってみました。

 まずは、プラグイン本体(function.paging.php)。Smartyプラグインディレクトリに保存してください。

<?php
function smarty_function_paging($params, $smarty)
{
    $total_page = ceil($params['paging_data']['total_row_count'] / $params['paging_data']['page_row_count']);
    $total_page_str = $total_page;
    if (empty($params['paging_data']['current_page'])) {
        $params['paging_data']['current_page'] = 1;
    }

    $result = null;

    // ページが2ページ以上ある場合にページャーを表示
    if ($total_page > 1) {
        $prev = $params['paging_data']['current_page'] - 1;
        $prev_str = $prev;
        $next = $params['paging_data']['current_page'] + 1;
        $next_str = $next;

        $result = '<nav aria-label="Page navigation">' . "\n";
        $result .= '<ul class="pagination">' . "\n";

        if ($prev < 1) {
            // 最初のページ
            $result .= '<li class="disabled"><span><span aria-hidden="true">&laquo;</span></span></li>' . "\n";
            // 前のページ
            $result .= '<li class="disabled"><span><span aria-hidden="true">&lt;</span></span></li>' . "\n";
        } else {
            // 最初のページ
            $result .= '<li><a href="' . str_replace('%p', '1',
                    $params['paging_data']['url']) . '" aria-label="First"><span aria-hidden="true">&laquo;</span></a></li>' . "\n";
            // 前のページ
            $result .= '<li><a href="' . str_replace('%p', $prev_str,
                    $params['paging_data']['url']) . '" aria-label="Previous"><span aria-hidden="true">&lt;</span></a></li>' . "\n";
        }

        $start_page = max(1, $params['paging_data']['current_page'] - 3);
        $end_page = min($total_page, $params['paging_data']['current_page'] + 3);

        for ($page = $start_page; $page <= $end_page; $page++) {
            $page_str = $page;

            if ($page == $params['paging_data']['current_page']) {
                // 現在のページ
                $result .= '<li class="active"><span>' . $page_str . '<span class="sr-only">(current)</span></span></li>
' . "\n";
            } else {
                $result .= '<li><a href="' . str_replace('%p', $page_str,
                        $params['paging_data']['url']) . '">' . $page_str . '</a></li>' . "\n";
            }
        }

        if ($next > $total_page) {
            // 次のページ
            $result .= '<li class="disabled"><span><span aria-hidden="true">&gt;</span></span></li>' . "\n";
            // 最後のページ
            $result .= '<li class="disabled"><span><span aria-hidden="true">&raquo;</span></span></li>' . "\n";
        } else {
            // 次のページ
            $result .= '<li><a href="' . str_replace('%p', $next_str,
                    $params['paging_data']['url']) . '" aria-label="Next"><span aria-hidden="true">&gt;</span></a></li>' . "\n";
            // 最後のページ
            $result .= '<li><a href="' . str_replace('%p', $total_page_str,
                    $params['paging_data']['url']) . '" aria-label="Last"><span aria-hidden="true">&raquo;</span></a></li>' . "\n";
        }
        $result .= '</ul>' . "\n";
        $result .= '</nav>' . "\n";
    }

    if ($params['debug']) {
        $result .= '<div class="bs-callout bs-callout-info"><h4>ページングデバッグ</h4>' . "\n";
        $result .= '<ul class="list-group">' . "\n";
        $result .= '<li class="list-group-item">全ページ数:' . $total_page . '</li>';
        $result .= '<li class="list-group-item">URL:' . $params['paging_data']['url'] . '</li>';
        $result .= '<li class="list-group-item">ページ内表示件数:' . $params['paging_data']['total_row_count'] . '</li>';
        $result .= '<li class="list-group-item">件数:' . $params['paging_data']['page_row_count'] . '</li></ul></div>';
    }

    $smarty->assign('pager', $result);
}

 次に呼び出し側のPHPですが、こちらは

<?php
$smarty = new Smarty();

$page = (int)filter_input(INPUT_GET, 'page');
if ($page == 0) {
    $page = 1;
}

// データベースから取得したデータが $data として

$paging_data = array(
    'page_row_count' => 30,
    'current_page' => $page,
    'url' => $_SERVER['SCRIPT_NAME'] . '?page=%p',
    'total_row_count' => $data->count();
);

$smarty->assign('paging_data', $paging_data);
$smarty->display('page.tpl');

みたいな感じで。%p の部分が実際にはページ番号に置き換えられます

最後にテンプレートファイルですが

{paging paging_data=$paging_data}

プラグインを呼び出して、ページャーを入れたいところに

{$pager}

を入れる感じです

ちなみに

{paging paging_data=$paging_data debug=1}

とすると、プラグインに渡した値が確認できます。
基本的に Bootstrap3 のみで表示できるようになっていますが、デバッグモードの部分だけ

.bs-callout {
  padding: 20px;
  margin: 20px 0;
  border: 1px solid #eee;
  border-left-width: 5px;
  border-radius: 3px;
}
.bs-callout h4 {
  margin-top: 0;
  margin-bottom: 5px;
}
.bs-callout p:last-child {
  margin-bottom: 0;
}
.bs-callout code {
  border-radius: 3px;
}
.bs-callout+.bs-callout {
  margin-top: -5px;
}
.bs-callout-info {
  border-left-color: #5bc0de;
}
.bs-callout-info h4 {
  color: #5bc0de;
}

css に追加してください。Bootstrapの公式サイトでも使われているデザインなのですが、BootstrapのCSSには定義されていないので。