Skip to content

paginationNav() / pageNumberLinks() cannot emit Bootstrap <li class="page-item active"> pattern without regex post-process in app code #2718

@bpamiri

Description

@bpamiri

Severity: medium — same audience as #2715 (Bootstrap-styled 3.x apps). Forces a regex hack in every app's pagination helper.

Surfaced by: titan Phase 2.4 (Wheels 4.0 upgrade), 2026-05-15.

Description

The Bootstrap pagination pattern places the active-page class on the <li> wrapper, not on the <a>:

<ul class=\"pagination\">
  <li class=\"page-item\"><a class=\"page-link\" href=\"...\">1</a></li>
  <li class=\"page-item active\"><a class=\"page-link\" href=\"...\">2</a></li>
  <li class=\"page-item\"><a class=\"page-link\" href=\"...\">3</a></li>
</ul>

Neither paginationLinks() (legacy) nor pageNumberLinks() (4.0 primitive used internally by paginationNav()) can emit this. Both put classForCurrent on the <a>:

<li class=\"page-item\"><a class=\"page-link active\" href=\"...\">2</a></li>

The legacy addActiveClassToPrependedParent arg sounds like it should help, but it only inserts the class into the wrapper's existing class attribute; it doesn't replace the active on the anchor. Apps still need a Replace() regex post-process to move the class from <a> to <li>.

Titan's working pattern (in app/views/helpers.cfm after Phase 2.4 migration) keeps a Replace() hack across the bsPaginationLinks() output:

local.rv = Replace(local.rv, \" active\", \"\", \"all\");  // strip from anchors
// ... then re-insert into <li> via different code path

Suggested fix

Add to pageNumberLinks() (and inherited by paginationNav()) one of:

  • activeClassOnPrependedParent — if true, omit classForCurrent from the anchor, append it to prependToPage's class attribute on the current-page iteration only.
  • currentPageWrap=\"<li class='page-item active'><a class='page-link'>\" — full override on the current page, regardless of normal prependToPage.

Either lets Bootstrap-styled apps drop the regex hack.

cc @bpamiri

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions