Collections

Configurable page collections with table UI and REST API

Collections — ProcessWire Module

Requires: ProcessWire 3.0.244+, PHP 8.2+
Author: Maxim Semenov · smnv.org · maxim@smnv.org
GitHub: github.com/mxmsmnv/Collections


The Problem


ProcessWire's default Page List is built for site structure — not data management. When you have thousands of pages as data records (products, listings, candidates, menu items), the default admin becomes painful fast:

  • No table view. You see one page at a time, nested in a tree. Finding a specific record means clicking through folders or memorizing IDs.
  • No inline filters. Want to see only unpublished products from Italy? You're writing a selector in the URL or building a custom admin page from scratch.
  • No bulk actions. Publishing 200 seasonal items means 200 individual saves.
  • No export. Getting your data out requires a custom template or a module.
  • No REST API. Feeding a mobile app or a headless frontend means building endpoints yourself.
  • No role scoping. Every editor sees every page. Limiting a franchisee to their own location's menu requires custom code.

Every ProcessWire developer has solved some version of this problem on every project. Collections solves it once.


What It Does


Collections gives any ProcessWire template a configurable admin table — with live search, dropdown filters, inline status toggles, bulk actions, CSV/JSON export, and a REST API — all configured through a UI, without writing code.

It installs as a dedicated section inside the ProcessWire admin. Editors get a professional, responsive interface. Developers get a REST API with zero boilerplate.


Real-World Use Cases


Product catalog (e-commerce) A spirits retailer manages 12,000+ products across ABV, country, region, brand, SKU, and size variants. Collections provides a filterable table where buyers bulk-publish seasonal items, export the filtered view to CSV for distributors, and jump to edit any row — without leaving the list.

Property listings (real estate) An agency runs listings across multiple cities. Each agent sees only their own listings via the permissions matrix and a created_by selector. The manager sees everything and exports weekly JSON reports fed to a mobile app through the built-in REST API.

Job board / HR A company posts vacancies across departments. HR manages the full board; department heads see only their own roles. When a hiring round closes, one bulk action archives the filled positions. Status dots show at a glance what's live and what's in draft.

Restaurant chain / franchise A franchise with 40 locations manages its menu centrally. Each location's menu is a separate collection scoped by a selector. The head chef publishes globally; location managers toggle availability for their own restaurant only — same module, different permission roles.

Media / editorial A magazine team of writers and editors. Writers see their own drafts; editors see everything. Publish status is inline — no need to open each article. Bulk-scheduling a campaign batch takes seconds.

SaaS client portal A B2B platform manages client projects as ProcessWire pages. Each account manager sees only their client records. The REST API feeds a React dashboard with paginated, filtered data using Bearer token auth.

Headless CMS with Next.js / Nuxt / SvelteKit ProcessWire as the content backend, Collections as the REST layer. Frontend frameworks fetch data from /api/products/?filter[category]=42&sort=modified&dir=desc. No custom API templates needed.

Mobile app backend iOS/Android apps consume the Collections API. API keys with expiration dates and usage tracking provide per-app access control. The /schema/ endpoint lets the app self-describe available fields without hardcoding.


Features


Admin UI

  • Configurable table columns per collection with custom labels
  • Live search with 300ms debounce, multi-field, including Page reference fields
  • Dropdown filters for FieldtypePage and FieldtypeOptions fields
  • Inline status toggle (publish / unpublish) via AJAX — no page reload
  • Clickable rows with visual selection highlight themed to --pw-main-color
  • Bulk actions: publish, unpublish, delete with CSRF protection
  • Quick delete button per row (optional)
  • Collapsible sidebar with persistent state (localStorage)
  • "View in Collection" button injected into each page's edit form
  • Admin UI colors adapt to ProcessWire's --pw-main-color theme variable

Data

  • CSV and JSON export with current search/filter state preserved
  • Configuration export / import as JSON
  • Role-based permissions matrix (global and per-collection)

REST API

  • Bearer token, query param (?api_key=), HTTP Basic Auth, and PW session
  • API key management with optional expiration dates and per-key capability scopes
  • SHA-256 hashed keys — raw key shown only once on creation
  • Usage tracking: last used timestamp, request count
  • Rate limit: 100 requests/minute per IP per collection (HTTP 429 on excess)
  • WireCache support for GET responses (configurable TTL)

Field Types Supported Text, Textarea, Integer, Float, Checkbox, URL, Email, Color (hex), Date/Datetime, Image, File, FieldtypeFileB2, FieldtypePage (single and multi), FieldtypeOptions, MapMarker, Profields Table, Profields Textareas, Profields Multiplier, Profields Repeater Matrix, Profields Combo

Dot-notation column syntax Subfields of composite ProFields can be addressed directly in the Columns setting using field.subfield notation. The renderer auto-detects field types at each level — no type prefix needed.

SyntaxField typeResult
address.cityComboSingle subfield value
address.typeCombo (Radio)Resolved label (e.g. breweryBrewery)
address.certificationCombo (Checkboxes)All selected labels joined with ,
blocks.titleRepeater MatrixSubfield from first item (any type)
blocks.hero.titleRepeater MatrixSubfield from first item of type hero
blocks.hero.imageRepeater MatrixThumbnail from typed item
media.property_photos.photosMatrix → RepeaterFirst Repeater item's image field
media.property_photos.photos_categoryMatrix → RepeaterFirst Repeater item's Options field
media.photo.property_photos.photosMatrix[type] → RepeaterTyped Matrix item → Repeater → subfield
prices.amountTableColumn value from first row
prices.*.amountTableAll rows' amount values, joined with ,
options.*.wine.colorMatrix (wildcard)color from all items of type wine, joined
options.*.titleMatrix (wildcard)title from all items regardless of type

Installation


  1. Copy the Collections/ folder to site/modules/
  2. In the admin go to Modules → Refresh
  3. Install CollectionsProcessCollections installs automatically
  4. Go to Admin → Collections → Configure to create your first collection

Quick Start


Go to Admin → Collections → Configure, click New Collection and fill in:

FieldExampleNotes
KeyproductsLowercase slug, URL-safe, unique
LabelProductsDisplay name in sidebar and header
TemplateproductProcessWire template name
Selectorparent.name=shopOptional extra PW selector to scope results
Columnstitle, sku, brand, country, modifiedComma-separated field names
Search fieldstitle, skuFields queried by the search bar
Sort bytitleDefault sort field
Sort dirascasc or desc
Per page40Overrides global default (0 = use global)
GroupcontentSidebar group label
Iconfa-boxFontAwesome 4 icon class

Global Settings


Admin → Collections → Configure → Global Settings

SettingDefaultDescription
Show ID columnonPrepends the page id to every table
Show Status columnonColored dot: green=published, red=unpublished, yellow=hidden
Show Name columnoffPage name (URL slug)
Inline status toggleonPublish/unpublish without leaving the list
Quick delete buttonoffTrash icon in each row's action column
Confirm batch deleteonConfirmation dialog before bulk delete
Live searchonSearch fires as you type (300ms debounce)
Min search length2Minimum characters before search fires
Default per page25Rows per page when collection doesn't override
Date formatM j, YPHP date() format string for date fields
Thumbnail size32 × 32Width × height of image thumbnails in the table (32–128 px)
Enable REST APIoffMust be enabled to use any API endpoint
API base path/api/URL prefix for all endpoints
Enable API cacheoffCaches GET responses using WireCache
Cache TTL300Cache lifetime in seconds

REST API


Full API reference and code examples for cURL, JavaScript, PHP, Python, Next.js, and React Query are in API.md.


Permissions


Permission slugDescription
collections-viewView collection pages and use the table UI
collections-createCreate new pages via admin or API
collections-editEdit pages, toggle status, bulk publish/unpublish
collections-deleteDelete pages individually or in bulk
collections-configureAccess the Configure tab, create/delete collections
collections-exportExport collection data as CSV or JSON

Assign permissions to roles under Access → Roles in ProcessWire, then configure which roles have which capabilities per collection under Configure → Permissions.


Database Tables


Four custom tables are created on install and dropped on uninstall:

TableContents
collections_itemsCollection definitions stored as JSON rows
collections_globalGlobal settings as key/value pairs
collections_permissionsRole capability matrix (JSON per role)
collections_api_keysAPI keys — SHA-256 hash, prefix, expiry, usage stats

File Structure


Collections/
 Collections.module.php          Autoload module — hooks, API routing, cache invalidation
 ProcessCollections.module.php   Admin Process — UI, bulk actions, configure
 src/
   Collection.php                Value object + PW selector builder
   CollectionConfig.php          DB-backed settings storage (4 tables)
   CollectionRenderer.php        HTML table + row renderer, ProFields support
   CollectionQuery.php           PW selector query execution + pagination
   CollectionPermissions.php     Role + capability permission checks
   CollectionExporter.php        CSV / JSON streaming export
   QueryParams.php               QueryParams + QueryResult value objects
   Api/
     CollectionApiRouter.php     REST router + rate limiter (100 req/min)
     CollectionApiHandler.php    CRUD handlers + field serialization
     CollectionApiResponse.php   JSON response wrapper
 views/
   layout.php                    Sidenav + main layout wrapper
   dashboard.php                 Dashboard with collection cards + counts
   collection-list.php           Collection table view + bulk bar
   configure.php                 Configure UI — collections, global, API, permissions, import/export
   partials/
     toolbar.php                 Search input + filter dropdowns
     pagination.php              Pagination widget
 assets/
   collections.js                Live search, AJAX toggle, bulk actions, row selection
   collections.css               Layout, table, sidebar, bulk bar, dark mode theming
 install/
   permissions.php               Creates 6 PW permissions on install
 API.md
 CHANGELOG.md
 README.md

Changelog


See CHANGELOG.md.


Author


Maxim Semenov
smnv.org · maxim@smnv.org
GitHub: github.com/mxmsmnv/Collections

More modules by Maxim Semenov

  • Context

    Export ProcessWire site context for AI development (JSON + TOON formats)
  • WireWall

    Advanced traffic firewall with VPN/Proxy/Tor detection, rate limiting, and JS challenge
  • LQRS URL Shortener Profile

    This site profile for ProcessWire offers a free and easy-to-use URL shortener that transforms long links into concise, shareable URLs. It is built using standard ProcessWire modules and field types.
  • Media Platform Profile

    This site profile for ProcessWire offers a fully-featured media platform for hosting and managing video content with Backblaze B2 and Cloudflare integration.
  • Page Markdown

    Export any page to a clean Markdown file. Adds an export button to the page editor.
  • Subscribe

    Newsletter subscription handler with lists, double opt-in, honeypot, rate limiting and unsubscribe link.
  • Plausible Analytics

    Plausible Analytics dashboard using Stats API v2 with page-edit widget, traffic trends chart, and geo/device tabs.
  • AiWire

    AI integration for ProcessWire. Supports Anthropic, OpenAI, Google, xAI, and OpenRouter.
  • AgeWire

    Age verification module with Tailwind CSS support

All modules by Maxim Semenov

Install and use modules at your own risk. Always have a site and database backup before installing new modules.