Skip to content

Releases: mxmsmnv/Collections

1.9.5

28 Jun 23:51

Choose a tag to compare

Fixed

  • published system field now uses the configured date formatter in collection tables, matching created and modified.

Thanks to Torsten Baldes (@tobaco) for PR #2.

1.9.4

28 Jun 23:49

Choose a tag to compare

Added

  • User-definable collection groups: the Group control in Configure is now a text input with suggestions for content, taxonomy, custom, plus any custom groups already used by existing collections. Custom group names are sanitized with ProcessWire's name sanitizer and fall back to content when empty.

Changed

  • README updated for current collection settings, including custom groups, group name rules, per-collection export toggle, order, related-page search, and the current REST API capability summary.

v1.9.3

08 May 23:56

Choose a tag to compare

1.9.3 — 2026-05-08

Fixed

  • Collection default sort direction ignored$params->sortDir defaults to 'asc' (a non-empty string), so $params->sortDir ?: $collection->sortDir always resolved to 'asc', never falling through to the configured direction. Fixed by checking $input->get('sort') to distinguish an explicit URL sort from the default, and using collection sortBy/sortDir as a pair when no URL sort is present.
  • View icon shown for pages without a template view file — the View action was displayed for any page with a non-empty URL, even when no frontend template file existed, resulting in a 404 on click. Now gated behind $page->viewable().
  • Add button shown when template disallows new pages — the "Add" button appeared regardless of the template's noParents setting. Added canAddNew() to Collection which returns false when noParents = 1 (no new pages) or noParents = -1 and a page with that template already exists (singleton).

Added

  • Sort indicator in selector note — the Selector: details block now shows the active sort field and direction inline (e.g. · Sort: created DESC), reflecting either the URL override or the collection default.

v1.9.2

04 May 04:22

Choose a tag to compare

1.9.2 — 2026-05-03

Fixed

  • FieldtypeDatetime / FieldtypeDate showing unix timestamp — date fields were only formatted when the column type was explicitly set to date in collection settings. Now auto-detected by $ftName so any datetime field renders correctly with the configured date format without manual override.
  • created / modified system fields showing unix timestamp — PW system fields created and modified were not handled in renderCellValue() and fell through to the generic scalar renderer, outputting a raw integer. Now explicitly caught before field lookup and passed through formatDate().
  • Filter dropdowns not applyingfetchTable() in collections.js used new URLSearchParams(params).toString() which percent-encodes [ and ] as %5B%5D. PHP's array parsing requires literal brackets in filter[field]=value, so $input->get('filter') returned null instead of an array. Query string is now built manually to keep brackets unencoded.
  • API log growing unbounded in production — every API request and API key authentication wrote a line to the collections log regardless of environment. Both log->save() calls are now gated behind $this->wire('config')->debug, so logs are only written when Tracy / debug mode is active.
  • Apply button not appearing when typing in search field — the Apply button was only rendered inside the if (!empty($filterOptions)) block, so it was absent from the DOM on collections without filter dropdowns, making showApplyBtn() a no-op. Button is now rendered unconditionally (always hidden by default) outside the filters block.
  • Search input input event never firinggetElementById('collections-search-input') and other direct DOM lookups ran at script parse time, before the DOM was ready (script loaded via $config->scripts->add() in <head>). All DOM-dependent initialisation is now wrapped in DOMContentLoaded handlers.
  • Pressing Enter in search field losing active filters — the search form submitted natively, discarding filter dropdown values that were applied via AJAX (hidden inputs in the form are server-rendered and not updated on the client). Form submit is now intercepted and routed through fetchTable, identical to clicking Apply.
  • Clear button absent when filters restored from localStorage — the Clear button was PHP-rendered only when $params had active filters, so on a clean page load it was missing from the DOM entirely. It is now always rendered (hidden by default) and shown/hidden via JS alongside the Apply button.
  • Apply button not shown after localStorage restorerestoreFilterState() restored UI controls and called fetchTable but never called showApplyBtn(), leaving the button hidden despite active filters being present.

Added

  • Persistent filter state per collection — search query and filter dropdown values are saved to localStorage under collections_filters_{col} after every successful table fetch. On page load, if the URL carries no active filters, the saved state is restored and the table is re-fetched automatically. Clicking Clear wipes the saved state so nothing is restored on the next visit.

v1.9.1 — ProFields deep rendering, dot-notation, thumbnail settings

25 Apr 05:50

Choose a tag to compare

1.9.1 — 2026-04-25

Added

  • Thumbnail size setting — Global Settings now has a Width × Height input (32–128 px) for preview thumbnails. Previously hardcoded to 32×32. Value stored in collections_global as thumb_width / thumb_height.
  • matrixTypeName() helper — safe internal method for reading the matrix type name from a RepeaterMatrixPage. Falls back to reading repeater_matrix_type integer from the field config when the matrix() hook method is unavailable in the current context.
  • matrixTypeN() helper — companion to matrixTypeName(), returns the matrix type integer index.
  • resolveRepeater() helper — normalises a Repeater field value that PW returns as an integer page ID into a RepeaterPageArray by loading the container page and calling ->children().
  • Matrix → Repeater → subfield path — dot-notation now resolves three-segment paths where the middle segment is a Repeater field on a Matrix item rather than a type name (e.g. media.property_photos.photos).
  • Combo Checkboxes array support in dot-notationrenderDotNotation now resolves array values (multi-select Checkboxes subfields) through resolveComboOptionLabel() and joins them with , .

Fixed

  • RepeaterMatrixPageArray intercepted by instanceof PageArrayFieldtypeRepeaterMatrix dispatch was placed after the generic PageArray check, so matrix fields were rendered as plain page-reference arrays. Matrix branch is now checked first.
  • matrix() hook not callablemethod_exists() and hasMethod() both fail for the matrix() hook method on RepeaterMatrixPage in the renderer context. Replaced with matrixTypeName() helper that catches exceptions and falls back to getUnformatted('repeater_matrix_type').
  • getUnformatted() on RepeaterMatrix returns raw IDsrenderCellValue() and renderDotNotation() now use $page->get() (formatted) for FieldtypeRepeaterMatrix and FieldtypeRepeater fields.
  • Pageimages cast to string showing filenamesrenderScalarOrObject() now uses fully-qualified \ProcessWire\Pageimage / \ProcessWire\Pageimages class names and adds an is_object() trap as final guard.
  • SelectableOptionArray rendering 1 instead of label — now explicitly dispatched to renderOptions() before the WireArray check.
  • Array to string warning from non-searchable ProField columns — all non-searchable types (FieldtypeTable, FieldtypeRepeaterMatrix, FieldtypeCombo, etc.) now excluded from buildSelector().

Changed

  • Sidebar group order — groups now render in fixed order: Content → Taxonomy → Custom. Applies to both the sidebar nav and the dashboard grid.
  • renderScalarOrObject() — all instanceof checks now use fully-qualified \ProcessWire\* class names.

v1.9.0

24 Apr 02:07

Choose a tag to compare

feat: add ProFields Repeater Matrix and Combo support, dot-notation c…

v1.8.2

09 Apr 23:28

Choose a tag to compare

Changelog

1.8.2 — 2026-04-09

Changed

  • CSS fully migrated to UIkit design system variables — all hardcoded colors replaced with --pw-* CSS custom properties from AdminThemeUikit. Dark mode now works automatically. Affected variables: --pw-blocks-background, --pw-inputs-background, --pw-border-color, --pw-muted-color, --pw-text-color, --pw-main-background, --pw-error-inline-text-color. All fallback values preserved for environments where variables are not defined.

1.8.1 — 2026-04-07

Fixed

  • Default sort not applied on first loadsortBy/sortDir from collection settings were only applied when per_page was absent from URL. Now always applied as fallback when not explicitly set in request params.
  • Default sort direction ignoredQueryParams::fromInput returned 'asc' as hardcoded default for dir, preventing collection's sortDir from taking effect. Now returns empty string so collection default wins.
  • Filter dropdowns not firing — used querySelectorAll at script load time before DOM was ready. Replaced with document.addEventListener('change') event delegation.
  • Export ignores active filters — export links now include all current filter[] and q params. Export links also update dynamically after AJAX table refresh.
  • Array to string warningPageArray::each('id') returns array in PW 3.0.240+. Now explicitly converted to pipe-separated string.

Added

  • "Search in related page titles" option per collection — controls whether Page reference columns are automatically included in search. Enabled by default (existing behavior preserved). Can be disabled per collection in Configure.

1.8 — 2026-04-05

Fixed

  • Admin hooks not firingaddCollectionLink and addPageListAction hooks moved from init() to ready(), where $page is fully resolved. Caused "View in Collection" buttons to disappear after module update.
  • Bulk actions failing with WireCSRFExceptionsubmitBulk() now posts to location.pathname + location.search preserving ?col=key, which was silently dropped before, causing the server to lose collection context.
  • CSRF token mismatch on bulk/delete — replaced double getTokenName()/getTokenValue() calls (which could reset the token) with a single renderInput() call; token name and value now extracted once server-side and passed to JS.
  • Quick delete JSON parse error — row-level delete was calling the REST API without auth headers, receiving an HTML 401 response instead of JSON. Now uses the same form POST mechanism as bulk actions.
  • API tab redirect after key create/delete — was redirecting to ?configure=1 (Collections tab); now redirects to ?configure=1#tab-api.

Changed

  • Action icons replaced — all FontAwesome icons in the table action column replaced with inline SVG (Heroicons solid + Bootstrap Icons): pencil for edit, eye for view, check-circle/x-circle for status toggle, trash for delete. Fixes invisible icons caused by FontAwesome CSS overriding SVG dimensions.
  • Thead styled with --pw-main-color — table header background uses a 15% tint of the ProcessWire theme color; text and icons use the full theme color. Adapts automatically to any AdminThemeUikit color scheme.
  • Clickable rows — clicking anywhere on a table row toggles its checkbox. Interactive elements (links, buttons, inputs) are excluded.
  • Row selection highlight — selected rows get a color-mix tint of --pw-main-color at 8%; hover on selected rows at 13%.
  • sticky_header setting removed — the sticky header feature was unreliable due to ProcessWire AdminTheme's scroll container blocking CSS position: sticky. Setting removed from Global Settings UI and defaults.
  • Configure page icons — View/Edit/Delete text buttons in the collection list replaced with Heroicons SVG icons. API key delete button also updated.

Added

  • getCsrf() helper in collections.js — reads CSRF token from #collections-csrf hidden input at submit time, used by both bulk form and quick delete.
  • row-selected CSS class — toggled on <tr> when checkbox is checked/unchecked, including select-all and cancel actions.

1.7 — 2026-03-28

Initial release.

  • Configurable collections backed by custom MySQL tables
  • Table UI with sortable columns, live search, pagination
  • Inline status toggle via AJAX
  • Bulk publish / unpublish / delete
  • CSV and JSON export
  • REST API: list, show, create, update, delete, bulk, schema, export
  • API key management with SHA-256 hashing and expiration
  • Role-based permissions matrix (global and per-collection)
  • Collapsible sidebar with persistent state
  • Configuration export / import
  • Supports: Text, Textarea, Image, File, Page reference, Options, Checkbox, Color, URL, Email, MapMarker, Profields Table/Textareas/Multiplier
  • Integration hooks on page edit and page list
  • Cache invalidation on page save/delete

v1.8.1

08 Apr 02:20

Choose a tag to compare

Changelog

1.8.1 — 2026-04-07

Fixed

  • Default sort not applied on first loadsortBy/sortDir from collection settings were only applied when per_page was absent from URL. Now always applied as fallback when not explicitly set in request params.
  • Default sort direction ignoredQueryParams::fromInput returned 'asc' as hardcoded default for dir, preventing collection's sortDir from taking effect. Now returns empty string so collection default wins.
  • Filter dropdowns not firing — used querySelectorAll at script load time before DOM was ready. Replaced with document.addEventListener('change') event delegation.
  • Export ignores active filters — export links now include all current filter[] and q params. Export links also update dynamically after AJAX table refresh.
  • Array to string warningPageArray::each('id') returns array in PW 3.0.240+. Now explicitly converted to pipe-separated string.

Added

  • "Search in related page titles" option per collection — controls whether Page reference columns are automatically included in search. Enabled by default (existing behavior preserved). Can be disabled per collection in Configure.

1.8 — 2026-04-05

Fixed

  • Admin hooks not firingaddCollectionLink and addPageListAction hooks moved from init() to ready(), where $page is fully resolved. Caused "View in Collection" buttons to disappear after module update.
  • Bulk actions failing with WireCSRFExceptionsubmitBulk() now posts to location.pathname + location.search preserving ?col=key, which was silently dropped before, causing the server to lose collection context.
  • CSRF token mismatch on bulk/delete — replaced double getTokenName()/getTokenValue() calls (which could reset the token) with a single renderInput() call; token name and value now extracted once server-side and passed to JS.
  • Quick delete JSON parse error — row-level delete was calling the REST API without auth headers, receiving an HTML 401 response instead of JSON. Now uses the same form POST mechanism as bulk actions.
  • API tab redirect after key create/delete — was redirecting to ?configure=1 (Collections tab); now redirects to ?configure=1#tab-api.

Changed

  • Action icons replaced — all FontAwesome icons in the table action column replaced with inline SVG (Heroicons solid + Bootstrap Icons): pencil for edit, eye for view, check-circle/x-circle for status toggle, trash for delete. Fixes invisible icons caused by FontAwesome CSS overriding SVG dimensions.
  • Thead styled with --pw-main-color — table header background uses a 15% tint of the ProcessWire theme color; text and icons use the full theme color. Adapts automatically to any AdminThemeUikit color scheme.
  • Clickable rows — clicking anywhere on a table row toggles its checkbox. Interactive elements (links, buttons, inputs) are excluded.
  • Row selection highlight — selected rows get a color-mix tint of --pw-main-color at 8%; hover on selected rows at 13%.
  • sticky_header setting removed — the sticky header feature was unreliable due to ProcessWire AdminTheme's scroll container blocking CSS position: sticky. Setting removed from Global Settings UI and defaults.
  • Configure page icons — View/Edit/Delete text buttons in the collection list replaced with Heroicons SVG icons. API key delete button also updated.

Added

  • getCsrf() helper in collections.js — reads CSRF token from #collections-csrf hidden input at submit time, used by both bulk form and quick delete.
  • row-selected CSS class — toggled on <tr> when checkbox is checked/unchecked, including select-all and cancel actions.

1.7 — 2026-03-28

Initial release.

  • Configurable collections backed by custom MySQL tables
  • Table UI with sortable columns, live search, pagination
  • Inline status toggle via AJAX
  • Bulk publish / unpublish / delete
  • CSV and JSON export
  • REST API: list, show, create, update, delete, bulk, schema, export
  • API key management with SHA-256 hashing and expiration
  • Role-based permissions matrix (global and per-collection)
  • Collapsible sidebar with persistent state
  • Configuration export / import
  • Supports: Text, Textarea, Image, File, Page reference, Options, Checkbox, Color, URL, Email, MapMarker, Profields Table/Textareas/Multiplier
  • Integration hooks on page edit and page list
  • Cache invalidation on page save/delete

v1.8

07 Apr 02:34

Choose a tag to compare

Changelog

1.8 — 2026-04-05

Fixed

  • Admin hooks not firingaddCollectionLink and addPageListAction hooks moved from init() to ready(), where $page is fully resolved. Caused "View in Collection" buttons to disappear after module update.
  • Bulk actions failing with WireCSRFExceptionsubmitBulk() now posts to location.pathname + location.search preserving ?col=key, which was silently dropped before, causing the server to lose collection context.
  • CSRF token mismatch on bulk/delete — replaced double getTokenName()/getTokenValue() calls (which could reset the token) with a single renderInput() call; token name and value now extracted once server-side and passed to JS.
  • Quick delete JSON parse error — row-level delete was calling the REST API without auth headers, receiving an HTML 401 response instead of JSON. Now uses the same form POST mechanism as bulk actions.
  • API tab redirect after key create/delete — was redirecting to ?configure=1 (Collections tab); now redirects to ?configure=1#tab-api.

Changed

  • Action icons replaced — all FontAwesome icons in the table action column replaced with inline SVG (Heroicons solid + Bootstrap Icons): pencil for edit, eye for view, check-circle/x-circle for status toggle, trash for delete. Fixes invisible icons caused by FontAwesome CSS overriding SVG dimensions.
  • Thead styled with --pw-main-color — table header background uses a 15% tint of the ProcessWire theme color; text and icons use the full theme color. Adapts automatically to any AdminThemeUikit color scheme.
  • Clickable rows — clicking anywhere on a table row toggles its checkbox. Interactive elements (links, buttons, inputs) are excluded.
  • Row selection highlight — selected rows get a color-mix tint of --pw-main-color at 8%; hover on selected rows at 13%.
  • sticky_header setting removed — the sticky header feature was unreliable due to ProcessWire AdminTheme's scroll container blocking CSS position: sticky. Setting removed from Global Settings UI and defaults.
  • Configure page icons — View/Edit/Delete text buttons in the collection list replaced with Heroicons SVG icons. API key delete button also updated.

Added

  • getCsrf() helper in collections.js — reads CSRF token from #collections-csrf hidden input at submit time, used by both bulk form and quick delete.
  • row-selected CSS class — toggled on <tr> when checkbox is checked/unchecked, including select-all and cancel actions.

1.7 — 2026-03-28

Initial release.

  • Configurable collections backed by custom MySQL tables
  • Table UI with sortable columns, live search, pagination
  • Inline status toggle via AJAX
  • Bulk publish / unpublish / delete
  • CSV and JSON export
  • REST API: list, show, create, update, delete, bulk, schema, export
  • API key management with SHA-256 hashing and expiration
  • Role-based permissions matrix (global and per-collection)
  • Collapsible sidebar with persistent state
  • Configuration export / import
  • Supports: Text, Textarea, Image, File, Page reference, Options, Checkbox, Color, URL, Email, MapMarker, Profields Table/Textareas/Multiplier
  • Integration hooks on page edit and page list
  • Cache invalidation on page save/delete