agentsclimarketplace

Cbpaginator

Skill ColdBox/skills/modules/cbpaginator

Collection of skills for the ColdBox Platform and Claude Plugin

Install
npx -y skills add ColdBox/skills --skill cbpaginator

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use this skill when implementing server-side pagination in ColdBox/BoxLang using cbpaginator. Covers installation, Paginator service configuration, generating pagination metadata for APIs and views, integrating with QB QueryBuilder, rendering Bootstrap pagination controls, and building pageable collection responses.

SKILL.md

4.9 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it

CBPaginator Skill

When to Use This Skill

Load this skill when:

  • Adding pagination to a listing handler or REST API endpoint
  • Generating page metadata (total, per_page, current_page, last_page, from, to)
  • Integrating pagination with QB or qb QueryBuilder
  • Building Bootstrap or Tailwind page-number navigation in views
  • Creating consistent { data: [], pagination: {} } API responses

Installation

box install cbpaginator

Core API

Injection

property name="paginator" inject="Pagination@cbpaginator";

Create a Paginator

var page = paginator
    .newPagination()
    .setTotalRecords( totalCount )
    .setMaxRows(      rc.perPage ?: 25 )
    .setPage(         rc.page    ?: 1 )
    .calculate()

// Available properties after calculate():
page.getPage()        // current page number
page.getMaxRows()     // per-page count
page.getTotalRecords()
page.getTotalPages()
page.getOffset()      // SQL OFFSET value
page.getFrom()        // first record on this page
page.getTo()          // last record on this page
page.hasPreviousPage()
page.hasNextPage()

Shorthand — paginate()

var page = paginator.paginate(
    page         = rc.page    ?: 1,
    maxRows      = rc.perPage ?: 25,
    totalRecords = userService.count()
)

var users = userService.list(
    max    = page.getMaxRows(),
    offset = page.getOffset()
)

Production Patterns

REST API — Pageable Collection

function index( event, rc, prc ) {
    var page  = paginator.paginate(
        page         = rc.page    ?: 1,
        maxRows      = rc.perPage ?: 25,
        totalRecords = userService.count()
    )

    event.renderData( type = "json", data = {
        data       : userService.list( max = page.getMaxRows(), offset = page.getOffset() ),
        pagination : {
            total        : page.getTotalRecords(),
            per_page     : page.getMaxRows(),
            current_page : page.getPage(),
            last_page    : page.getTotalPages(),
            from         : page.getFrom(),
            to           : page.getTo()
        }
    } )
}

QB Integration

// Inject QB
property name="qb"        inject="QueryBuilder@qb";
property name="paginator" inject="Pagination@cbpaginator";

function index( event, rc, prc ) {
    var total = qb.from( "users" ).where( "isActive", true ).count()

    var page  = paginator.paginate(
        page         = rc.page ?: 1,
        maxRows      = 20,
        totalRecords = total
    )

    prc.users = qb.from( "users" )
        .where( "isActive", true )
        .orderByDesc( "createdAt" )
        .limit(  page.getMaxRows() )
        .offset( page.getOffset() )
        .get()

    prc.pagination = page
}

View — Bootstrap 5 Pagination

<cfif prc.pagination.getTotalPages() gt 1>
    <nav>
        <ul class="pagination">
            <!--- Previous --->
            <li class="page-item <cfif NOT prc.pagination.hasPreviousPage()>disabled</cfif>">
                <a class="page-link"
                   href="#event.buildLink( 'users.index' )#?page=#prc.pagination.getPage() - 1#">
                    &laquo;
                </a>
            </li>

            <!--- Page numbers --->
            <cfloop from="1" to="#prc.pagination.getTotalPages()#" index="i">
                <li class="page-item <cfif i eq prc.pagination.getPage()>active</cfif>">
                    <a class="page-link"
                       href="#event.buildLink( 'users.index' )#?page=#i#">#i#</a>
                </li>
            </cfloop>

            <!--- Next --->
            <li class="page-item <cfif NOT prc.pagination.hasNextPage()>disabled</cfif>">
                <a class="page-link"
                   href="#event.buildLink( 'users.index' )#?page=#prc.pagination.getPage() + 1#">
                    &raquo;
                </a>
            </li>
        </ul>
    </nav>
</cfif>

Best Practices

  • Always validate rc.page and rc.perPage are positive integers before passing to paginate()
  • Cap maxRows at a reasonable limit (e.g., 100) to prevent unbounded queries
  • Run the count query before paginate() — ensure accurate total records
  • Return offset from the paginator, not calculated manually, to cover edge-case page-boundary arithmetic
  • Clamp page to valid range — if the requested page exceeds totalPages, redirect or return the last page
  • Include pagination metadata in every list API response for consistent consumer contracts

Documentation

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,970. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.