Metadata-Version: 2.4
Name: coffeecode-paginator
Version: 1.0.0
Summary: Lightweight HTML pagination renderer with limit/offset helpers for SQL. Python fork of robsonvleite/paginator (PHP).
Project-URL: Homepage, https://github.com/kauelima21/coffeecode-paginator
Project-URL: Original PHP, https://github.com/robsonvleite/paginator
Project-URL: Issues, https://github.com/kauelima21/coffeecode-paginator/issues
Author-email: Kaue Leal <kaue.lima@totvs.com.br>
License: MIT
License-File: LICENSE
Keywords: coffeecode,fastapi,flask,html,limit,offset,pagination,paginator,sql
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.9
Provides-Extra: dev
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Description-Content-Type: text/markdown

# Paginator (Python)

Port em Python do pacote PHP [coffeecode/paginator](https://github.com/robsonvleite/paginator)
de Robson V. Leite. Gera HTML de paginacao + helpers `limit()`/`offset()` para
sua query SQL. API minima: configura no construtor, chama `pager()`, renderiza.

> Python port of the PHP package [coffeecode/paginator](https://github.com/robsonvleite/paginator)
> by Robson V. Leite. Renders pagination HTML and exposes `limit()`/`offset()`
> for SQL queries. Configure via constructor, call `pager()`, then `render()`.

## Destaques

- Pure Python, zero dependencias de runtime
- HTML estruturado com classes customizaveis (`<nav>`, `<a>`, `<span>`)
- `limit()` / `offset()` prontos para `LIMIT ? OFFSET ?`
- Suporte a hash (`#anchor`) e GET params extras nos links
- Janela de paginas configuravel (`range_`)

## Instalacao

```bash
pip install coffeecode-paginator
```

Requer Python >= 3.9.

## Uso

```python
from coffeecode_paginator import Paginator

pager = Paginator()
pager.pager(rows=100, limit=10, page=1)

print(pager.limit())   # 10
print(pager.offset())  # 0
print(pager.pages())   # 10
print(pager.render())
```

Saida (formatada para leitura):

```html
<nav class="paginator">
  <a class="paginator_item" aria-label="Primeira página" title="Primeira página" href="?page=1"><<</a>
  <span class="paginator_item paginator_active">1</span>
  <a class="paginator_item" aria-label="Página 2" title="Página 2" href="?page=2">2</a>
  <a class="paginator_item" aria-label="Página 3" title="Página 3" href="?page=3">3</a>
  <a class="paginator_item" aria-label="Página 4" title="Página 4" href="?page=4">4</a>
  <a class="paginator_item" aria-label="Última página" title="Última página" href="?page=10">>></a>
</nav>
```

### First/Last dinamicos

Esconde os links "Primeira"/"Última" quando voce ja esta na primeira/ultima:

```python
pager.render(fixed_first_and_last=False)
```

### FastAPI

```python
from fastapi import FastAPI, Query
from fastapi.responses import HTMLResponse
from coffeecode_paginator import Paginator

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
def index(page: int = Query(1, ge=1)):
    pager = Paginator()
    pager.pager(rows=237, limit=20, page=page)
    nav = pager.render() or ""
    return f"<html><body>{nav}</body></html>"
```

### Flask

```python
from flask import Flask, request
from coffeecode_paginator import Paginator

app = Flask(__name__)

@app.route("/")
def index():
    page = request.args.get("page", default=1, type=int)
    pager = Paginator()
    pager.pager(rows=100, limit=10, page=page)
    return f"<html><body>{pager.render() or ''}</body></html>"
```

### Hash + GET params extras

```python
pager.pager(rows=100, limit=10, page=2, hash_="results", params={"q": "hello"})
pager.render()
# href="?page=1#results&q=hello"
# href="?page=10#results&q=hello"
```

## API

### `Paginator(link="?page=", title="Página", first=("Primeira página", "<<"), last=("Última página", ">>"))`

Configura textos e template do link. Aceita qualquer prefixo:
`Paginator(link="/items/page/")` gera `href="/items/page/3"`.

### `pager(rows, limit=10, page=None, range_=3, hash_=None, params=None)`

Calcula estado da paginacao. `page` invalido ou maior que o total e
**clampado** para a ultima pagina valida (PHP redirecionava com `header()`;
o port nao tem contexto HTTP — caller decide se redireciona).

### `render(css_class=None, fixed_first_and_last=True)`

Retorna o HTML do `<nav>`. Retorna `None` quando `rows <= limit` (paginacao
desnecessaria).

### Helpers

- `limit() -> int`
- `offset() -> int`
- `page() -> int`
- `pages() -> int`
- `first_page(fixed=True) -> Optional[str]`
- `last_page(fixed=True) -> Optional[str]`

## CSS sugerido

Mesmo do exemplo PHP — funciona out-of-the-box:

```css
.paginator { list-style: none; padding: 0; margin-top: 30px; }
.paginator_item {
  display: inline-block; margin: 0 10px; padding: 4px 12px;
  background: #A287E7; color: #fff; text-decoration: none;
  border-radius: 4px;
}
.paginator_item:hover { background: #8A6ED5; }
.paginator_active, .paginator_active:hover { background: #cccccc; }
```

## Equivalencia com a versao PHP

| PHP                                       | Python                                |
|-------------------------------------------|---------------------------------------|
| `CoffeeCode\Paginator\Paginator`          | `coffeecode_paginator.Paginator`      |
| `pager($rows, $limit, $page, $range, $hash, $params)` | `pager(rows, limit, page, range_, hash_, params)` |
| `render($cssClass, $fixedFirstAndLast)`   | `render(css_class, fixed_first_and_last)` |
| `firstPage()` / `lastPage()`              | `first_page()` / `last_page()`        |
| `header("Location: ...")` redirect         | (omitido — caller redireciona)        |

## Creditos

- API original: Robson V. Leite — [coffeecode/paginator](https://github.com/robsonvleite/paginator) (MIT)
- Port Python: Kaue Leal

## Licenca

MIT.
