Demand Spring – Core
Demand Spring 2026 site — single consolidated WordPress plugin
by Inkline / Demand Spring · github.com/inkline-media/demandspring-core · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/inkline-media/demandspring-core/archive/refs/heads/main.zipSite-wide functionality for the Demand Spring 2026 site. This is a single WordPress plugin that owns:
- Pillared URLs for the
serviceCPT —/services/{pillar}/{slug}/ - Pillared URLs for the
insightCPT —/insights-events/insights/{type}/{slug}/ - Rewrite rules so the
/services/{pillar}/and/insights-events/insights/{type}/filter Pages resolve instead of being shadowed by the CPTs - The Glossary ACF field group (code-defined,
ds_glossary_*namespaced) - Rank Math JSON-LD schema emitter for Glossary entries (
DefinedTerm+FAQPage)
It replaces five legacy demandspring-* plugins that previously shipped these concerns separately.
The full architectural rationale lives in deliverables/Demand Spring 2026 — WordPress Architecture Spec.docx in the main project repo.
Install / update
First install
Download the latest release zip from Releases and upload via Plugins → Add New → Upload Plugin. Activate. The activation hook flushes rewrite rules and runs the one-shot glossary ACF meta-key migration.
Future updates (recommended)
Install Git Updater (the maintained successor to GitHub Updater) once. It adds this repo to WordPress's normal "Updates" screen, so every tagged release here surfaces as a standard plugin update in WP admin. Auto-update can be enabled per the site's policy.
The plugin headers (GitHub Plugin URI, Primary Branch, Release Asset) already point Git Updater at this repo and tell it to pull the release-attached zip rather than the raw branch archive.
For a private repo, configure a Personal Access Token in Git Updater's settings (Settings → Git Updater → GitHub) with repo scope.
Architecture overview
The plugin file is one PHP file, intentionally — easy to read, deploy, and version. It is organized into 8 numbered sections, each preceded by a ========= banner:
| § | Responsibility |
|---|---|
| 1 | Constants (pillar slugs, insight type→URL map, type page slugs) |
| 2 | Service CPT permalinks (filter + rewrite + canonical 301) |
| 3 | Service pillar Page rewrites |
| 4 | Insight CPT permalinks (filter + rewrite + canonical 301) |
| 5 | Insight type-filter Page rewrites |
| 6 | Glossary ACF field group (code-defined, ds_glossary_* namespaced) |
| 7 | Glossary JSON-LD schema (DefinedTerm + FAQPage via rank_math/json_ld filter) |
| 8 | Activation hook: flush rewrites + one-shot ACF meta-key migration |
Naming conventions
- ACF field names:
ds_<cpt>_<fieldname>for CPT-specific (e.g.ds_glossary_short_definition),ds_<fieldname>for cross-CPT. Field keys mirror the same pattern:field_ds_<cpt>_<fieldname>. - PHP constants:
DS_*(e.g.DS_SERVICE_PILLARS). - PHP functions:
ds_*(e.g.ds_service_get_pillar_slug).
The double prefix avoids collisions with third-party plugins and makes ownership obvious when reading wp_postmeta directly.
Activation migration (one-shot)
On first activation, the plugin renames every glossary wp_postmeta row from the legacy un-prefixed keys to ds_glossary_*, including repeater sub-rows. Guarded by the ds_glossary_meta_migrated option flag — runs exactly once. A per-key row count is logged to error_log() and stored in ds_glossary_meta_migrated_summary for review.
Adding a new pillar or insight type
The URL rewrites whitelist known segments to avoid catching unintended traffic. To add a new one:
New service pillar:
- Create the
service_pillartaxonomy term. - Add the slug to
DS_SERVICE_PILLARSin the plugin. - Create the matching
/services/{pillar}/Page. - Deactivate + reactivate the plugin to flush rewrites.
New insight type:
- Create the
insight_typetaxonomy term. - Add the term-slug → URL-segment pair to
DS_INSIGHT_TYPE_URL_MAP. - Add the URL segment to
DS_INSIGHT_TYPE_PAGES. - Create the matching
/insights-events/insights/{type}/Page. - Deactivate + reactivate the plugin to flush rewrites.
Releasing a new version
- Bump the
Version:header indemandspring-core.php. - Commit + push to
main. - Tag the commit:
git tag v1.1.0 && git push origin v1.1.0. - Create a GitHub Release from that tag and attach a zip named
demandspring-core.zipcontaining the plugin directory (usemake releaseif a Makefile is present; otherwise see below).
Building the release zip
mkdir -p dist
git archive --format=zip --prefix=demandspring-core/ HEAD demandspring-core.php > dist/demandspring-core.zip
gh release upload <tag> dist/demandspring-core.zip attaches it to the release.
Sites running Git Updater will see the new release as an available update within ~12 hours (or after a manual "Check for updates" in Dashboard → Updates).
License
Proprietary. © Inkline / Demand Spring. Not for redistribution.