---
title: Pagination
description: URL-driven pagination with template helpers.
---

Pagination in Nibiru is **URL-driven**. The page number is a URL segment (`/products/index/page/3`), not a query string. The `Pageination` class — note the spelling — reads it, computes offsets, and assigns a `pagination` array into Smarty.

## Wiring it in

```php
use Nibiru\Pageination;
use Nibiru\Model\products;

class productsController extends Controller
{
    public function pageAction() {
        $products = new products();
        Pageination::setEntriesPerPage(25);   // optional; default from INI
        Pageination::setTable($products);
        $rows = Pageination::loadTableAsArray();

        View::assign(['products' => $rows]);
    }

    public function navigationAction() {
        JsonNavigation::getInstance()->loadJsonNavigationArray();
    }
}
```

`Pageination::setTable(...)` reads the URL, calculates offsets, and assigns the navigation metadata into the template via the `pagination` variable.

## Rendering in the template

```smarty
{include 'shared/header.tpl'}
<body>
{include file="navigation.tpl"}

<main class="container">
  <table class="table">
    {foreach $products as $p}
      <tr><td>{$p.id}</td><td>{$p.name|escape}</td></tr>
    {/foreach}
  </table>

  {include file="pageination.tpl"}
</main>
{include 'shared/footer.tpl'}
</body>
```

Or render inline:

```smarty
<nav class="pagination">
  {if $pagination.previous}
    <a href="{$pagination.paginationPath}/page/{$pagination.previous}">←</a>
  {/if}

  {foreach $pagination as $entry}
    {if isset($entry.page)}
      <a class="{if $entry.page == $pagination.current}active{/if}"
         href="{$pagination.paginationPath}/page/{$entry.page}">
        {$entry.page}
      </a>
    {/if}
  {/foreach}

  {if $pagination.next}
    <a href="{$pagination.paginationPath}/page/{$pagination.next}">→</a>
  {/if}
</nav>
```

## URL format

```
/<controller>/<action>/page/<N>
```

Examples:

```
/products/index/page/2
/products/page/2          ; if action is omitted, "index" is implied
/users/list/page/7
```

The `paginationPath` template variable is the path *without* `/page/N` — append your own page number when generating links.

## Configuration

```ini
[SETTINGS]
entries.per.page = 25
```

This is the global default; override per-controller with `Pageination::setEntriesPerPage()` before `setTable()`.

## Common pitfalls

- **Spelling.** The class is `Pageination`, the trait is `Attributes\Pageination`, the template is `pageination.tpl`. It's spelled this way throughout the framework. Don't fight it.
- **`setTable()` order.** Call `setEntriesPerPage()` *before* `setTable()`, otherwise the offsets are computed against the default.
- **Page-0 is invalid.** If a user requests `/page/0`, treat it as `1`. Nibiru does this internally, but if you build your own pagination links, normalise inputs.
