39290-vm/wp-content/mu-plugins/coaching-mvp.php
2026-03-24 10:38:28 +00:00

1627 lines
68 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Plugin Name: Coaching MVP Site Kit
* Description: Premium coaching template base with booking, lead capture, testimonials, pages, and starter content.
*/
if (!defined('ABSPATH')) {
exit;
}
const COACHING_MVP_TEMPLATE_VERSION = '2.0.0';
function coaching_mvp_service_catalog() {
return [
'discovery-call' => [
'label' => 'Discovery Call',
'code' => '01',
'summary' => 'A low-friction first step for visitors who want to explore fit, goals, and next steps before committing.',
'bullets' => ['30 minutes', 'Ideal first conversation', 'Best for fit and direction'],
],
'clarity-session' => [
'label' => 'Clarity Session',
'code' => '02',
'summary' => 'A focused deep-dive session for transitions, decisions, leadership tension, and getting unstuck quickly.',
'bullets' => ['90-minute intensive', 'Decision support', 'Action summary included'],
],
'momentum-coaching' => [
'label' => 'Momentum Coaching',
'code' => '03',
'summary' => 'Ongoing coaching for clients who need accountability, calm execution, and stronger follow-through over time.',
'bullets' => ['Ongoing 1:1 rhythm', 'Reflection between sessions', 'Built for durable progress'],
],
'leadership-intensive' => [
'label' => 'Leadership Intensive',
'code' => '04',
'summary' => 'A premium strategy container for founders, executives, and senior leaders navigating a high-stakes season.',
'bullets' => ['Executive-level support', 'Complex challenges welcome', 'Clear implementation path'],
],
];
}
function coaching_mvp_services() {
$services = [];
foreach (coaching_mvp_service_catalog() as $slug => $service) {
$services[$slug] = $service['label'];
}
return $services;
}
function coaching_mvp_register_post_types() {
register_post_type('testimonial', [
'labels' => [
'name' => 'Testimonials',
'singular_name' => 'Testimonial',
'add_new_item' => 'Add New Testimonial',
'edit_item' => 'Edit Testimonial',
],
'public' => true,
'show_in_rest' => true,
'menu_icon' => 'dashicons-format-quote',
'supports' => ['title', 'editor', 'excerpt', 'page-attributes'],
'has_archive' => false,
'rewrite' => ['slug' => 'testimonial'],
]);
register_post_type('booking_request', [
'labels' => [
'name' => 'Bookings',
'singular_name' => 'Booking',
'add_new_item' => 'Add Booking',
'edit_item' => 'View Booking',
],
'public' => false,
'show_ui' => true,
'show_in_rest' => false,
'menu_icon' => 'dashicons-calendar-alt',
'supports' => ['title'],
'capability_type' => 'post',
'map_meta_cap' => true,
]);
register_post_type('lead_capture', [
'labels' => [
'name' => 'Leads',
'singular_name' => 'Lead',
'add_new_item' => 'Add Lead',
'edit_item' => 'View Lead',
],
'public' => false,
'show_ui' => true,
'show_in_rest' => false,
'menu_icon' => 'dashicons-email-alt2',
'supports' => ['title'],
'capability_type' => 'post',
'map_meta_cap' => true,
]);
}
add_action('init', 'coaching_mvp_register_post_types');
function coaching_mvp_body_class($classes) {
$classes[] = 'coaching-mvp-active';
return $classes;
}
add_filter('body_class', 'coaching_mvp_body_class');
function coaching_mvp_styles() {
if (is_admin()) {
return;
}
wp_register_style('coaching-mvp-inline', false, [], null);
wp_enqueue_style('coaching-mvp-inline');
$css = <<<'CSS'
:root {
--coach-primary: #5468ff;
--coach-secondary: #13c7b8;
--coach-accent: #d7b267;
--coach-background: #f6f4ef;
--coach-surface: #ffffff;
--coach-surface-soft: rgba(255,255,255,.72);
--coach-text: #142033;
--coach-muted: #667085;
--coach-deep: #0d1530;
--coach-deeper: #091022;
--coach-border: rgba(20,32,51,.09);
--coach-shadow: 0 30px 80px rgba(15,23,42,.12);
--coach-shadow-lg: 0 50px 120px rgba(8,15,34,.22);
--coach-radius: 28px;
--coach-radius-sm: 18px;
--coach-spacing: 1.5rem;
}
body.coaching-mvp-active {
background:
radial-gradient(circle at top left, rgba(84,104,255,.10), transparent 28%),
radial-gradient(circle at top right, rgba(215,178,103,.12), transparent 26%),
linear-gradient(180deg, #f1f5ff 0%, #faf8f4 38%, #ffffff 100%);
color: var(--coach-text);
}
body.coaching-mvp-active .wp-site-blocks,
body.coaching-mvp-active .site,
body.coaching-mvp-active main {
color: var(--coach-text);
}
body.coaching-mvp-active.page .wp-site-blocks main,
body.coaching-mvp-active.home .wp-site-blocks main,
body.coaching-mvp-active.blog .wp-site-blocks main,
body.coaching-mvp-active.single-post .wp-site-blocks main {
--wp--style--global--content-size: min(1220px, calc(100vw - 40px));
--wp--style--global--wide-size: min(1380px, calc(100vw - 40px));
}
body.coaching-mvp-active .wp-block-post-content,
body.coaching-mvp-active .wp-block-query,
body.coaching-mvp-active .wp-block-group {
width: 100%;
}
body.coaching-mvp-active .wp-block-post-content.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)),
body.coaching-mvp-active .coach-home-page.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
max-width: var(--wp--style--global--content-size);
}
body.coaching-mvp-active header.wp-block-template-part {
position: sticky;
top: 0;
z-index: 30;
backdrop-filter: blur(18px);
background: rgba(255,255,255,.78);
border-bottom: 1px solid rgba(20,32,51,.06);
}
body.coaching-mvp-active .wp-block-site-title a,
body.coaching-mvp-active .wp-block-navigation a,
body.coaching-mvp-active .wp-block-navigation-item__content {
color: var(--coach-text);
text-decoration: none;
}
body.coaching-mvp-active .wp-block-navigation .wp-block-navigation-item__content {
font-weight: 600;
}
body.coaching-mvp-active .wp-block-navigation .current-menu-item > a,
body.coaching-mvp-active .wp-block-navigation .current_page_item > a {
color: var(--coach-primary);
}
body.coaching-mvp-active .wp-block-button__link {
border-radius: 999px;
padding: .95rem 1.4rem;
font-weight: 700;
text-decoration: none;
box-shadow: none;
}
body.coaching-mvp-active .wp-block-button.is-style-outline > .wp-block-button__link {
border-radius: 999px;
}
body.coaching-mvp-active .wp-block-post-title,
body.coaching-mvp-active h1,
body.coaching-mvp-active h2,
body.coaching-mvp-active h3,
body.coaching-mvp-active h4 {
letter-spacing: -.03em;
}
.coach-home-page .wp-block-post-title,
.page-slug-home .wp-block-post-title {
display: none;
}
.coach-shell,
.coach-hero,
.coach-section,
.coach-panel,
.coach-form-wrap,
.coach-service-card,
.coach-testimonial-card,
.coach-stat,
.coach-process-card,
.coach-mini-card,
.coach-faq-card,
.coach-story-card,
.coach-system-card,
.coach-blog-card,
.coach-quote-card,
.coach-visual-card {
border-radius: var(--coach-radius);
}
.coach-shell > * + * {
margin-top: clamp(1.5rem, 3vw, 2.5rem);
}
.coach-section {
margin-top: clamp(1.7rem, 4vw, 3rem);
}
.coach-hero {
position: relative;
overflow: hidden;
padding: clamp(2rem, 5vw, 4rem);
background:
radial-gradient(circle at top right, rgba(215,178,103,.28), transparent 25%),
radial-gradient(circle at left center, rgba(19,199,184,.18), transparent 30%),
linear-gradient(135deg, #091022 0%, #15254c 45%, #293f7c 75%, #5468ff 100%);
box-shadow: var(--coach-shadow-lg);
}
.coach-hero::before {
content: "";
position: absolute;
inset: auto -10% -25% 45%;
height: 360px;
background: radial-gradient(circle, rgba(255,255,255,.16), transparent 60%);
pointer-events: none;
}
.coach-hero h1,
.coach-hero h2,
.coach-hero p,
.coach-hero li,
.coach-hero strong,
.coach-hero .coach-quote-card {
color: #fff;
}
.coach-hero .wp-block-buttons .wp-block-button__link,
.coach-cta-row .wp-block-button__link,
.coach-form-wrap button,
.coach-inline-link {
border-radius: 999px;
padding: .95rem 1.4rem;
font-weight: 700;
text-decoration: none;
}
.coach-eyebrow {
display: inline-flex;
align-items: center;
gap: .5rem;
padding: .48rem .92rem;
border-radius: 999px;
background: rgba(255,255,255,.10);
border: 1px solid rgba(255,255,255,.18);
font-size: .8rem;
letter-spacing: .08em;
text-transform: uppercase;
}
.coach-badge {
display: inline-flex;
align-items: center;
gap: .45rem;
padding: .42rem .8rem;
border-radius: 999px;
background: rgba(84,104,255,.10);
color: var(--coach-primary);
font-size: .84rem;
font-weight: 800;
}
.coach-badge.dark {
background: rgba(255,255,255,.12);
color: #fff;
}
.coach-grid-2,
.coach-grid-3,
.coach-grid-4,
.coach-card-grid,
.coach-testimonial-grid,
.coach-process-grid,
.coach-story-grid,
.coach-faq-grid,
.coach-stats-grid,
.coach-mini-grid,
.coach-system-grid,
.coach-blog-grid,
.coach-visual-grid,
.coach-booking-layout {
display: grid;
gap: 1.2rem;
}
.coach-grid-2,
.coach-booking-layout { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.coach-grid-3,
.coach-card-grid,
.coach-testimonial-grid,
.coach-process-grid,
.coach-story-grid,
.coach-faq-grid,
.coach-mini-grid,
.coach-system-grid,
.coach-blog-grid,
.coach-visual-grid { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.coach-grid-4,
.coach-stats-grid { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.coach-panel,
.coach-service-card,
.coach-testimonial-card,
.coach-stat,
.coach-process-card,
.coach-mini-card,
.coach-faq-card,
.coach-story-card,
.coach-form-wrap,
.coach-system-card,
.coach-blog-card,
.coach-quote-card,
.coach-visual-card {
background: rgba(255,255,255,.92);
border: 1px solid var(--coach-border);
box-shadow: var(--coach-shadow);
padding: 1.35rem;
}
.coach-panel.soft,
.coach-quote-card,
.coach-visual-card.dark {
background: rgba(255,255,255,.10);
border-color: rgba(255,255,255,.16);
box-shadow: none;
}
.coach-quote-card {
color: #fff;
}
.coach-visual-card {
min-height: 140px;
}
.coach-visual-card h3,
.coach-visual-card p {
color: #fff;
}
.coach-hero-shell {
position: relative;
z-index: 1;
}
.coach-system-card h3,
.coach-service-card h3,
.coach-process-card h3,
.coach-faq-card h3,
.coach-story-card h3,
.coach-testimonial-card h3,
.coach-mini-card h3,
.coach-blog-card h3 {
margin-top: .35rem;
margin-bottom: .6rem;
}
.coach-stat strong {
display: block;
font-size: clamp(1.4rem, 3vw, 2.15rem);
color: var(--coach-text);
}
.coach-stat span,
.coach-muted,
.coach-service-card p,
.coach-process-card p,
.coach-faq-card p,
.coach-story-card p,
.coach-system-card p,
.coach-blog-card p,
.coach-testimonial-meta,
.coach-form-wrap p,
.coach-section p,
.coach-quote-card p,
.coach-mini-card p {
color: var(--coach-muted);
}
.coach-hero .coach-panel p,
.coach-hero .coach-quote-card p,
.coach-hero .coach-visual-card p,
.coach-hero .coach-badge.dark + h3 + p {
color: rgba(255,255,255,.82);
}
.coach-service-card ul,
.coach-process-card ul,
.coach-story-card ul,
.coach-system-card ul {
margin: .8rem 0 0 1rem;
}
.coach-icon-dot {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2.4rem;
height: 2.4rem;
border-radius: 50%;
background: rgba(84,104,255,.11);
color: var(--coach-primary);
font-weight: 800;
}
.coach-form-wrap {
padding: 1.55rem;
background: rgba(255,255,255,.96);
}
.coach-form-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 1rem;
}
.coach-form-grid .full {
grid-column: 1 / -1;
}
.coach-form-wrap label {
display: block;
font-weight: 700;
margin-bottom: .4rem;
color: var(--coach-text);
}
.coach-form-wrap input,
.coach-form-wrap textarea,
.coach-form-wrap select {
width: 100%;
border: 1px solid rgba(20,32,51,.12);
border-radius: 16px;
padding: .9rem 1rem;
font-size: 1rem;
background: #fff;
color: var(--coach-text);
}
.coach-form-wrap textarea {
min-height: 140px;
}
.coach-form-wrap button {
border: 0;
background: linear-gradient(135deg, var(--coach-primary), #7f56d9);
color: #fff;
cursor: pointer;
box-shadow: 0 18px 30px rgba(84,104,255,.24);
}
.coach-alert {
border-radius: 16px;
padding: .95rem 1rem;
margin-bottom: 1rem;
font-weight: 600;
}
.coach-alert.success {
background: rgba(19,199,184,.12);
color: #0e7067;
border: 1px solid rgba(19,199,184,.2);
}
.coach-alert.error {
background: rgba(255,107,129,.10);
color: #8d2d3b;
border: 1px solid rgba(255,107,129,.18);
}
.coach-testimonial-grid blockquote {
margin: 0;
}
.coach-testimonial-card .coach-rating {
color: #f5a524;
letter-spacing: .18em;
font-size: .95rem;
margin-bottom: .7rem;
}
.coach-cta-band {
padding: 1.6rem;
background:
linear-gradient(135deg, rgba(84,104,255,.10), rgba(19,199,184,.10)),
#fff;
border: 1px solid rgba(84,104,255,.12);
border-radius: var(--coach-radius);
box-shadow: var(--coach-shadow);
}
.coach-stack > * + * {
margin-top: 1rem;
}
.coach-inline-link {
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--coach-primary);
background: rgba(84,104,255,.08);
}
.coach-admin-link {
display: inline-flex;
align-items: center;
gap: .5rem;
margin-top: .5rem;
color: var(--coach-primary);
text-decoration: none;
font-weight: 700;
}
.coach-footer-note {
text-align: center;
color: var(--coach-muted);
font-size: .95rem;
margin-top: 2rem;
}
.coach-blog-card a,
.coach-blog-card .wp-block-post-excerpt__more-link,
.wp-block-post-excerpt__more-link,
.wp-block-read-more {
color: var(--coach-primary);
font-weight: 700;
text-decoration: none;
}
body.coaching-mvp-active .wp-block-post-template {
gap: 1.2rem;
}
body.coaching-mvp-active .wp-block-post-template > li,
body.coaching-mvp-active .wp-block-post {
border-radius: var(--coach-radius);
background: rgba(255,255,255,.94);
border: 1px solid var(--coach-border);
box-shadow: var(--coach-shadow);
padding: 1.25rem;
}
body.coaching-mvp-active .wp-block-post-featured-image img {
border-radius: 18px;
}
body.coaching-mvp-active .wp-block-query-title,
body.coaching-mvp-active .wp-block-post-title a {
color: var(--coach-text);
text-decoration: none;
}
body.coaching-mvp-active .wp-block-query-pagination {
margin-top: 1.2rem;
}
body.coaching-mvp-active .wp-block-query-pagination a {
color: var(--coach-primary);
text-decoration: none;
}
@media (max-width: 781px) {
.coach-hero { padding: 1.5rem; }
body.coaching-mvp-active header.wp-block-template-part { position: static; }
}
CSS;
wp_add_inline_style('coaching-mvp-inline', $css);
}
add_action('wp_enqueue_scripts', 'coaching_mvp_styles');
function coaching_mvp_home_content() {
return <<<'HTML'
<!-- wp:group {"className":"coach-home-page coach-shell","layout":{"type":"constrained"}} -->
<div class="wp-block-group coach-home-page coach-shell"><div class="wp-block-group__inner-container">
<!-- wp:group {"align":"wide","className":"coach-hero"} -->
<div class="wp-block-group alignwide coach-hero">
<!-- wp:columns {"verticalAlignment":"center"} -->
<div class="wp-block-columns are-vertically-aligned-center">
<!-- wp:column {"verticalAlignment":"center","width":"58%"} -->
<div class="wp-block-column is-vertically-aligned-center" style="flex-basis:58%">
<!-- wp:paragraph {"className":"coach-eyebrow"} -->
<p class="coach-eyebrow">Premium Coaching Template • Booking-first architecture</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1,"fontSize":"xx-large"} -->
<h1 class="wp-block-heading has-xx-large-font-size">A premium coaching template that future AI models can customize without rebuilding the foundation.</h1>
<!-- /wp:heading -->
<!-- wp:paragraph {"fontSize":"large"} -->
<p class="has-large-font-size">This starter is built to feel like a paid template: strong hero, real booking flow, editable services, dynamic testimonials, simple WordPress blog, and lead capture already wired into the conversion path.</p>
<!-- /wp:paragraph -->
<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button {"backgroundColor":"contrast-3","textColor":"base"} -->
<div class="wp-block-button"><a class="wp-block-button__link has-base-color has-contrast-3-background-color has-text-color has-background wp-element-button" href="/book-session/">Book Session</a></div>
<!-- /wp:button -->
<!-- wp:button {"className":"is-style-outline"} -->
<div class="wp-block-button is-style-outline"><a class="wp-block-button__link wp-element-button" href="/services/">Explore Services</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons -->
<!-- wp:list -->
<ul><li>Reusable template shell, not a one-off personal brand site</li><li>All must-have pages for coaching offers are already structured</li><li>Future customization can focus on niche, voice, offer, and visuals</li></ul>
<!-- /wp:list -->
</div>
<!-- /wp:column -->
<!-- wp:column {"verticalAlignment":"center","width":"42%"} -->
<div class="wp-block-column is-vertically-aligned-center" style="flex-basis:42%">
<!-- wp:html -->
<div class="coach-hero-shell coach-stack">
<div class="coach-quote-card">
<span class="coach-badge dark">Template objective</span>
<h3>Start from a premium base, then tailor it for the next coaching client.</h3>
<p>Replace the story, offer names, testimonials, and palette later — keep the expensive-looking structure now.</p>
</div>
<div class="coach-visual-grid">
<div class="coach-visual-card dark"><span class="coach-badge dark">Booking live</span><h3>Pay-later booking flow</h3><p>Requests are stored in WordPress admin for manual follow-up.</p></div>
<div class="coach-visual-card dark"><span class="coach-badge dark">Social proof</span><h3>Editable testimonials system</h3><p>Homepage and testimonials page both pull from the same content type.</p></div>
<div class="coach-visual-card dark"><span class="coach-badge dark">Content engine</span><h3>Simple core blog</h3><p>WordPress posts are already positioned as the lightweight content layer.</p></div>
</div>
</div>
<!-- /wp:html -->
</div>
<!-- /wp:column --></div>
<!-- /wp:columns -->
</div>
<!-- /wp:group -->
<!-- wp:html -->
<section class="coach-section coach-stats-grid">
<div class="coach-stat"><strong>7</strong><span>Core template areas already mapped for coaching businesses.</span></div>
<div class="coach-stat"><strong>Booking</strong><span>Primary conversion path is visible from the first fold.</span></div>
<div class="coach-stat"><strong>WP Core</strong><span>Blog stays simple and easy for future teams to manage.</span></div>
<div class="coach-stat"><strong>Reusable</strong><span>Built to be customized repeatedly, not recreated from zero.</span></div>
</section>
<!-- /wp:html -->
<!-- wp:group {"className":"coach-section","layout":{"type":"constrained"}} -->
<div class="wp-block-group coach-section"><div class="wp-block-group__inner-container">
<!-- wp:paragraph {"className":"coach-badge"} -->
<p class="coach-badge">Template systems</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2 class="wp-block-heading">Everything essential for a premium coaching template is already inside the shell</h2>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>These sections are the reusable operating system for future coaching sites. Each one can be re-skinned later without replacing the UX architecture.</p>
<!-- /wp:paragraph -->
<!-- wp:html -->
<div class="coach-system-grid">
<article class="coach-system-card"><span class="coach-icon-dot">01</span><h3>Hero</h3><p>A conversion-focused introduction with premium visual weight and immediate calls to action.</p></article>
<article class="coach-system-card"><span class="coach-icon-dot">02</span><h3>Booking system</h3><p>Dedicated booking page, structured intake fields, and saved requests in admin.</p></article>
<article class="coach-system-card"><span class="coach-icon-dot">03</span><h3>Services</h3><p>Offer cards, positioning language, and a page built to support higher-ticket decisions.</p></article>
<article class="coach-system-card"><span class="coach-icon-dot">04</span><h3>Testimonials</h3><p>Dynamic proof system powered by a custom content type instead of hard-coded copy.</p></article>
<article class="coach-system-card"><span class="coach-icon-dot">05</span><h3>About</h3><p>Credibility, method, philosophy, and founder-story space for trust building.</p></article>
<article class="coach-system-card"><span class="coach-icon-dot">06</span><h3>Blog</h3><p>Simple WordPress core blog kept intentionally clean for easy long-term maintenance.</p></article>
<article class="coach-system-card"><span class="coach-icon-dot">07</span><h3>Lead capture</h3><p>Secondary conversion path for visitors who need a conversation before booking.</p></article>
</div>
<!-- /wp:html -->
</div></div>
<!-- /wp:group -->
<!-- wp:group {"className":"coach-section","layout":{"type":"constrained"}} -->
<div class="wp-block-group coach-section"><div class="wp-block-group__inner-container">
<!-- wp:paragraph {"className":"coach-badge"} -->
<p class="coach-badge">Services snapshot</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2 class="wp-block-heading">A polished service layer that feels premium from day one</h2>
<!-- /wp:heading -->
<!-- wp:shortcode -->
[coaching_services limit="3"]
<!-- /wp:shortcode -->
<!-- wp:html -->
<div class="coach-mini-grid coach-section">
<div class="coach-mini-card"><h3>Designed for customization</h3><p>Future AI runs can swap labels, bullets, target audience, and package names without changing structure.</p></div>
<div class="coach-mini-card"><h3>Built for premium offers</h3><p>The layout supports discovery calls, intensives, retainers, and niche-specific coaching products.</p></div>
<div class="coach-mini-card"><h3>Clean conversion path</h3><p>Every service block naturally points visitors toward booking or inquiry.</p></div>
</div>
<!-- /wp:html -->
</div></div>
<!-- /wp:group -->
<!-- wp:group {"className":"coach-section","layout":{"type":"constrained"}} -->
<div class="wp-block-group coach-section"><div class="wp-block-group__inner-container">
<!-- wp:html -->
<div class="coach-cta-band coach-grid-2">
<div>
<span class="coach-badge">Booking-first</span>
<h2>The primary CTA is already doing the right job</h2>
<p>This template assumes booking is the main action. The homepage, services page, and trust sections all support that path without making the experience feel salesy.</p>
<p><a class="coach-inline-link" href="/book-session/">Open booking flow</a></p>
</div>
<div class="coach-process-grid">
<article class="coach-process-card"><span class="coach-icon-dot">1</span><h3>Choose a service</h3><p>Visitors self-select an offer that fits their current stage or challenge.</p></article>
<article class="coach-process-card"><span class="coach-icon-dot">2</span><h3>Submit preferences</h3><p>Date, time, format, and goals are captured without the complexity of a heavy external scheduler.</p></article>
<article class="coach-process-card"><span class="coach-icon-dot">3</span><h3>Follow up manually</h3><p>Admin review keeps this starter flexible until a future model replaces it with Calendly or another integration.</p></article>
</div>
</div>
<!-- /wp:html -->
</div></div>
<!-- /wp:group -->
<!-- wp:group {"className":"coach-section","layout":{"type":"constrained"}} -->
<div class="wp-block-group coach-section"><div class="wp-block-group__inner-container">
<!-- wp:paragraph {"className":"coach-badge"} -->
<p class="coach-badge">About foundation</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2 class="wp-block-heading">The about-story section is ready to carry positioning, philosophy, and trust</h2>
<!-- /wp:heading -->
<!-- wp:html -->
<div class="coach-grid-2">
<div class="coach-panel">
<h3>Built for future founder-story customization</h3>
<p>Later AI models can replace this copy with a real coach story, niche differentiators, credentials, and personal philosophy — while keeping the premium page rhythm intact.</p>
<p><a class="coach-inline-link" href="/about/">Open About page</a></p>
</div>
<div class="coach-story-grid">
<article class="coach-story-card"><h3>Credibility</h3><p>Space for experience, results, and approach without sounding inflated or generic.</p></article>
<article class="coach-story-card"><h3>Method</h3><p>Explain how sessions work, what changes for clients, and why the process feels different.</p></article>
<article class="coach-story-card"><h3>Trust</h3><p>Blend empathy, structure, and confidence — the three signals high-value coaching pages need most.</p></article>
</div>
</div>
<!-- /wp:html -->
</div></div>
<!-- /wp:group -->
<!-- wp:group {"className":"coach-section","layout":{"type":"constrained"}} -->
<div class="wp-block-group coach-section"><div class="wp-block-group__inner-container">
<!-- wp:paragraph {"className":"coach-badge"} -->
<p class="coach-badge">Testimonials system</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2 class="wp-block-heading">Social proof is already dynamic, editable, and reusable across the template</h2>
<!-- /wp:heading -->
<!-- wp:shortcode -->
[coaching_testimonials limit="3"]
<!-- /wp:shortcode -->
</div></div>
<!-- /wp:group -->
<!-- wp:group {"className":"coach-section","layout":{"type":"constrained"}} -->
<div class="wp-block-group coach-section"><div class="wp-block-group__inner-container">
<!-- wp:paragraph {"className":"coach-badge"} -->
<p class="coach-badge">Blog preview</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2 class="wp-block-heading">The content layer stays simple: native WordPress posts with a cleaner presentation</h2>
<!-- /wp:heading -->
<!-- wp:shortcode -->
[coaching_recent_posts limit="3"]
<!-- /wp:shortcode -->
</div></div>
<!-- /wp:group -->
<!-- wp:group {"className":"coach-section","layout":{"type":"constrained"}} -->
<div class="wp-block-group coach-section"><div class="wp-block-group__inner-container">
<!-- wp:html -->
<div class="coach-cta-band coach-grid-2">
<div>
<span class="coach-badge">Lead capture</span>
<h2>Not every ideal client is ready to book on the first visit</h2>
<p>The lead form is the secondary path for visitors who need a question answered, want help choosing an offer, or simply prefer a lower-commitment start.</p>
<p><a class="coach-inline-link" href="/contact/">Open Contact page</a></p>
</div>
<div>[coaching_lead_form]</div>
</div>
<!-- /wp:html -->
</div></div>
<!-- /wp:group -->
<!-- wp:paragraph {"className":"coach-footer-note"} -->
<p class="coach-footer-note">This template base is intentionally generic enough to be reused, but polished enough to feel like a premium coaching starter on day one.</p>
<!-- /wp:paragraph -->
</div></div>
<!-- /wp:group -->
HTML;
}
function coaching_mvp_services_content() {
return <<<'HTML'
<!-- wp:group {"className":"coach-shell","layout":{"type":"constrained"}} -->
<div class="wp-block-group coach-shell"><div class="wp-block-group__inner-container">
<!-- wp:paragraph {"className":"coach-badge"} --><p class="coach-badge">Coaching services</p><!-- /wp:paragraph -->
<!-- wp:heading {"level":1} --><h1 class="wp-block-heading">Services designed to feel premium, clear, and easy to customize later</h1><!-- /wp:heading -->
<!-- wp:paragraph {"fontSize":"large"} --><p class="has-large-font-size">This page is the reusable offer layer of the template: clear service cards, premium positioning, and enough structure for future AI customization without page rebuilding.</p><!-- /wp:paragraph -->
<!-- wp:shortcode -->
[coaching_services limit="4"]
<!-- /wp:shortcode -->
<!-- wp:html -->
<div class="coach-grid-2 coach-section">
<div class="coach-panel">
<span class="coach-badge">Who this is for</span>
<h3>Built for founders, professionals, leaders, and experts in transition</h3>
<p>These cards work equally well for executive coaching, mindset coaching, business coaching, career transition work, and niche-specific premium offers.</p>
</div>
<div class="coach-panel">
<span class="coach-badge">What each offer should do</span>
<h3>Reduce hesitation and make the next step obvious</h3>
<p>Each service helps visitors self-select the right level of support, then move directly into booking or lead capture.</p>
</div>
</div>
<div class="coach-process-grid coach-section">
<article class="coach-process-card"><span class="coach-icon-dot">01</span><h3>Clarify the need</h3><p>Use one service for discovery, one for depth, one for continuity, and one for premium escalation.</p></article>
<article class="coach-process-card"><span class="coach-icon-dot">02</span><h3>Frame the value</h3><p>Premium service pages make the experience feel contained, specific, and safe to say yes to.</p></article>
<article class="coach-process-card"><span class="coach-icon-dot">03</span><h3>Route to action</h3><p>All roads should lead to booking or contact — not to dead-end informational copy.</p></article>
</div>
<div class="coach-cta-band coach-section">
<h3>Ready to adapt these offers for a real coach or niche?</h3>
<p>Use the booking page if the service structure is already clear, or the contact page if you want a softer first step.</p>
<p><a class="coach-inline-link" href="/book-session/">Book now</a> <a class="coach-inline-link" href="/contact/" style="margin-left:.5rem;">Ask a question</a></p>
</div>
<!-- /wp:html -->
</div></div>
<!-- /wp:group -->
HTML;
}
function coaching_mvp_testimonials_content() {
return <<<'HTML'
<!-- wp:group {"className":"coach-shell","layout":{"type":"constrained"}} -->
<div class="wp-block-group coach-shell"><div class="wp-block-group__inner-container">
<!-- wp:paragraph {"className":"coach-badge"} --><p class="coach-badge">Testimonials system</p><!-- /wp:paragraph -->
<!-- wp:heading {"level":1} --><h1 class="wp-block-heading">A reusable proof system that future AI models can rewrite without touching the layout</h1><!-- /wp:heading -->
<!-- wp:paragraph --><p>This page is powered by a dedicated Testimonials content type in WordPress. Replace sample quotes later, and both this page and the homepage will update automatically.</p><!-- /wp:paragraph -->
<!-- wp:shortcode -->
[coaching_testimonials limit="6"]
<!-- /wp:shortcode -->
<!-- wp:html -->
<div class="coach-mini-grid coach-section">
<div class="coach-mini-card"><h3>Editable from admin</h3><p>Add, remove, or reorder testimonials in WordPress without changing page content.</p></div>
<div class="coach-mini-card"><h3>Supports premium positioning</h3><p>Use role labels to add context like founder, executive, creative leader, or high-performance client.</p></div>
<div class="coach-mini-card"><h3>Shared across template</h3><p>The same testimonial source powers key proof moments across the site.</p></div>
</div>
<div class="coach-cta-band coach-section"><h3>Need to manage sample proof now?</h3><p>Add new testimonials in the WordPress admin and they will automatically appear here.</p><p><a class="coach-admin-link" href="/wp-admin/edit.php?post_type=testimonial">Manage testimonials →</a></p></div>
<!-- /wp:html -->
</div></div>
<!-- /wp:group -->
HTML;
}
function coaching_mvp_about_content() {
return <<<'HTML'
<!-- wp:group {"className":"coach-shell","layout":{"type":"constrained"}} -->
<div class="wp-block-group coach-shell"><div class="wp-block-group__inner-container">
<!-- wp:paragraph {"className":"coach-badge"} --><p class="coach-badge">About the coach</p><!-- /wp:paragraph -->
<!-- wp:heading {"level":1} --><h1 class="wp-block-heading">An about page with enough depth to build trust, but enough flexibility to customize for many coaching niches</h1><!-- /wp:heading -->
<!-- wp:paragraph {"fontSize":"large"} --><p class="has-large-font-size">This page is the trust layer of the template. It is designed to hold founder story, method, philosophy, credentials, and emotional reassurance without becoming cluttered.</p><!-- /wp:paragraph -->
<!-- wp:html -->
<div class="coach-grid-2 coach-section">
<div class="coach-panel">
<span class="coach-badge">Starter story</span>
<h3>Replace with a real founder narrative later</h3>
<p>Use this area for the coachs turning point, philosophy, client promise, or the problem they are uniquely good at helping solve.</p>
<p><a class="coach-inline-link" href="/book-session/">Book a session</a></p>
</div>
<div class="coach-story-grid">
<article class="coach-story-card"><h3>Philosophy</h3><p>Clarity before noise. Direction before pressure. Action without performative hustle.</p></article>
<article class="coach-story-card"><h3>Experience</h3><p>Space for credentials, lived experience, certifications, or industry-specific credibility.</p></article>
<article class="coach-story-card"><h3>Client experience</h3><p>Explain how sessions feel: direct, calm, strategic, supportive, practical, or deeply reflective.</p></article>
</div>
</div>
<div class="coach-process-grid coach-section">
<article class="coach-process-card"><span class="coach-icon-dot">01</span><h3>Listen deeply</h3><p>The coach should feel perceptive, not generic.</p></article>
<article class="coach-process-card"><span class="coach-icon-dot">02</span><h3>Create direction</h3><p>Move from emotional fog or strategic overload into an honest next path.</p></article>
<article class="coach-process-card"><span class="coach-icon-dot">03</span><h3>Support action</h3><p>Ground ideas into behavior, decisions, rhythm, and follow-through.</p></article>
</div>
<div class="coach-cta-band coach-section"><h3>Trust pages should always hand visitors a next move</h3><p>Point them to services, booking, or testimonials so the about page supports conversion instead of acting like a dead end.</p><p><a class="coach-inline-link" href="/services/">Explore services</a></p></div>
<!-- /wp:html -->
</div></div>
<!-- /wp:group -->
HTML;
}
function coaching_mvp_booking_content() {
return <<<'HTML'
<!-- wp:group {"className":"coach-shell","layout":{"type":"constrained"}} -->
<div class="wp-block-group coach-shell"><div class="wp-block-group__inner-container">
<!-- wp:paragraph {"className":"coach-badge"} --><p class="coach-badge">Booking system</p><!-- /wp:paragraph -->
<!-- wp:heading {"level":1} --><h1 class="wp-block-heading">Request a session through a clean, premium booking experience</h1><!-- /wp:heading -->
<!-- wp:paragraph --><p>This template uses a pay-later booking request flow. It is intentionally simple, lightweight, and easy to replace later with Calendly or another scheduling tool.</p><!-- /wp:paragraph -->
<!-- wp:html -->
<div class="coach-booking-layout coach-section">
<div>[coaching_booking_form]</div>
<div class="coach-stack">
<div class="coach-mini-card"><h3>What happens next</h3><p>The coach reviews the request inside WordPress, then follows up manually to confirm fit, timing, and session details.</p></div>
<div class="coach-mini-card"><h3>Why this works for a template</h3><p>It delivers a real booking system now without locking the starter into one external platform or workflow.</p></div>
<div class="coach-mini-card"><h3>Admin review</h3><p>Every request is stored in a dedicated Bookings section in the dashboard.</p><p><a class="coach-admin-link" href="/wp-admin/edit.php?post_type=booking_request">View bookings →</a></p></div>
<div class="coach-mini-card"><h3>Recommended future upgrades</h3><p>Calendly embed, Stripe-powered paid session flow, confirmation emails, or service-specific funnels.</p></div>
</div>
</div>
<!-- /wp:html -->
</div></div>
<!-- /wp:group -->
HTML;
}
function coaching_mvp_contact_content() {
return <<<'HTML'
<!-- wp:group {"className":"coach-shell","layout":{"type":"constrained"}} -->
<div class="wp-block-group coach-shell"><div class="wp-block-group__inner-container">
<!-- wp:paragraph {"className":"coach-badge"} --><p class="coach-badge">Lead capture</p><!-- /wp:paragraph -->
<!-- wp:heading {"level":1} --><h1 class="wp-block-heading">Open a lower-friction conversation for visitors who are not ready to book yet</h1><!-- /wp:heading -->
<!-- wp:paragraph --><p>This page is the secondary conversion path. It captures thoughtful leads who need clarity, have questions, or want a recommendation before choosing an offer.</p><!-- /wp:paragraph -->
<!-- wp:html -->
<div class="coach-booking-layout coach-section">
<div>[coaching_lead_form]</div>
<div class="coach-stack">
<div class="coach-mini-card"><h3>Best use cases</h3><p>Service selection questions, founder introductions, budget-fit conversations, or slower trust-building journeys.</p></div>
<div class="coach-mini-card"><h3>Why it matters</h3><p>Not every premium buyer wants to jump straight into a booking flow on the first visit.</p></div>
<div class="coach-mini-card"><h3>Admin review</h3><p>Every lead appears in a dedicated Leads section for easy follow-up.</p><p><a class="coach-admin-link" href="/wp-admin/edit.php?post_type=lead_capture">View leads →</a></p></div>
<div class="coach-mini-card"><h3>Suggested future add-ons</h3><p>CRM sync, email automation, lead scoring, or a niche-specific qualification form.</p></div>
</div>
</div>
<!-- /wp:html -->
</div></div>
<!-- /wp:group -->
HTML;
}
function coaching_mvp_template_pages() {
return [
'home' => [
'title' => 'Home',
'content' => coaching_mvp_home_content(),
],
'services' => [
'title' => 'Services',
'content' => coaching_mvp_services_content(),
],
'testimonials' => [
'title' => 'Testimonials',
'content' => coaching_mvp_testimonials_content(),
],
'about' => [
'title' => 'About',
'content' => coaching_mvp_about_content(),
],
'book-session' => [
'title' => 'Book Session',
'content' => coaching_mvp_booking_content(),
],
'contact' => [
'title' => 'Contact',
'content' => coaching_mvp_contact_content(),
],
'blog' => [
'title' => 'Blog',
'content' => '',
],
];
}
function coaching_mvp_upsert_page($slug, $definition) {
$page = get_page_by_path($slug, OBJECT, 'page');
$postarr = [
'post_title' => $definition['title'],
'post_name' => $slug,
'post_type' => 'page',
'post_status' => 'publish',
'post_content' => $definition['content'],
];
if ($page) {
$postarr['ID'] = $page->ID;
wp_update_post($postarr);
return (int) $page->ID;
}
return (int) wp_insert_post($postarr);
}
function coaching_mvp_seed_navigation($page_ids) {
$nav = get_page_by_title('Primary Navigation', OBJECT, 'wp_navigation');
$nav_content = sprintf(
"<!-- wp:navigation-link {\"label\":\"Home\",\"type\":\"page\",\"id\":%d,\"url\":\"/\",\"kind\":\"post-type\"} /-->\n" .
"<!-- wp:navigation-link {\"label\":\"Services\",\"type\":\"page\",\"id\":%d,\"url\":\"/services/\",\"kind\":\"post-type\"} /-->\n" .
"<!-- wp:navigation-link {\"label\":\"Testimonials\",\"type\":\"page\",\"id\":%d,\"url\":\"/testimonials/\",\"kind\":\"post-type\"} /-->\n" .
"<!-- wp:navigation-link {\"label\":\"About\",\"type\":\"page\",\"id\":%d,\"url\":\"/about/\",\"kind\":\"post-type\"} /-->\n" .
"<!-- wp:navigation-link {\"label\":\"Blog\",\"type\":\"page\",\"id\":%d,\"url\":\"/blog/\",\"kind\":\"post-type\"} /-->\n" .
"<!-- wp:navigation-link {\"label\":\"Book Session\",\"type\":\"page\",\"id\":%d,\"url\":\"/book-session/\",\"kind\":\"post-type\"} /-->\n" .
"<!-- wp:navigation-link {\"label\":\"Contact\",\"type\":\"page\",\"id\":%d,\"url\":\"/contact/\",\"kind\":\"post-type\"} /-->\n" .
"<!-- wp:navigation-link {\"label\":\"Admin\",\"type\":\"custom\",\"url\":\"/wp-admin/\",\"kind\":\"custom\"} /-->",
$page_ids['home'],
$page_ids['services'],
$page_ids['testimonials'],
$page_ids['about'],
$page_ids['blog'],
$page_ids['book-session'],
$page_ids['contact']
);
$postarr = [
'post_title' => 'Primary Navigation',
'post_status' => 'publish',
'post_type' => 'wp_navigation',
'post_content' => $nav_content,
];
if ($nav) {
$postarr['ID'] = $nav->ID;
wp_update_post($postarr);
return;
}
wp_insert_post($postarr);
}
function coaching_mvp_seed_testimonials() {
$items = [
[
'title' => 'Jordan Ellis — Sample',
'role' => 'Founder, advisory studio',
'content' => 'I came in overwhelmed and spread thin. The coaching process helped me narrow the signal, make cleaner decisions, and finally move with conviction instead of noise.',
'menu_order' => 1,
],
[
'title' => 'Maya Chen — Sample',
'role' => 'Senior leader, technology team',
'content' => 'What felt different was the balance of calm and challenge. I left each session with clearer priorities, stronger boundaries, and next steps I could actually execute.',
'menu_order' => 2,
],
[
'title' => 'Daniel Ross — Sample',
'role' => 'Executive coaching client',
'content' => 'This gave me the structure I was missing. Instead of collecting more insight, I built momentum and followed through on decisions I had delayed for months.',
'menu_order' => 3,
],
[
'title' => 'Alina Patel — Sample',
'role' => 'Creative founder, growth stage brand',
'content' => 'The sessions felt premium, focused, and deeply useful. I had space to think, but also enough accountability to convert clarity into action.',
'menu_order' => 4,
],
];
foreach ($items as $item) {
$existing = get_page_by_title($item['title'], OBJECT, 'testimonial');
$postarr = [
'post_type' => 'testimonial',
'post_status' => 'publish',
'post_title' => $item['title'],
'post_content' => $item['content'],
'menu_order' => $item['menu_order'],
];
if ($existing) {
$postarr['ID'] = $existing->ID;
$post_id = wp_update_post($postarr);
} else {
$post_id = wp_insert_post($postarr);
}
if ($post_id && !is_wp_error($post_id)) {
update_post_meta($post_id, '_testimonial_role', $item['role']);
}
}
}
function coaching_mvp_seed_blog_posts() {
$posts = [
[
'title' => 'How Clarity Creates Better Decisions',
'slug' => 'how-clarity-creates-better-decisions',
'content' => "Decision fatigue usually does not come from too few options. It comes from too many open loops. A good coaching conversation reduces noise, clarifies what matters now, and turns vague pressure into an honest next move.\n\nFor a premium coaching site, content like this helps visitors feel the style of the work before they ever book. That is why this template keeps the blog simple but present: it supports authority, trust, and tone without distracting from the core conversion path.",
],
[
'title' => 'When High Performers Need Structure, Not More Pressure',
'slug' => 'when-high-performers-need-structure-not-more-pressure',
'content' => "Many coaching clients do not need more motivation. They need better structure, cleaner priorities, and an environment that supports follow-through.\n\nThis starter blog post shows how the template can host thoughtful, trust-building content while remaining lightweight and easy to customize for any future coaching niche.",
],
[
'title' => 'A Better Rhythm for Coaching Between Insight and Action',
'slug' => 'a-better-rhythm-for-coaching-between-insight-and-action',
'content' => "Great coaching is not just about reflection. It is also about timing, pacing, and what happens after the session ends.\n\nUse the blog area for ideas like this: practical, reassuring, and aligned with the experience the visitor can expect once they become a client.",
],
];
foreach ($posts as $item) {
$existing = get_page_by_path($item['slug'], OBJECT, 'post');
$postarr = [
'post_type' => 'post',
'post_status' => 'publish',
'post_title' => $item['title'],
'post_name' => $item['slug'],
'post_content' => $item['content'],
];
if ($existing) {
$postarr['ID'] = $existing->ID;
wp_update_post($postarr);
} else {
wp_insert_post($postarr);
}
}
}
function coaching_mvp_seed_template_content() {
if (get_option('coaching_mvp_template_version') === COACHING_MVP_TEMPLATE_VERSION) {
return;
}
$page_ids = [];
foreach (coaching_mvp_template_pages() as $slug => $definition) {
$page_ids[$slug] = coaching_mvp_upsert_page($slug, $definition);
}
if (!empty($page_ids['home'])) {
update_option('show_on_front', 'page');
update_option('page_on_front', $page_ids['home']);
}
if (!empty($page_ids['blog'])) {
update_option('page_for_posts', $page_ids['blog']);
}
coaching_mvp_seed_navigation($page_ids);
coaching_mvp_seed_testimonials();
coaching_mvp_seed_blog_posts();
update_option('coaching_mvp_template_version', COACHING_MVP_TEMPLATE_VERSION, false);
flush_rewrite_rules(false);
}
add_action('init', 'coaching_mvp_seed_template_content', 30);
function coaching_mvp_sanitize_textarea($value) {
return trim(wp_strip_all_tags((string) $value));
}
function coaching_mvp_handle_forms() {
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || empty($_POST['coaching_form_action'])) {
return;
}
$action = sanitize_key(wp_unslash($_POST['coaching_form_action']));
$redirect = !empty($_POST['_wp_http_referer']) ? wp_unslash($_POST['_wp_http_referer']) : home_url('/');
$redirect = remove_query_arg(['booking_status', 'lead_status'], $redirect);
if (!isset($_POST['coaching_form_nonce']) || !wp_verify_nonce(wp_unslash($_POST['coaching_form_nonce']), 'coaching_form_submit')) {
wp_safe_redirect(add_query_arg($action === 'booking' ? 'booking_status' : 'lead_status', 'error', $redirect));
exit;
}
$name = sanitize_text_field(wp_unslash($_POST['name'] ?? ''));
$email = sanitize_email(wp_unslash($_POST['email'] ?? ''));
$phone = sanitize_text_field(wp_unslash($_POST['phone'] ?? ''));
$message = coaching_mvp_sanitize_textarea(wp_unslash($_POST['message'] ?? ''));
if (!$name || !$email) {
wp_safe_redirect(add_query_arg($action === 'booking' ? 'booking_status' : 'lead_status', 'error', $redirect));
exit;
}
if ($action === 'booking') {
$service = sanitize_text_field(wp_unslash($_POST['service'] ?? 'Discovery Call'));
$preferred_date = sanitize_text_field(wp_unslash($_POST['preferred_date'] ?? ''));
$preferred_time = sanitize_text_field(wp_unslash($_POST['preferred_time'] ?? ''));
$format = sanitize_text_field(wp_unslash($_POST['session_format'] ?? 'Zoom'));
$goal = coaching_mvp_sanitize_textarea(wp_unslash($_POST['goal'] ?? ''));
$post_id = wp_insert_post([
'post_type' => 'booking_request',
'post_status' => 'private',
'post_title' => sprintf('%s — %s', $name, $preferred_date ?: current_time('Y-m-d')),
], true);
if (is_wp_error($post_id)) {
wp_safe_redirect(add_query_arg('booking_status', 'error', $redirect));
exit;
}
update_post_meta($post_id, '_booking_name', $name);
update_post_meta($post_id, '_booking_email', $email);
update_post_meta($post_id, '_booking_phone', $phone);
update_post_meta($post_id, '_booking_service', $service);
update_post_meta($post_id, '_booking_date', $preferred_date);
update_post_meta($post_id, '_booking_time', $preferred_time);
update_post_meta($post_id, '_booking_format', $format);
update_post_meta($post_id, '_booking_goal', $goal);
update_post_meta($post_id, '_booking_message', $message);
wp_safe_redirect(add_query_arg('booking_status', 'success', $redirect));
exit;
}
if ($action === 'lead') {
$focus = sanitize_text_field(wp_unslash($_POST['focus'] ?? ''));
$company = sanitize_text_field(wp_unslash($_POST['company'] ?? ''));
$post_id = wp_insert_post([
'post_type' => 'lead_capture',
'post_status' => 'private',
'post_title' => sprintf('%s — %s', $name, current_time('Y-m-d H:i')),
], true);
if (is_wp_error($post_id)) {
wp_safe_redirect(add_query_arg('lead_status', 'error', $redirect));
exit;
}
update_post_meta($post_id, '_lead_name', $name);
update_post_meta($post_id, '_lead_email', $email);
update_post_meta($post_id, '_lead_phone', $phone);
update_post_meta($post_id, '_lead_company', $company);
update_post_meta($post_id, '_lead_focus', $focus);
update_post_meta($post_id, '_lead_message', $message);
wp_safe_redirect(add_query_arg('lead_status', 'success', $redirect));
exit;
}
}
add_action('template_redirect', 'coaching_mvp_handle_forms', 1);
function coaching_mvp_booking_form_shortcode() {
$status = isset($_GET['booking_status']) ? sanitize_key(wp_unslash($_GET['booking_status'])) : '';
ob_start();
?>
<div class="coach-form-wrap" id="book-form">
<?php if ($status === 'success') : ?>
<div class="coach-alert success">Thanks — your booking request was received. You can review it anytime in the WordPress admin under Bookings.</div>
<?php elseif ($status === 'error') : ?>
<div class="coach-alert error">Please complete the required fields and try again.</div>
<?php endif; ?>
<div class="coach-stack">
<div>
<span class="coach-badge">Book a pay-later session</span>
<h3>Request your coaching session</h3>
<p>Pick the service, preferred date, and format. This template stores requests in WordPress so the coach can confirm details personally.</p>
</div>
<form method="post" class="coach-stack">
<?php wp_nonce_field('coaching_form_submit', 'coaching_form_nonce'); ?>
<input type="hidden" name="coaching_form_action" value="booking" />
<div class="coach-form-grid">
<div>
<label for="coach-book-name">Full name</label>
<input id="coach-book-name" type="text" name="name" required />
</div>
<div>
<label for="coach-book-email">Email</label>
<input id="coach-book-email" type="email" name="email" required />
</div>
<div>
<label for="coach-book-phone">Phone</label>
<input id="coach-book-phone" type="text" name="phone" />
</div>
<div>
<label for="coach-book-service">Service</label>
<select id="coach-book-service" name="service">
<?php foreach (coaching_mvp_services() as $value => $label) : ?>
<option value="<?php echo esc_attr($label); ?>"><?php echo esc_html($label); ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="coach-book-date">Preferred date</label>
<input id="coach-book-date" type="date" name="preferred_date" required />
</div>
<div>
<label for="coach-book-time">Preferred time</label>
<input id="coach-book-time" type="time" name="preferred_time" required />
</div>
<div>
<label for="coach-book-format">Session format</label>
<select id="coach-book-format" name="session_format">
<option value="Zoom">Zoom</option>
<option value="Phone">Phone</option>
<option value="In Person">In Person</option>
</select>
</div>
<div class="full">
<label for="coach-book-goal">What would you like help with?</label>
<textarea id="coach-book-goal" name="goal" placeholder="Share the challenge, decision, transition, or result you want support with."></textarea>
</div>
<div class="full">
<label for="coach-book-message">Anything else?</label>
<textarea id="coach-book-message" name="message" placeholder="Include context, timing constraints, or preferred cadence."></textarea>
</div>
</div>
<div>
<button type="submit">Request Session</button>
</div>
</form>
</div>
</div>
<?php
return ob_get_clean();
}
add_shortcode('coaching_booking_form', 'coaching_mvp_booking_form_shortcode');
function coaching_mvp_lead_form_shortcode() {
$status = isset($_GET['lead_status']) ? sanitize_key(wp_unslash($_GET['lead_status'])) : '';
ob_start();
?>
<div class="coach-form-wrap" id="lead-form">
<?php if ($status === 'success') : ?>
<div class="coach-alert success">Thanks — your message was captured and is now visible in the WordPress admin under Leads.</div>
<?php elseif ($status === 'error') : ?>
<div class="coach-alert error">Please add your name and email so we can respond properly.</div>
<?php endif; ?>
<div class="coach-stack">
<div>
<span class="coach-badge">Lead capture</span>
<h3>Start the conversation</h3>
<p>Not ready to book yet? Share your focus area and the coach can follow up with the right next step.</p>
</div>
<form method="post" class="coach-stack">
<?php wp_nonce_field('coaching_form_submit', 'coaching_form_nonce'); ?>
<input type="hidden" name="coaching_form_action" value="lead" />
<div class="coach-form-grid">
<div>
<label for="coach-lead-name">Full name</label>
<input id="coach-lead-name" type="text" name="name" required />
</div>
<div>
<label for="coach-lead-email">Email</label>
<input id="coach-lead-email" type="email" name="email" required />
</div>
<div>
<label for="coach-lead-phone">Phone</label>
<input id="coach-lead-phone" type="text" name="phone" />
</div>
<div>
<label for="coach-lead-company">Company / role</label>
<input id="coach-lead-company" type="text" name="company" />
</div>
<div class="full">
<label for="coach-lead-focus">What are you working toward?</label>
<input id="coach-lead-focus" type="text" name="focus" placeholder="Examples: leadership transition, consistency, executive presence, burnout recovery" />
</div>
<div class="full">
<label for="coach-lead-message">Message</label>
<textarea id="coach-lead-message" name="message" placeholder="Share what support would feel most valuable right now."></textarea>
</div>
</div>
<div>
<button type="submit">Send Inquiry</button>
</div>
</form>
</div>
</div>
<?php
return ob_get_clean();
}
add_shortcode('coaching_lead_form', 'coaching_mvp_lead_form_shortcode');
function coaching_mvp_services_shortcode($atts = []) {
$atts = shortcode_atts(['limit' => 4], $atts, 'coaching_services');
$limit = max(1, (int) $atts['limit']);
$catalog = array_slice(coaching_mvp_service_catalog(), 0, $limit, true);
ob_start();
echo '<div class="coach-card-grid">';
foreach ($catalog as $service) {
echo '<article class="coach-service-card">';
echo '<span class="coach-icon-dot">' . esc_html($service['code']) . '</span>';
echo '<h3>' . esc_html($service['label']) . '</h3>';
echo '<p>' . esc_html($service['summary']) . '</p>';
echo '<ul>';
foreach ($service['bullets'] as $bullet) {
echo '<li>' . esc_html($bullet) . '</li>';
}
echo '</ul>';
echo '</article>';
}
echo '</div>';
return ob_get_clean();
}
add_shortcode('coaching_services', 'coaching_mvp_services_shortcode');
function coaching_mvp_testimonials_shortcode($atts = []) {
$atts = shortcode_atts(['limit' => 6], $atts, 'coaching_testimonials');
$items = get_posts([
'post_type' => 'testimonial',
'post_status' => 'publish',
'numberposts' => (int) $atts['limit'],
'orderby' => 'menu_order date',
'order' => 'ASC',
]);
if (!$items) {
return '<p>No testimonials yet.</p>';
}
ob_start();
echo '<div class="coach-testimonial-grid">';
foreach ($items as $item) {
$role = get_post_meta($item->ID, '_testimonial_role', true);
echo '<article class="coach-testimonial-card">';
echo '<div class="coach-rating">★★★★★</div>';
echo '<blockquote><p>' . esc_html(wp_strip_all_tags($item->post_content)) . '</p></blockquote>';
echo '<h3>' . esc_html(get_the_title($item)) . '</h3>';
if ($role) {
echo '<div class="coach-testimonial-meta">' . esc_html($role) . '</div>';
}
echo '</article>';
}
echo '</div>';
return ob_get_clean();
}
add_shortcode('coaching_testimonials', 'coaching_mvp_testimonials_shortcode');
function coaching_mvp_recent_posts_shortcode($atts = []) {
$atts = shortcode_atts(['limit' => 3], $atts, 'coaching_recent_posts');
$items = get_posts([
'post_type' => 'post',
'post_status' => 'publish',
'numberposts' => (int) $atts['limit'],
'orderby' => 'date',
'order' => 'DESC',
]);
if (!$items) {
return '<p>No blog posts yet.</p>';
}
ob_start();
echo '<div class="coach-blog-grid">';
foreach ($items as $item) {
echo '<article class="coach-blog-card">';
echo '<span class="coach-badge">Blog</span>';
echo '<h3><a href="' . esc_url(get_permalink($item)) . '">' . esc_html(get_the_title($item)) . '</a></h3>';
echo '<p>' . esc_html(wp_trim_words(wp_strip_all_tags($item->post_content), 26)) . '</p>';
echo '<a class="coach-admin-link" href="' . esc_url(get_permalink($item)) . '">Read article →</a>';
echo '</article>';
}
echo '</div>';
return ob_get_clean();
}
add_shortcode('coaching_recent_posts', 'coaching_mvp_recent_posts_shortcode');
function coaching_mvp_admin_columns($columns, $post_type) {
if ($post_type === 'booking_request') {
return [
'cb' => $columns['cb'],
'title' => 'Booking',
'service' => 'Service',
'date' => 'Date',
'contact' => 'Contact',
'format' => 'Format',
];
}
if ($post_type === 'lead_capture') {
return [
'cb' => $columns['cb'],
'title' => 'Lead',
'focus' => 'Focus',
'contact' => 'Contact',
'date' => 'Received',
];
}
if ($post_type === 'testimonial') {
$columns['role'] = 'Role';
return $columns;
}
return $columns;
}
add_filter('manage_booking_request_posts_columns', fn($columns) => coaching_mvp_admin_columns($columns, 'booking_request'));
add_filter('manage_lead_capture_posts_columns', fn($columns) => coaching_mvp_admin_columns($columns, 'lead_capture'));
add_filter('manage_testimonial_posts_columns', fn($columns) => coaching_mvp_admin_columns($columns, 'testimonial'));
function coaching_mvp_render_admin_column($column, $post_id) {
switch ($column) {
case 'service':
echo esc_html((string) get_post_meta($post_id, '_booking_service', true));
break;
case 'date':
if (get_post_type($post_id) === 'booking_request') {
$date = get_post_meta($post_id, '_booking_date', true);
$time = get_post_meta($post_id, '_booking_time', true);
echo esc_html(trim($date . ' ' . $time));
} else {
echo esc_html(get_the_date('Y-m-d H:i', $post_id));
}
break;
case 'contact':
$email_key = get_post_type($post_id) === 'booking_request' ? '_booking_email' : '_lead_email';
$phone_key = get_post_type($post_id) === 'booking_request' ? '_booking_phone' : '_lead_phone';
echo esc_html((string) get_post_meta($post_id, $email_key, true));
$phone = get_post_meta($post_id, $phone_key, true);
if ($phone) {
echo '<br>' . esc_html((string) $phone);
}
break;
case 'format':
echo esc_html((string) get_post_meta($post_id, '_booking_format', true));
break;
case 'focus':
echo esc_html((string) get_post_meta($post_id, '_lead_focus', true));
break;
case 'role':
echo esc_html((string) get_post_meta($post_id, '_testimonial_role', true));
break;
}
}
add_action('manage_booking_request_posts_custom_column', 'coaching_mvp_render_admin_column', 10, 2);
add_action('manage_lead_capture_posts_custom_column', 'coaching_mvp_render_admin_column', 10, 2);
add_action('manage_testimonial_posts_custom_column', 'coaching_mvp_render_admin_column', 10, 2);
function coaching_mvp_details_meta_box() {
foreach (['booking_request', 'lead_capture'] as $post_type) {
add_meta_box('coaching-mvp-details', 'Submission Details', 'coaching_mvp_details_meta_box_html', $post_type, 'normal', 'high');
}
add_meta_box('coaching-mvp-testimonial-role', 'Testimonial Details', 'coaching_mvp_testimonial_meta_box_html', 'testimonial', 'side');
}
add_action('add_meta_boxes', 'coaching_mvp_details_meta_box');
function coaching_mvp_details_meta_box_html($post) {
if ($post->post_type === 'booking_request') {
$fields = [
'Name' => get_post_meta($post->ID, '_booking_name', true),
'Email' => get_post_meta($post->ID, '_booking_email', true),
'Phone' => get_post_meta($post->ID, '_booking_phone', true),
'Service' => get_post_meta($post->ID, '_booking_service', true),
'Preferred date' => get_post_meta($post->ID, '_booking_date', true),
'Preferred time' => get_post_meta($post->ID, '_booking_time', true),
'Format' => get_post_meta($post->ID, '_booking_format', true),
'Goal' => get_post_meta($post->ID, '_booking_goal', true),
'Extra notes' => get_post_meta($post->ID, '_booking_message', true),
];
} else {
$fields = [
'Name' => get_post_meta($post->ID, '_lead_name', true),
'Email' => get_post_meta($post->ID, '_lead_email', true),
'Phone' => get_post_meta($post->ID, '_lead_phone', true),
'Company / role' => get_post_meta($post->ID, '_lead_company', true),
'Focus area' => get_post_meta($post->ID, '_lead_focus', true),
'Message' => get_post_meta($post->ID, '_lead_message', true),
];
}
echo '<div class="coaching-admin-meta">';
foreach ($fields as $label => $value) {
echo '<p><strong>' . esc_html($label) . ':</strong><br>' . nl2br(esc_html((string) $value)) . '</p>';
}
echo '</div>';
}
function coaching_mvp_testimonial_meta_box_html($post) {
wp_nonce_field('coaching_testimonial_meta', 'coaching_testimonial_meta_nonce');
$role = get_post_meta($post->ID, '_testimonial_role', true);
echo '<p><label for="coaching-testimonial-role"><strong>Role / context</strong></label></p>';
echo '<input type="text" id="coaching-testimonial-role" name="coaching_testimonial_role" value="' . esc_attr((string) $role) . '" style="width:100%;" />';
echo '<p class="description">Example: Founder, Sample Client</p>';
}
function coaching_mvp_save_testimonial_meta($post_id) {
if (!isset($_POST['coaching_testimonial_meta_nonce']) || !wp_verify_nonce(wp_unslash($_POST['coaching_testimonial_meta_nonce']), 'coaching_testimonial_meta')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (isset($_POST['coaching_testimonial_role'])) {
update_post_meta($post_id, '_testimonial_role', sanitize_text_field(wp_unslash($_POST['coaching_testimonial_role'])));
}
}
add_action('save_post_testimonial', 'coaching_mvp_save_testimonial_meta');
function coaching_mvp_current_request_origin() {
if (defined('WP_CLI') && WP_CLI) {
return null;
}
$host = '';
if (!empty($_SERVER['HTTP_X_FORWARDED_HOST'])) {
$parts = explode(',', (string) $_SERVER['HTTP_X_FORWARDED_HOST']);
$host = trim(end($parts));
} elseif (!empty($_SERVER['HTTP_HOST'])) {
$host = trim((string) $_SERVER['HTTP_HOST']);
}
if ($host === '' || preg_match('/[^a-z0-9\-\.:\[\]]/i', $host)) {
return null;
}
$scheme = 'http';
if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
$parts = explode(',', (string) $_SERVER['HTTP_X_FORWARDED_PROTO']);
$candidate = strtolower(trim(end($parts)));
if (in_array($candidate, ['http', 'https'], true)) {
$scheme = $candidate;
}
} elseif (!empty($_SERVER['REQUEST_SCHEME']) && in_array($_SERVER['REQUEST_SCHEME'], ['http', 'https'], true)) {
$scheme = $_SERVER['REQUEST_SCHEME'];
} elseif (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
$scheme = 'https';
}
return $scheme . '://' . $host;
}
function coaching_mvp_should_replace_local_host($url) {
$host = wp_parse_url($url, PHP_URL_HOST);
return in_array($host, ['localhost', '127.0.0.1', '::1'], true);
}
function coaching_mvp_replace_local_origin($url) {
$origin = coaching_mvp_current_request_origin();
if (!$origin || !coaching_mvp_should_replace_local_host($url)) {
return $url;
}
$path = (string) wp_parse_url($url, PHP_URL_PATH);
$query = wp_parse_url($url, PHP_URL_QUERY);
$fragment = wp_parse_url($url, PHP_URL_FRAGMENT);
$rebuilt = rtrim($origin, '/') . $path;
if ($query) {
$rebuilt .= '?' . $query;
}
if ($fragment) {
$rebuilt .= '#' . $fragment;
}
return $rebuilt;
}
function coaching_mvp_filter_option_home($value) {
return coaching_mvp_replace_local_origin((string) $value);
}
add_filter('option_home', 'coaching_mvp_filter_option_home');
add_filter('option_siteurl', 'coaching_mvp_filter_option_home');
function coaching_mvp_filter_generated_url($url) {
return coaching_mvp_replace_local_origin((string) $url);
}
add_filter('home_url', 'coaching_mvp_filter_generated_url', 10, 1);
add_filter('site_url', 'coaching_mvp_filter_generated_url', 10, 1);
add_filter('content_url', 'coaching_mvp_filter_generated_url', 10, 1);
add_filter('plugins_url', 'coaching_mvp_filter_generated_url', 10, 1);
add_filter('includes_url', 'coaching_mvp_filter_generated_url', 10, 1);
add_filter('rest_url', 'coaching_mvp_filter_generated_url', 10, 1);
add_filter('network_home_url', 'coaching_mvp_filter_generated_url', 10, 1);
add_filter('network_site_url', 'coaching_mvp_filter_generated_url', 10, 1);
function coaching_mvp_replace_local_origin_in_html($html) {
$origin = coaching_mvp_current_request_origin();
if (!$origin || !is_string($html) || $html === '') {
return $html;
}
return str_replace(
['http://localhost', 'https://localhost', 'http://127.0.0.1', 'https://127.0.0.1'],
$origin,
$html
);
}
function coaching_mvp_filter_rendered_block_html($block_content) {
if (is_admin()) {
return $block_content;
}
return coaching_mvp_replace_local_origin_in_html($block_content);
}
add_filter('render_block', 'coaching_mvp_filter_rendered_block_html', 10, 1);