Benson Theatre — Build Spec
The single source of truth for how the rebuild gets built. Plugins, custom post types, ACF schema, and a row-by-row solution for every functional area of the site. If you're an agent picking up this project, read this doc end-to-end before writing code.
Last updated: 2026-05-08
Reminder on terminology: "Membership" on this site means a recurring donation tier (PayPal subscription), NOT an on-site user account. There is no login, no member portal, no gated content. WP user roles exist only for staff/admin. No membership plugin needed.
1. Hosting & infrastructure
| Layer | Decision |
|---|---|
| Local dev | Local by Flywheel, new site benson-theater.local, scaffolded via /local-sites |
| Production hosting | TBD — see Open Decisions below |
| DNS / registrar | GoDaddy (already controlled — Account #35049182) |
Google Workspace — already on aspmx.l.google.com MX records, do not disturb |
|
| CDN | Whatever the host provides (Fastly on Flywheel, Cloudflare on Kinsta) |
| Image CDN | None on rebuild — drop ExactDN/Jetpack from the live site, use the host's built-in image CDN |
2. Theme
| Item | Decision |
|---|---|
| Theme slug | benson-theatre-rebuild (or shorter: bt-rebuild) — must NOT collide with the existing benson-theatre and benson-theatre-child slugs from Shape Society's install, in case both ever land on the same host |
| Stack | G&M Tailwind + ACF boilerplate (per /wordpress-theme-setup skill) |
| CSS scope | Standard G&M .tailwind-scope wrapper (per CLAUDE.md G&M rule) |
| Layout system | .full / .content containers (per /tailwind-layout skill) |
| Module system | ACF Flexible Content + ACFE flex-modal picker (per /wordpress-modules skill) |
| ACF JSON sync | acf-json/ committed to repo (per /wordpress-acf skill) |
| Brand tokens | See BRAND-TOKENS.md |
3. Plugin slate
This is the canonical plugin list. Anything not on this list does NOT get installed unless we explicitly amend this section.
Always-on (G&M + project defaults)
| Plugin | Purpose | Notes |
|---|---|---|
| Advanced Custom Fields Pro | Field groups, flex content, options pages | G&M standard. JSON sync to repo. |
| ACF Extended Pro (ACFE) | Module-picker modal, flex content categories, per-module thumbnails | G&M default UX for ACF flex modules |
| Gravity Forms | All forms (volunteer, student membership signup, contact, booking, press inquiry, group sales, rental quote) | Replacing existing Contact Form 7 + Google Forms. License under G&M's Gravity account. |
| Events Manager Pro | Events CPT + calendar grid view | Per Eric. Replaces the theme-baked custom event CPT on the existing site. |
| Admin Columns Pro | Better admin list views for events + posts | Standard for CPT-heavy projects. |
| Redirection (free) | 301 redirects from old URL paths to new | Critical for SEO recovery. |
| WP-Optimize | DB cleanup, image optimization options | Configure via /wp-optimize skill (Flywheel-aware: page cache OFF, FlyCache handles edge) |
| Yoast SEO (Free) | Titles, meta, sitemap, OG tags, schema | Locked. |
| Imagify | Image optimization | Locked. |
| Wordfence (Free) | Firewall, scanning, login protection | Locked. |
| CookieYes (Free) | Cookie consent banner with Google Consent Mode v2 | Pairs with GA4 install. |
| WP Mail SMTP (Free) | Route Gravity Forms notifications through SendGrid | Wp_mail unreliable on managed hosts. |
Decided 2026-05-08
| Slot | Decision |
|---|---|
| SEO | Yoast SEO (Free) |
| Image optimization | Imagify |
| Visual approach | Fresh take using the existing palette + fonts-equivalent as a starting point. Brand continuity (gold accent, theater poster aesthetic) preserved; design debt and broken pieces dropped. |
| Fonts | Google Fonts: Manrope (replaces Bicyclette) + Caveat (replaces Enchanted). See BRAND-TOKENS.md. |
| Security | Wordfence (Free) |
| Login hardening | Wordfence handles it — no separate plugin (avoids double-enforcement) |
| Backup | Host-native only (Flywheel or Kinsta automatic daily backups; no offsite plugin layer) |
| SVG support | Native — SVG uploads allowed without sanitization. NOTE: per Eric's call. Mitigate by limiting Editor/Author roles' upload scope and trusting only admin-uploaded SVGs. |
| Site search | Built-in WordPress search. Content set is small enough that this is plenty. |
| Analytics | Fresh GA4 only — no Google Tag Manager. Inject gtag.js directly via theme wp_head. New GA4 property under Benson Theatre's account post-Workspace recovery (or G&M's account in the interim). Loses historical data continuity with Shape Society's GTM-WNGJGS6 — accepted tradeoff. |
| Legal docs (Privacy / Terms / Cookie) | Termly free generator → hand-edit for nonprofit specifics. Pages published at /privacy-policy/, /terms-of-use/, /cookie-policy/. Linked from footer. |
| Cookie consent banner | CookieYes Free plugin. Wires into Google Consent Mode v2 paired with GA4. Banner with Accept / Reject / Customize. |
| Calendar UX (iCal feed + Add-to-Calendar buttons) | Skipped — calendar grid + event detail pages alone. No iCal subscribe feed, no per-event Add-to-Calendar buttons. Per Eric. |
Deferred to Jim's working session 2026-05-11
| Slot | Why deferred |
|---|---|
| Newsletter integration | Need Jim to confirm how the current "quarterly insider newsletter" is being sent. If Mailchimp, integrate. If manual Gmail, separate conversation. Build placeholder footer signup (no live integration) until decision lands. |
| Bar / Catering Room / Tech pages | KEEP/KILL/MERGE call lives in Jim's session. Default-stage as "keep" until then. |
| Day-to-day site admin | Likely Miranda Hindman (new GM, hired April 2026), but defer to confirm with Jim. Affects training plan + when Admin Columns Pro setup matters. |
NOT installing (explicit "no")
| Plugin | Why no |
|---|---|
| Membership plugins (Paid Memberships Pro, MemberPress, WooCommerce Subscriptions) | "Membership" on this site = donation tier, NOT on-site account. PayPal handles the subscription billing, no plugin needed on WP. |
| Contact Form 7 | Replaced by Gravity Forms |
| Jetpack | Don't need ExactDN once we're off Flywheel-with-Jetpack. Drops weight + reduces 3rd-party load. |
| ajax-search-lite (wpDreams ASL) | Not worth the JS bloat for a site this size. Built-in or upgrade to SearchWP if needed. |
| add-to-any | Replace with hand-built share links in theme footer/single templates (5 lines of HTML) |
| pixll-blocks, visual-link-preview | Custom Gutenberg blocks from Shape Society's setup. Not migrating. |
| ewww-image-optimizer | Replacing with whichever optimization plugin Eric picks (Imagify default) |
| accessiBe / UserWay overlay tools | Cost-justified for revenue sites, not for a small nonprofit with no scoped budget. Build accessibility correctly into the theme instead. |
4. Custom post types
| CPT | Source | Used for | Slug | Notes |
|---|---|---|---|---|
| Posts (built-in) | WP core | News + Press editorial content | /news/, /press/ (via category templates) |
Use existing core categories bt-news and bt-press. No new CPT. |
| Pages (built-in) | WP core | Static pages (About, History, Donate, Memberships, etc.) | / | No new CPT. |
event |
Events Manager Pro | Single events on the calendar | /event/[slug] |
Plugin owns the schema. We add ACF fields via Events Manager's hooks if we need extras (Buy Tickets URL, etc.). |
| None other | — | — | — | Resist the urge. Memberships, Volunteer slots, Tickets — all of these have non-CPT solutions. |
Why no extra CPTs
- News + Press can live as standard Posts with the existing category split. Avoids multiple "post-like" content types in admin.
- Memberships are static page content with PayPal CTA buttons — no entries to manage.
- Volunteer applications are Gravity Forms entries — no CPT needed.
- Press hits / outbound editorial mentions could be a CPT but are rare enough to be page-managed initially. Revisit only if the press list grows past ~20 items.
5. ACF field schema
Event (extending Events Manager Pro)
| Field | Type | Notes |
|---|---|---|
event_buy_url |
Text (NOT acf URL — per CLAUDE.md anti-pattern) | The "Buy Tickets" CTA link |
event_buy_label |
Text | Optional override for the button label (default: "Buy Tickets"). Used for things like "Free — Reserve a Seat" |
event_short_description |
Textarea | Card teaser (used on listing pages) |
event_long_description |
WYSIWYG | Full event detail body |
event_age_restriction |
Select | None / All ages / 18+ / 21+ |
event_doors_time |
Text | E.g. "7pm doors / 8pm show" |
Site settings (ACF Options page)
| Field | Type | Notes |
|---|---|---|
org_phone |
Text | 402.991.4333 |
org_email_public |
info@bensontheatre.org | |
org_email_volunteer |
volunteer@bensontheatre.org | |
org_email_booking |
booking@bensontheatre.org | |
org_address |
Textarea | 6054 Maple Street, Omaha, NE 68104 |
social_instagram_url |
URL-text | |
social_facebook_url |
URL-text | |
social_twitter_url |
URL-text | |
paypal_donate_button_id |
Text | ZDRQZF6C3GXFY (hosted button ID) |
recognition_badges |
Repeater | NAM Proud Member, Candid Platinum Seal 2024 (per badge: image, alt, link) |
footer_lead_copy |
Textarea | Mission statement / tagline |
donation_pitch |
WYSIWYG | Reusable pitch copy |
Membership tiers (ACF Options page — repeater)
Per the CLAUDE.md anti-pattern note: don't hardcode tier definitions in PHP — make them editable in admin.
| Field | Type | Notes |
|---|---|---|
tier_name |
Text | e.g. "Advocate" |
tier_price_label |
Text | e.g. "$60/year ($5/month)" |
tier_paypal_url |
Text | The PayPal subscription URL with plan_id |
tier_blurb |
Textarea | Short description |
tier_includes |
WYSIWYG | What's included (bullet list) |
tier_is_free |
True/False | Marks the Student tier — uses Gravity Form instead of PayPal URL |
tier_form_id |
Number | If tier_is_free, the Gravity Form ID for the signup |
Page modules (ACF Flexible Content — page_modules field)
Standard G&M modules per /wordpress-modules skill. Initial set (expand as design needs):
- Hero (text + image variants)
- Two-column text + image
- Quote / pullquote
- Image gallery
- CTA banner
- Events feed (auto-populated from Events Manager)
- News/Press feed (auto-populated)
- PayPal donate CTA card
- Membership tier grid
- Sponsor / partner logo grid
- Recognition badge strip
- Embed (YouTube / Vimeo)
- Spacer
6. Functional area solutions matrix
Every part of the site has a row here. If a row says TBD, that's an Open Decision below.
| Functional area | Solution |
|---|---|
| Static pages (About, History, Donate, Memberships, Booking, Education, etc.) | WP Pages + ACF flex modules. Content sourced from site-scrape/pages/. |
| News + Press editorial articles | Built-in Posts with categories bt-news, bt-press. Archives at /news/ + /press/ via custom category templates. |
| Events single page | Events Manager Pro event CPT + custom single template single-event.php |
| Calendar grid (month view) | Events Manager Pro built-in calendar block / shortcode, themed in our CSS |
| Events list / archive | Custom archive template archive-event.php, queries the EM Pro CPT |
| Buy Tickets CTA per event | ACF text field event_buy_url rendered as a <a target="_blank" rel="noopener"> button |
| Volunteer application | Gravity Forms — embed on /volunteer page. Notifications to volunteer@ + admin@bensontheatre.org. |
| Free Student "membership" signup | Gravity Forms — embed on /memberships page in the Student tier card. Notifications to admin@. Replaces the existing Google Form. |
| Paid membership tier signup (Advocate, Associate, Stagehand, Artist, Producer, Director's Circle) | PayPal subscription buttons. Each tier card on the memberships page links to its existing PayPal subscription URL with the existing plan_id. No on-site account — donor goes to PayPal, completes checkout, gets perks via newsletter list / ticket discount codes (offline). |
| One-time donations | PayPal hosted button (button ID ZDRQZF6C3GXFY). Single "Donate" CTA on the donate page. |
| General contact form | Gravity Forms — new Contact form, embed on /contact page (page didn't exist on old site, adding) |
| Booking inquiry form | Gravity Forms — Booking Inquiry form on /booking-information page. Notifications to booking@. |
| Newsletter signup | TBD — see Open Decisions |
| Site search | TBD — see Open Decisions |
| Social share buttons | Hand-built <a> tags for Facebook / Twitter share intents. Optional: drop entirely if Jim doesn't care. |
| Image optimization | TBD — see Open Decisions |
| SEO (titles, meta descriptions, sitemap, OG tags) | TBD — see Open Decisions |
| Security (firewall, login hardening) | TBD — see Open Decisions |
| Backup | TBD — see Open Decisions |
| Caching | WP-Optimize for DB cleanup. Page cache handled by host (FlyCache on Flywheel, Edge Cache on Kinsta). |
| 301 redirects from old URLs | Redirection plugin. Map every URL in site-scrape/sitemap.md to its new equivalent. Kill paths for the spam-injected URLs. |
| Analytics | Google Analytics 4 — install GA4 measurement ID in theme via wp_head action |
| Search Console | Verify ownership via DNS TXT (we control DNS now). Submit fresh sitemap post-launch as part of SEO recovery from the spam compromise. |
| Site icon / favicon | Use existing icon.png from media inventory; rebuild as multi-size set in theme |
7. Open Decisions
All open decisions are tracked as Todoist cards on the Benson Theatre 🎭 board with blocked-needs-decision labels. As of 2026-05-08:
Resolved (9 of 13): 1. ✅ Fonts → Manrope + Caveat (Google Fonts substitute) 2. ✅ SEO plugin → Yoast SEO (Free) 3. ✅ Image optimization → Imagify 4. ✅ Visual approach → Fresh take using existing palette + fonts-equivalent 5. ✅ Security → Wordfence (Free) 6. ✅ Login hardening → Wordfence handles it 7. ✅ Backup → Host-native only 8. ✅ SVG support → Native (no sanitization) 9. ✅ Site search → Built-in WP
Deferred to Jim's working session 2026-05-11 (3 of 13): 10. Newsletter approach 11. Bar's future 12. Day-to-day site admin
Still owned by Eric (1 of 13): 13. Production hosting target — Flywheel under G&M / Kinsta / decide later (separate Todoist card already in Ready)
Plus Jim-side questions (in dashboard.yml open_questions):
- Who owns the PayPal merchant account?
- How is the quarterly insider newsletter sent today?
- Full mailbox roster on @bensontheatre.org?
8. Sequencing for build start
When Eric says "go," the order is:
- Pick up Todoist card "🚧 Decide hosting target" → answer it (this triggers Local Sites scaffold options)
- Pick up "🧹 Pull all 66 images" — the download is already done as of 2026-05-08, in
site-scrape/media-inventory/downloaded/. This card is mostly verified-and-imported now. - Pick up "✨ Scaffold custom benson-theatre WP theme on Local" → run
/local-sites+/wordpress-theme-setup - Pick up "✨ Define event CPT + ACF schema" — coordinated with Events Manager Pro install
- Build pages in parallel (Donate, Memberships, Volunteer, About/History merge, Booking, Education, etc.)
- Tech replacements (Volunteer Gravity Form, Student Membership Gravity Form, Buy Tickets per event)
- Media migration to WP library
- SEO + redirects (Phase 7)
- Launch (Phase 8)
The Open Decisions above don't block scaffolding the theme. They block the plugins-and-tokens config step. Worth resolving in Eric's first review pass after the theme is up.