Practice Site Platform Infrastructure
Documentation of the automation, activity tracking, and dashboard infrastructure on practice.baseworks.com. For cross-site tag sync and CRM automation, see Website Ecosystem Overview.
Platform Stack
Section titled “Platform Stack”| Layer | Plugin / Service | Role |
|---|---|---|
| Community | BuddyBoss Platform + Platform Pro + Theme + Child Theme | Community groups, forums, member profiles, messaging |
| LMS | LearnDash | Course structure, lesson access gating |
| Video delivery | Presto Player (Bunny CDN) | Video hosting and playback; fires completion events to Automator |
| Activity database | BW Activity Plugin (wp_bw_activity) | Core activity log — every practice session recorded here; replaced Formidable Form 69 in March 2026 |
| User interface | BW Activity Plugin shortcodes | Dashboard widgets, calendar, activity list, progress bar, smart revisit |
| Automation | Uncanny Automator | Captures Presto video completion events and writes Formidable entries |
| Access control | WP Fusion | Controls visibility of all dashboard sections by tag; also triggers primer_complete tag on Primer course completion (configured in LearnDash course settings) |
| Cross-site sync | WP Remote Users Sync | Syncs user accounts, tags, meta, and login sessions between practice.baseworks.com and baseworks.com in both directions. When a user logs into either site, WPRUS automatically logs them into the other. Configured bidirectionally with login, create, update, delete, password, and meta actions active. See infrastructure note below. |
| Multilingual | WPML | Japanese translation layer for select pages |
| ACF | Advanced Custom Fields | User timezone meta field (read by BW Activity Plugin for date display); course_cluster and related fields on Media Hub posts (used by Snippet 27 / Recipe 22021). GamiPress aggregate points fields abandoned 2026-03-20. |
| Code snippets | codesnippets.pro | Custom PHP snippets extending Formidable views and BuddyBoss |
Dashboard Architecture
Section titled “Dashboard Architecture”The root URL (practice.baseworks.com) is the main dashboard. WP Fusion controls visibility per section:
- Logged out → Shows a login widget only
- Logged in → Shows the full dashboard (sections further gated by tag)
Section 1: The Primer
Section titled “Section 1: The Primer”| Element | Implementation |
|---|---|
| Link to Primer course | Static link |
| Progress bar | Formidable Form 68 (dedicated progress tracking form) |
| Continue button | Uncanny Toolkit for LearnDash — “Resume Button” feature. Displays a button for a specific course that links to the last interacted lesson. This is the only Uncanny Toolkit feature currently in use on the platform. |
| Smart Revisit | Formidable view=18473 of Form 70. Suggests two already-completed lessons for revisiting. |
Note: Form 70 is used exclusively for Smart Revisit. Its purpose is separate from Form 69 (activity log).
Course completion → PRIMER_COMPLETE: The Primer course is configured in LearnDash’s WP Fusion settings to automatically apply the
primer_completetag when a user completes the course. WP Fusion on the practice site syncs the tag to FluentCRM, which fires anupdate_tagswebhook to baseworks.com. This is what triggers the deadline extension recipe (45413) on baseworks.com. See Website Ecosystem Overview for the full flow.
Section 2: Recent Stats / Activity
Section titled “Section 2: Recent Stats / Activity”| Element | Implementation |
|---|---|
| Recent Progress Widget | [bw_activity_bars] — BW Activity Plugin shortcode |
| Recent Activity Widget | [bw_activity_list display=3] — BW Activity Plugin shortcode (shows 3 most recent entries) |
| Link to full history | Links to /practice-history/ |
Section 3: Community
Section titled “Section 3: Community”| Element | Implementation |
|---|---|
| Displayed discussions | [bbp-topic-index-filtered limit=7] — custom shortcode (Code Snippet ID 40) |
Background: The standard BuddyBoss [bbp-topic-index] shortcode shows topics from all forums regardless of user permissions. The custom shortcode filters to only forums the current user can access (using bbp_user_can_view_forum()). Also removes the “Private: ” prefix WordPress adds to private forum titles. Created 2026-01-20.
See changelog entry: sites/practice.baseworks.com/code-snippets/2026-01-20-permission-filtered-topic-index.php
Section 4: Live Sessions
Section titled “Section 4: Live Sessions”Status: Not yet implemented. Infrastructure and programming for live sessions is in development. This needs to be built out as a priority, especially for international Primer marketing. No automation or display logic exists here yet.
Practice History Page
Section titled “Practice History Page”URL: practice.baseworks.com/practice-history/
Visible to all platform subscribers (not just Primer), showing personal practice session history.
| Element | Implementation |
|---|---|
| Timezone settings | Formidable Form 71 |
| Calendar view | [bw_activity_calendar] — BW Activity Plugin shortcode |
| Activity list | [bw_activity_list] — BW Activity Plugin shortcode (full history mode) |
| Total by category | [bw_activity_total category="foundation"], [bw_activity_total category="elements"], etc. |
| Overall total | [bw_activity_total] |
Japanese version (WPML)
Section titled “Japanese version (WPML)”A WPML-translated copy of this page exists for Japanese users. Translation is handled via the lang="ja" attribute on all BW Activity Plugin shortcodes (e.g., [bw_activity_calendar lang="ja"]), which switches all UI text to Japanese. There is currently no Japanese version of the Primer. The Japanese dashboard is minimal — practice-history/ is the main page Japanese users interact with.
Activity Tracking Engine
Section titled “Activity Tracking Engine”The Core Database: wp_bw_activity
Section titled “The Core Database: wp_bw_activity”The BW Activity Plugin maintains a purpose-built wp_bw_activity table as the central activity log. Every practice session becomes a row in this table. Fields include user_id, recorded_at, lesson_id, lesson_label, duration_min, activity_type, cluster, and source. Entries are created by Uncanny Automator Recipe 22021 (see below).
This replaced Formidable Form 69, which stored activity in an EAV model (wp_frm_items + wp_frm_item_metas). Form 69 data was migrated to the new table on 2026-03-20: 2,604 entries, 72 users, back to December 2020. Form 69 remains in place (deactivated) for legacy data access. See Formidable to Custom Plugin — Scalability Audit & Migration Decision for the rationale.
Why not use LearnDash lesson completion? LearnDash lesson completion hooks fire once per lesson (marking a lesson “done”). The Primer is designed for cyclical, recursive engagement — users revisit completed lessons many times. Standard completion events cannot track repeat visits. Presto Player’s video completion event fires every time a video is watched, which is the signal we need.
Activity Recording Recipes
Section titled “Activity Recording Recipes”| ID | Name | Trigger | Status | Purpose |
|---|---|---|---|---|
| 22021 | [Activity] Presto → BW Activity Entry | Presto Player video completion (Bunny CDN) | Active | Creates a wp_bw_activity entry for each video watch via BW Activity Plugin action |
| 18036 | [Activity] Presto Bunny to Formidable Entry | Presto Player video completion (Bunny CDN) | Deactivated 2026-03-20 | Was: creates a Form 69 entry for each video watch |
| 18647 | [Activity] Presto Bunny to Activity Points count | Presto Player video completion (Bunny CDN) | Deactivated 2026-03-20 | Was: maps activity points to ACF user meta fields (GamiPress); ACF aggregate fields abandoned |
| 19551 | [Activity] Manual Entry to Formidable Entry | Manual form submission | Active | Fallback for when automation fails to capture a practice. Used when automation failed AND the session was 60+ minutes. User submits manually. More relevant to Practice Sessions context than Primer. |
Code Snippets (codesnippets.pro)
Section titled “Code Snippets (codesnippets.pro)”Note: practice.baseworks.com uses codesnippets.pro — a different plugin than baseworks.com (which uses no snippet plugin). All snippets exported to the changelog repo at sites/practice.baseworks.com/code-snippets/.
| ID | Name | Status | Purpose |
|---|---|---|---|
| 27 | Add Custom Presto Token for HUB_ID | Active | Adds PRESTOVIDEO_HUB_ID and PRESTOVIDEO_POST_SLUG tokens to Uncanny Automator’s Presto Player trigger. See below. |
| 30 | Add [frm-date] shortcode | Deactivated 2026-03-20 | Was: date shortcode for Formidable views; replaced by BW Activity Plugin |
| 31 | Add custom dailymax type to [frm-stats] | Deactivated 2026-03-20 | Was: custom aggregate type for Formidable stats shortcode; replaced by BW Activity Plugin |
| 32 | Add Formidable Activity Bars for Form 69 | Deactivated 2026-03-20 | Was: activity bar visualizations from Form 69; replaced by [bw_activity_bars] |
| 33 | Add Formidable Activity STREAK | Deactivated 2026-03-20 | Was: streak calculation from Form 69; replaced by [bw_activity_streak] |
| 34 | Add Formidable Activity Dots Shortcode | Deactivated 2026-03-20 | Was: dot-grid visualization from Form 69; replaced by BW Activity Plugin |
| 40 | [bbp-topic-index-filtered] | Active | Permission-filtered BuddyBoss topic index (see Community section above) |
Snippet 27: Add Custom Presto Token for HUB_ID
Section titled “Snippet 27: Add Custom Presto Token for HUB_ID”File: sites/practice.baseworks.com/code-snippets/2025-12-27-presto-custom-token-hub-id.php ✓ exported
Purpose: Presto Player’s built-in Automator trigger tokens do not expose the Media Hub post ID or post slug. This snippet adds two custom tokens:
PRESTOVIDEO_HUB_ID— thepp_video_blockpost ID for the completed videoPRESTOVIDEO_POST_SLUG— thepost_name(URL slug) of that Media Hub post
These tokens are used in Recipe 22021 to read the video_category, lesson_slug, video_duration, and course_cluster ACF fields from the Media Hub post — the source of truth for lesson metadata.
How it works: Reads $video->hub_id from Presto’s normalize_video_data() response, which is the pp_video_block post ID. Supports both the new Automator trigger framework (v6.10+) and the legacy automator_maybe_parse_token filter for backward compatibility.
Why ACF fields are enabled on both lesson and hub post: $video->hub_id consistently returns the hub post ID in current Presto versions, so ACF values are pulled from the hub post. However, in some older Presto configurations or for videos without a dedicated hub post, hub_id could resolve to the LearnDash lesson post ID. Having video_category, lesson_slug, video_duration, and course_cluster registered on both sfwd-lessons and pp_video_block post types ensures the Automator recipe works regardless of which post ID the token resolves to.
Formidable Forms — ID Reference
Section titled “Formidable Forms — ID Reference”| ID | Purpose |
|---|---|
| 68 | Primer progress bar data |
| 69 | wp_bw_activity on 2026-03-20. Form deactivated; kept for legacy data access. |
| 70 | Smart Revisit suggestions |
| 71 | User timezone settings |
WP Remote Users Sync — Configuration Notes
Section titled “WP Remote Users Sync — Configuration Notes”Login sync between baseworks.com and practice.baseworks.com is handled by the WP Remote Users Sync plugin (installed on both sites). When a user logs into either site, WPRUS fires an async login action to the other site, logging them in automatically via a signed redirect token.
Active sync actions (both directions): login, create, update, password, meta. Logout, delete, and role sync are disabled.
How login sync works:
- User logs into Site A
- WPRUS enqueues an async login action and renews an authentication token with Site B
- User’s browser is redirected to Site B’s WPRUS endpoint with a signed payload
- Site B verifies the token, finds the matching user (matched by
user_login), and logs them in
Important: Users must have the same username (user_login) on both sites for sync to work. WPRUS does not match by email. Admin/test accounts created independently on each site may have mismatched usernames and will not sync.
Admin account isolation — do not change this intentionally: Patrick and Asia each have admin accounts with different usernames but the same email across the two sites:
| Person | baseworks.com username | practice username | Shared email |
|---|---|---|---|
| Patrick | basework | patrick | pat@baseworks.com |
| Asia | pandasia | asia | asia@baseworks.com |
Because WPRUS matches by username, it cannot find a counterpart for these admin accounts on the other site. When it tries to create a mirror via the create sync, WordPress rejects it due to the email already being in use. The result is that admin sessions on the two sites are fully independent — logging into one does not affect the other.
This is intentional and should be preserved. Do not “fix” the username mismatch or consolidate the emails. If both sites ever have the same username for an admin, WPRUS will start syncing that admin’s sessions cross-site, which causes the admin to lose privileges on whichever site has the lower role assigned to that username.
BuddyBoss “View As” isolation (resolved 2026-03-27):
BuddyBoss’s “View As” feature calls wp_set_auth_cookie() internally, which triggers WPRUS’s set_logged_in_cookie hook. Without intervention, entering or exiting “View As” on practice.baseworks.com would propagate the impersonated session to baseworks.com, giving access to that member’s WooCommerce billing data. Fixed by mu-plugin bw-suppress-wprus-on-view-as.php which removes WPRUS’s hook for the duration of any switch_to_user / switch_to_olduser request.
Server infrastructure dependency (resolved 2026-03-23):
All three sites (baseworks.com, practice.baseworks.com, crm.baseworks.com) run on the same server (5.180.253.171). WPRUS makes server-to-server HTTPS calls for token renewal. To prevent these from routing unnecessarily through Cloudflare, three entries were added to /etc/hosts on the server, pointing each domain directly to 5.180.253.171. This requires a publicly-trusted SSL certificate on the origin server — a Let’s Encrypt cert was installed by Patrick on 2026-03-23 for this purpose (replacing the previous Cloudflare Origin Certificate). Full investigation and fix details in the changelog entry dated 2026-03-23.
Cert renewal: Let’s Encrypt certs expire every 90 days. Certbot auto-renewal should be configured on the server.
Preparation Guide Page
Section titled “Preparation Guide Page”URL: practice.baseworks.com/preparation-guide/
WP Page ID: 22134
Published: 2026-04-02
Gating: WP Fusion — track-introductory only (page is invisible once the user progresses to track-standard or track-alumni)
Implementation
Section titled “Implementation”The page uses a single Custom HTML block in Gutenberg, not native blocks. All CSS is scoped under .prep-guide to avoid BuddyBoss theme conflicts. The WordPress page title is hidden via .page-id-22134 .entry-title { display: none } since the HTML block includes its own header pill.
Source HTML: Saved in the changelog repo at sites/practice.baseworks.com/page-blocks/preparation-guide-block.html
Sections
Section titled “Sections”- Header pill — dark blue rounded bar with Baseworks hexagon logo + title
- What to Expect — session format, 70min, instructor-led
- How to Prepare — fresh eyes, precise instructions, natural breathing, perceptual focus
- Considerations — 2x3 grid: clothing, equipment, shoes, socks, temperature, food
- The Venue — Proto Studio address bar with directions link, contained photo
- Add to Your Calendar — Google Calendar + Apple/Outlook subscribe buttons (Practice Sessions calendar)
- Event Participation Questionnaire — conceptual dark mock form UI + CTA button to
/members/me/background/ - After Your Introductory Session — styled pricing card ($29-38 CAD, 4 tiers) + link to baseworks.com pricing
- Community Forum — contained screenshot with hairline border
- Resources — 3x2 grid of linked cards to baseworks.com articles
Images
Section titled “Images”All images served from CDN (media.baseworks.com/website/practice-sessions/). No images in WP media library. Originals archived on NAS at /volume1/baseworks/media/website/practice-sessions/originals/.
| Image | Source | Photographer |
|---|---|---|
| baseworks-what-to-expect | Study Group Winter 2026 (_PMP3148) | Andrew Miller |
| baseworks-calendar-practice | Study Group Winter 2026 (_PMP3196) | Andrew Miller |
| baseworks-practice-community-forum | Screenshot (Practice Community page) | — |
| baseworks-standard-pricing | Screenshot (pricing table) | — |
Menu Items
Section titled “Menu Items”Two BuddyBoss menu items link to this page, both gated by WP Fusion to track-introductory:
| Menu | Item ID | Icon | Position |
|---|---|---|---|
| BuddyPanel sidebar (menu 551) | 22168 | bb-icon-clipboard (lined) | 1 |
| Mobile menu (menu 665) | 22169 | bb-icon-clipboard (lined) | 1 |
When a user’s track changes from track-introductory to track-standard (after first session), both the menu item and the page become invisible.
WP Fusion menu meta note: When setting tag visibility on nav menu items via WP-CLI, the wpf-settings meta must include "loggedout" => "loggedin" (the “Who can see this menu link?” dropdown). Without this key, the required tags field is ignored. See the full meta format in the changelog repo source.
Design Notes
Section titled “Design Notes”- Font: Poppins (loaded via
@import) - Accent: #39C3F0 (teal)
- Button style: 40px border-radius, teal fill, white text; hover inverts
- Mobile: header pill stacks vertically (logo above title) below 768px; grid sections stack to single column
- Proto Studio and Community Forum images use
containedclass (padding + rounded corners inside card)
Associated Email
Section titled “Associated Email”The welcome email for new introductory participants links to this page as its primary CTA. See Welcome Email — New Participants for the full template, HTML version, and UTM parameters.
Study Group Preparation Guide Page
Section titled “Study Group Preparation Guide Page”URL: practice.baseworks.com/preparation-guide-sg/
WP Page ID: 22172
Published: 2026-04-02
Gating: WP Fusion — study-group---mtl-2026-spring tag only
Implementation
Section titled “Implementation”Adapted from the Practice Sessions Preparation Guide (page 22134). Same design system (Poppins, .prep-guide scoped CSS, card-based layout) with content adjusted for the Study Group format. Uses a single Custom HTML block in Gutenberg. WordPress page title hidden via .page-id-22172 .entry-title { display: none }.
Source HTML: Saved in the changelog repo at sites/practice.baseworks.com/page-blocks/preparation-guide-sg-block.html
Differences from Practice Sessions Preparation Guide
Section titled “Differences from Practice Sessions Preparation Guide”| Section | Practice Sessions (22134) | Study Group (22172) |
|---|---|---|
| What to Expect | 70 min, instructor-led with real-time feedback | ~100 min, cohort-based, builds on Primer material |
| Calendar | Practice Sessions calendar links | Study Group calendar links |
| After Your Introductory Session | Included (pricing card) | Removed (not applicable) |
| Community Forum | Practice Community forum screenshot | Cohort Group / Forum screenshot (Spring 2026) |
| Resources (first card) | Practice Sessions Program Page | From Three Forms to Twenty-One (article, pending publish) |
Images
Section titled “Images”| Image | CDN Path | Source |
|---|---|---|
| baseworks-guided-practice-star-form-session | study-groups/2026-spring-montreal/ | Winter Study Group media (_PMP3341), Andrew Miller |
| baseworks-study-group-spring-2026-cohort-forum | study-groups/2026-spring-montreal/ | Screenshot (BuddyBoss group page) |
Menu Items
Section titled “Menu Items”Two menu items link to this page, both gated by WP Fusion to study-group---mtl-2026-spring:
| Menu | Item ID | Position |
|---|---|---|
| BuddyPanel sidebar (menu 551) | 22173 | 2 |
| Mobile menu (menu 665) | 22174 | 2 |
When the Spring 2026 cohort concludes, these menu items and the page will only remain visible to users who retain the cohort tag.
Associated Email
Section titled “Associated Email”The Study Group Email 01 (welcome + first assignment) links to this page as a preparation guide CTA. See 02-areas/educational-programs/study-groups/2026 (Spring) Study Group Montreal/emails/email-01-assets/email-01-final.html.
Known Issues / Micro-Issues
Section titled “Known Issues / Micro-Issues”WP Fusion tag-link accumulation for admin organizers
Section titled “WP Fusion tag-link accumulation for admin organizers”Investigated: 2026-03-21 | Priority: Low — no action needed now
When a BuddyBoss group has a WP Fusion “Link with Tag” configured, WP Fusion automatically removes any user from the group if they don’t have the linked tag in FluentCRM — including site admins. The exclude_admins setting in WP Fusion only bypasses content restriction, not group membership sync.
Observed behaviour: Asia (user 2, site admin) was removed from group gid=5 (Montreal Spring 2026 cohort) on 2026-03-14 at first login after the tag link was configured, because her FluentCRM contact did not have the study-group---mtl-2026-spring tag. Re-joining the group automatically applied the tag (via the join_group hook), so subsequent logins are fine.
Why it correlates with Patrick’s edits: Patrick’s group edit triggered nothing directly. The removal happened on Asia’s next login after the tag link was set up on the group — the two events were close in time but causally unrelated.
Scaling concern: As the number of study groups grows, each new group with a tag link will require Asia’s FluentCRM contact to carry that tag (or she risks being removed on her next login after the group is created). With a small number of cohorts this is self-correcting (re-joining restores the tag), but with many simultaneous groups it could become a recurring nuisance.
Options if this becomes a problem:
- Add each cohort tag to Asia’s FluentCRM contact proactively when creating a group
- Configure the group’s “Link with Tag — Group Organizer” field (separate from the regular tag link) — this has slightly different removal logic and may protect organizers
- Submit a WP Fusion feature request to respect
exclude_adminsinupdate_group_access() - Write a small plugin/snippet that hooks
groups_remove_memberand prevents removal of site admins
Open Items / Pending Actions
Section titled “Open Items / Pending Actions”- Export all code snippets (IDs 30–34, 40) from codesnippets.pro to changelog repo at
sites/practice.baseworks.com/code-snippets/ - Design and build Live Sessions infrastructure (dashboard Section 4)
- Decide on timeline for activity log refactoring (custom table vs. Formidable)
- Plan PrimerPrint online feature implementation (see primer-journey-visualizer)
- Audit whether Uncanny Toolkit for LearnDash is used for anything beyond the Resume button — if not, evaluate if the plugin is worth keeping
Related
Section titled “Related”- Website Ecosystem Overview — cross-site tag sync, WP Fusion, Primer deadline management
- BW Activity Plugin — Design & Implementation Plan — full implementation record for the custom activity log plugin
- Formidable to Custom Plugin — Scalability Audit & Migration Decision — archived: the audit and reasoning behind switching from Form 69
- Primer Journey Visualizer — PrimerPrint