v0.6.0-alpha — customer-ready foundation
Pre-releasehooked on facets v0.6.0-alpha — customer-ready foundation
Sixth alpha. Four pieces of plumbing that close the gap between "cool demo" and "real customer can actually run a store on this." Not glamorous; absolutely blocking. All four shipped in one push.
⌨️ WP-CLI
The commands every WordPress admin expects:
wp hof reindex # full reindex with progress bar
wp hof reindex --post=42 # single object
wp hof status [--format=json] # index stats: rows, distinct IDs, by-facet breakdown
wp hof facets [--format=json] # list configured facetsRegistered on cli_init so the class only loads in the CLI context — no overhead in normal page loads.
📅 Date Range indexer
Previously the Date Range display shipped but the indexer didn't actually do anything date-aware. v0.6 fixes that: when a facet has display: "date_range", string values from meta or post fields run through strtotime() at index time and the resulting epoch lands in facet_numeric. The existing range resolver path then serves date queries unchanged.
Verified end-to-end on the docker dataset:
post_date_string facet_numeric FROM_UNIXTIME(facet_numeric)
2026-05-15 03:46:17 1778816777 2026-05-15 03:46:17 ← perfect round-trip
Numeric values (existing epoch storage) pass through unchanged. Unparseable strings yield NULL so a single bad row can't poison the index.
🛒 WooCommerce first-class integration
The Facets admin grows a + WooCommerce facets button (visible when Woo is active). One click → suggests sensible facets based on what your store actually has:
| If the store has… | Suggest |
|---|---|
product_cat with terms |
Category (hierarchy) |
product_tag with terms |
Tags (checkbox) |
pa_color with terms |
Color (swatch if term_meta has swatch_color, else checkbox) |
pa_size with terms |
Size (radio) |
pa_brand with terms |
Brand (dropdown) |
Any other pa_* attribute |
(checkbox, auto-named) |
_price in postmeta |
Price (range) |
_stock_status in postmeta |
In stock only (toggle, true_value="instock") |
_featured in postmeta |
Featured (toggle, true_value="yes") |
Only suggests facets the store actually has data for — empty taxonomies and unused meta keys are skipped. New REST endpoint: GET /wp-json/hof/v1/integrations/woocommerce/suggest.
⚙️ Background reindex via wp_cron chunking
The synchronous reindex_all() is fine for catalogs under ~10k products. Past that, the admin button starts timing out PHP-FPM. v0.6 adds:
Indexer::queue_reindex_all()— truncates the index, counts total objects, persists job state inwp_options, schedules the first chunk event on the next cron tick.Indexer::run_background_chunk()— handles one chunk (default 200 posts) and re-schedules the next until done. Each chunk reuses the bulk-rebuild pipeline so it's not slower than the synchronous path; just non-blocking. Visual DNA palette extraction runs per chunk too.REST /reindex— defaults tomode=background(returns 202 with a job descriptor).mode=syncpreserves the original behavior. Auto-falls-back to sync whenDISABLE_WP_CRONis set.REST /reindex/status— now includes abackgroundblock:{job_id, total, done_posts, chunks, done_chunks, percent, running, started_at, finished_at}.
Verified: queued a 100,008-object reindex in 201 chunks; first chunk advanced state to done_posts: 500, percent: 0.5%, running: true.
🆙 Upgrade from v0.5.0-alpha
Drop-in. No schema changes. The first admin-button reindex after upgrade defaults to background mode — your screen returns instantly; check progress via wp hof status or the admin Indexer page.
Still in the box
Everything from v0.5.0-alpha continues to work: the licensing scaffold, ten public facet displays, three view facets (2D Slider, Ask, Visual DNA v3), admin CRUD with drag-reorder + validation, BYOK Anthropic for Ask.
Next up
- Documentation pass (Getting Started / Quick Start / Hook reference)
- Page-builder verification (smoke-test the shortcode inside Elementor / Bricks / Divi / Breakdance / Oxygen)
- Live EDD store at hookedonfacets.com so the licensing scaffold becomes a real "buy a key" flow
Feedback
Issues, PRs, "this didn't work for me" reports — all welcome.