wikipedia-pages-js — Wikipedia Pages (opaque continue-token pagination)
A demo of vanilla-grid against the public MediaWiki Action API that
paginates via an opaque continue object whose fields must be echoed back
on the next request. Implements a custom DataManager that stores the
continue token in its own state and ignores the grid's (skip, pageSize)
hint entirely.
What it shows
- Custom
DataManager—WikipediaDataManagerextendswindow.DataManagerand overridesfetchRows()/fetchMoreRows(). - Opaque continue-token pagination — the API returns
{ "continue": { "gcmcontinue": "...", "continue": "..." } }; we merge every field into the next request URL verbatim. Nototal_count. - No total count available — status bar uses the "Loaded N" format, switching to "(end of category)" when pagination terminates.
<vn-grid-toolbar>status bar — asrc/vanilla-grid-toolbar/linked to the grid: standard auto-fit / reset / reload commands in the empty template (no clear-filters — the continue-token API supports no filtering and every column is non-sortable); export-to-Excel + a custom view command (opens the page detail panel, single selection only) + clear-selection in the selected template. Only theexportToExcelcommand is overridden (registerCommand) for the app's file naming (theme-matched Excel styling is automatic — the grid'sexportToExcel()defaults tothemeStyle: 'auto') and returns the export's promise, so the toolbar handles its outcome (a cancelled export is not an error); the view command is handled via thevn-grid-toolbar-commandevent. The status line is fed viapagesToolbar.setStatusMessage()using generic "rows" wording, with the live selection count appended (… · 2 selected).- CORS via
&origin=*— required for browser access without auth. - No rate limit / no auth for normal use of the public Wikipedia API.
- Switchable category — header dropdown lets you choose among
Web Frameworks (default), Programming Languages, Operating
Systems, Text Editors, Free Software. Changing the selection
resets the data manager's continue-token state, refires
onConfigChanged, triggers a fresh load, and updates the tab title. The choice is persisted inlocalStorageunderwikipedia-pages-js:selectedCategory. - Multiple-row selection, row double-click → detail side panel, Excel export (theme-styled), 8 themes, EN/IT i18n, resizable grid container — all kept identical to northwind-orders-js.
Resizing the grid
The grid sits in a src/vanilla-resize-box/ (aria-label="Resizable Wikipedia pages grid"). Drag the corner handle to resize it — resizing is pointer-driven, with no keyboard path.
The handle carries role="separator" and takes its accessible name from the host's aria-label — here "Resizable Wikipedia pages grid — resize handle" — but is not focusable, so it adds no tab stop to the page. This app's markup needs nothing beyond the aria-label it already carries.
Endpoint
GET https://en.wikipedia.org/w/api.php
?action=query
&format=json
&formatversion=2
&origin=*
&generator=categorymembers
&gcmtitle=Category:Web_frameworks
&gcmlimit=20
&gcmtype=page
&gcmsort=sortkey
&gcmdir=ascending
&prop=info|pageimages|extracts
&inprop=url
&piprop=thumbnail
&pithumbsize=80
&exintro=1
&explaintext=1
&exlimit=20
&exchars=300
Note: the intro extract ships with the list query, which is safe only because
gcmlimit === exlimit(bothPAGE_SIZE, 20). The MediaWiki TextExtracts module capsexlimit; when a page holds more rows than extracts, the API returnscontinue.excontinueinstead ofgcmcontinue, which would stall the generator. Keeping the two equal gives every row its extract (the grid's Preview column and the detail panel) with no per-row request.
Subsequent requests append the entire continue object verbatim:
&continue=gcmcontinue||&gcmcontinue=page%7C123%7C456
Sorting
The MediaWiki categorymembers generator only supports two server-side
sort modes via the gcmsort parameter:
gcmsort |
Description |
|---|---|
sortkey |
Default. By per-page category sort key (see caveat below). |
timestamp |
When the page was added to the category (not when it was edited). |
Direction is controlled by gcmdir=ascending|descending.
In this demo every column (pageid, title, preview, length,
touched, contentmodel, pagelanguage) is marked sortable="false"
in index.html: the API exposes no sort key for most of
them, client-side sorting would be misleading on a partially loaded
infinite-scroll dataset, and sortkey is not a true title sort (see the
caveat below). The data manager still maps a title sort to
gcmsort=sortkey / gcmdir, so re-enabling sorting on Title is a
markup-only change.
⚠️ Caveat —
sortkeyis NOT strict alphabetical-by-title. The category sort key is a per-page string set manually by editors with[[Category:Web frameworks|<sortkey>]]. When omitted it defaults to the page title, but many pages override it (e.g. Apache Cocoon may be filed underCocoon, The Sponge Framework underSponge). The resulting order looks roughly alphabetical but contains surprises; there is no way to get a strict title sort from this generator.
💡 Why
formatversion=2matters. With the legacyformatversion=1response,query.pagesis an object keyed by pageid. Iterating it withObject.values(...)in JavaScript silently re-sorts entries numerically by pageid, destroying the server's sort order. We requestformatversion=2soquery.pagescomes back as an ordered array that preserves the API'sgcmsortordering.
Etiquette
The Wikimedia Foundation asks API consumers to set a descriptive
User-Agent header. Browsers do not allow JS to override User-Agent,
so the demo cannot do this — for production scrapers please proxy through
a backend that sets one. See https://meta.wikimedia.org/wiki/User-Agent_policy.
Run
Serve the workspace root with any static server, then open
/samples/wikipedia-pages-js/index.html.
Files
index.html— same shell as northwind-orders-js; columns target Wikipedia page fields (pageid, title, preview, length, touched, …).modules/pages-tab.js— definesWikipediaDataManagerand wires the grid (initializePagesGrid) / detail panel / export.modules/i18n.js— page-specific translations.modules/dom-refs.js,modules/theme.js,styles.css,themes/— unchanged from northwind-orders-js.
Notes for adapting to other continue-token APIs
The same pattern works for any API that returns an opaque continuation
object that must be echoed back (Azure ARM nextLink, AWS NextToken,
…). Only _buildUrl() and the response parser inside _get() need
adapting.