Shipping URL Hierarchy Migration Across 8 Live Apps
Just wrapped up a pretty intense migration session that touched both the honeybun-workers and badboothsites codebases. The goal was to move our URL structure from flat slugs to proper hierarchical ones across all verticals.
What Got Done
The big win here was completing template patches for all 9 verticals (plus the _base template). Every single one now uses a "meta-first" approach for extracting slugs - they check for _hb_venue_slug, _hb_city_slug, and _hb_county_slug post meta first, then fall back to the old flat regex pattern for backwards compatibility.
I also added some new helper functions to bbs-config.php: bbs_geo_city_url(), bbs_geo_county_url(), and bbs_geo_venue_url(). These use our DCC cities array plus county_slug meta to build proper hierarchical URLs, with graceful fallback to bare slugs when needed.
The class-vertical-loader.php got extended to handle more page types (service, job, booth, event, sub-event), and all 11 verticals.json files were updated with the new hierarchical slug patterns.
The Deployment Dance
This is where things got real. Had to deploy across all 8 golden apps:
- plumbers, gyms, barbershops, hvac
- medspas, realtors, roofers, electricians
Each one needed the core inc files updated, plus their vertical-specific templates and configs. The _base templates went everywhere since some verticals (hvac, realtors, roofers) don't have their own city/venue/county templates.
Smart Decisions Made
The meta-first approach was key here. Instead of breaking everything, we prioritize the new hb*_slug post meta but keep the legacy flat regex as backup. This means existing pages keep working while new hierarchical pages get the benefits.
Turns out the seo.php breadcrumb logic was already correct - it uses get_permalink() on the WordPress parent chain, so no hardcoded URL prefixes needed. Sometimes the existing code is smarter than you think.
What's Next
Time to actually test this thing end-to-end on a provisioned site with hierarchical pages. Need to make sure the hb-content worker is seeding county data properly in the DCC cities array so those bbs_geo_city_url() calls can resolve hierarchical nearby city links.
The provisioner was already creating the right WordPress page structure with parent/child relationships and post meta. Now the templates actually read and use that data instead of ignoring it.
Pretty satisfying to see a complex migration like this go live across multiple codebases and apps without breaking anything. The backwards compatibility strategy paid off.