# How to Implement Pagination for LargeTable in Outfancy

> Learn how to implement pagination for LargeTable in Outfancy. Discover how to easily manage large datasets with Outfancy's built-in pagination features for improved table performance.

- Repository: [Carlos A. Planchón/outfancy](https://github.com/carlosplanchon/outfancy)
- Tags: how-to-guide
- Published: 2026-02-26

---

**Outfancy's `Table` class includes built-in pagination via the `page` parameter in `render()`, which internally calculates visible rows using `check_page_value()` and slices output through `post_render()` in [`outfancy/table.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/table.py).**

The `outfancy` library provides terminal table formatting with native support for large datasets. Implementing pagination for LargeTable in outfancy requires no external dependencies—the `Table` class contains integrated logic to calculate page heights based on terminal dimensions and slice rendered output accordingly. This guide demonstrates how to use the built-in `page` argument and customize pagination behavior for CLI applications.

## How Pagination Works in Outfancy

The pagination mechanism follows a three-step pipeline defined in [`outfancy/table.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/table.py):

### Step 1: Request a Specific Page via `render()`

The `render()` method accepts a `page` argument (`int | None`) that specifies the zero-based page index to display【/tmp/instagit_umjxpk52/outfancy/table.py:260‑263】. When `page` is `None`, the entire table renders without slicing. When an integer is provided, the library calculates which rows belong to that page.

### Step 2: Calculate Visible Rows with `check_page_value()`

Before rendering, `check_page_value()` determines the `page_height` by analyzing the terminal height (`screen_y`) and subtracting one line if a label row is present【/tmp/instagit_umjxpk52/outfancy/table.py:576‑589】. This ensures the table never exceeds the available terminal real estate.

### Step 3: Slice the Rendered String in `post_render()`

After generating the full table string, `post_render()` splits the output into lines, extracts the slice from `first_row` to `last_row` based on the calculated page height, and rejoins the lines【/tmp/instagit_umjxpk52/outfancy/table.py:154‑168】. This sliced string is returned as the final output.

## Basic Pagination Implementation

To paginate through a large dataset, instantiate the `Table` class and call `render()` with incrementing `page` values:

```python
from outfancy.table import Table
from outfancy.example_dataset import dataset

tbl = Table()

# Optional: remove row limits to let terminal height dictate page size

tbl.set_maximum_number_of_rows(-1)

for page in range(3):
    rendered = tbl.render(dataset, page=page)
    print(f"\n--- Page {page + 1} ---")
    print(rendered)

```

**How this works:**
- `page=0` displays the first screenful of rows
- `check_page_value()` automatically derives `page_height` from your terminal size
- `post_render()` handles the string slicing internally

## Controlling Page Size and Layout

### Fixed-Size Pages Regardless of Terminal Height

To enforce a specific number of rows per page (e.g., exactly 10 data rows), manually set `screen_y` to account for the header and margin:

```python
from outfancy.table import Table
from outfancy.example_dataset import dataset

tbl = Table()
tbl.set_maximum_number_of_rows(-1)

# 10 data rows + 1 header + 1 margin = 12 lines

screen_y = 12

for i in range(0, len(dataset), 10):
    page_index = i // 10
    rendered = tbl.render(dataset, page=page_index, screen_y=screen_y)
    print(rendered)
    print("-" * 40)

```

**Note:** The library subtracts one line for the label row when `label_list` is present, leaving exactly 10 rows for data【/tmp/instagit_umjxpk52/outfancy/table.py:576‑589】.

### Terminal-Responsive Pagination

For dynamic resizing based on the actual terminal dimensions, omit the `screen_y` argument or pass the current terminal height. The `check_page_value()` method recalculates `page_height` on each `render()` call, adapting to window resizing automatically.

## Building an Interactive Pager

Create a command-line pager using a simple loop that adjusts the `page` parameter based on user input:

```python
from outfancy.table import Table
from outfancy.example_dataset import dataset

tbl = Table()
current_page = 0

while True:
    output = tbl.render(dataset, page=current_page)
    print("\n" + output)
    
    cmd = input("\n[p]rev | [n]ext | [q]uit: ").strip().lower()
    if cmd == "n":
        current_page += 1
    elif cmd == "p" and current_page > 0:
        current_page -= 1
    elif cmd == "q":
        break

```

This implementation reuses the same `render()` logic—no manual slicing required.

## Summary

- **Built-in pagination** is available via the `page` parameter in `Table.render()` at lines 260‑263 of [`outfancy/table.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/table.py)
- **Page height calculation** occurs automatically in `check_page_value()` (lines 576‑589), respecting terminal dimensions and header rows
- **Row slicing** is handled by `post_render()` (lines 154‑168), which extracts the appropriate line range from the rendered string
- **Customization** is possible through `set_maximum_number_of_rows()` or explicit `screen_y` values to override terminal detection

## Frequently Asked Questions

### How do I disable pagination and show all rows at once?

Pass `page=None` (the default) to `render()`. When `page` is `None`, `post_render()` skips the slicing logic and returns the complete table string.

### Can I limit the maximum rows per page independently of terminal size?

Yes. Call `tbl.set_maximum_number_of_rows(n)` where `n` is the desired limit, or pass a fixed `screen_y` value to `render()`. Setting `-1` removes the limit entirely, allowing the terminal height to determine page size.

### Where is the pagination logic implemented in the source code?

The core pagination logic resides in [`outfancy/table.py`](https://github.com/carlosplanchon/outfancy/blob/main/outfancy/table.py). Specifically, `check_page_value()` calculates how many rows fit on screen (lines 576‑589), while `post_render()` performs the actual string slicing to isolate the current page (lines 154‑168).

### Does outfancy use zero-based or one-based page indexing?

Outfancy uses **zero-based indexing** for the `page` argument. The first page is `0`, the second is `1`, and so on. This aligns with Python's standard indexing conventions used throughout the library.