Skip to content

Practice Site Platform Infrastructure

Created 2026-03-13
Updated 2026-04-02
Status draft
Tags infrastructurepractice-siteformidable-formslearndashuncanny-automatorbuddybossactivity-trackingtechnical

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.


LayerPlugin / ServiceRole
CommunityBuddyBoss Platform + Platform Pro + Theme + Child ThemeCommunity groups, forums, member profiles, messaging
LMSLearnDashCourse structure, lesson access gating
Video deliveryPresto Player (Bunny CDN)Video hosting and playback; fires completion events to Automator
Activity databaseBW Activity Plugin (wp_bw_activity)Core activity log — every practice session recorded here; replaced Formidable Form 69 in March 2026
User interfaceBW Activity Plugin shortcodesDashboard widgets, calendar, activity list, progress bar, smart revisit
AutomationUncanny AutomatorCaptures Presto video completion events and writes Formidable entries
Access controlWP FusionControls visibility of all dashboard sections by tag; also triggers primer_complete tag on Primer course completion (configured in LearnDash course settings)
Cross-site syncWP Remote Users SyncSyncs 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.
MultilingualWPMLJapanese translation layer for select pages
ACFAdvanced Custom FieldsUser 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 snippetscodesnippets.proCustom PHP snippets extending Formidable views and BuddyBoss

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)
ElementImplementation
Link to Primer courseStatic link
Progress barFormidable Form 68 (dedicated progress tracking form)
Continue buttonUncanny 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 RevisitFormidable 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_complete tag when a user completes the course. WP Fusion on the practice site syncs the tag to FluentCRM, which fires an update_tags webhook to baseworks.com. This is what triggers the deadline extension recipe (45413) on baseworks.com. See Website Ecosystem Overview for the full flow.

ElementImplementation
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 historyLinks to /practice-history/
ElementImplementation
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

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.


URL: practice.baseworks.com/practice-history/

Visible to all platform subscribers (not just Primer), showing personal practice session history.

ElementImplementation
Timezone settingsFormidable 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]

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.


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.

IDNameTriggerStatusPurpose
22021[Activity] Presto → BW Activity EntryPresto Player video completion (Bunny CDN)ActiveCreates a wp_bw_activity entry for each video watch via BW Activity Plugin action
18036[Activity] Presto Bunny to Formidable EntryPresto Player video completion (Bunny CDN)Deactivated 2026-03-20Was: creates a Form 69 entry for each video watch
18647[Activity] Presto Bunny to Activity Points countPresto Player video completion (Bunny CDN)Deactivated 2026-03-20Was: maps activity points to ACF user meta fields (GamiPress); ACF aggregate fields abandoned
19551[Activity] Manual Entry to Formidable EntryManual form submissionActiveFallback 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.

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/.

IDNameStatusPurpose
27Add Custom Presto Token for HUB_IDActiveAdds PRESTOVIDEO_HUB_ID and PRESTOVIDEO_POST_SLUG tokens to Uncanny Automator’s Presto Player trigger. See below.
30Add [frm-date] shortcodeDeactivated 2026-03-20Was: date shortcode for Formidable views; replaced by BW Activity Plugin
31Add custom dailymax type to [frm-stats]Deactivated 2026-03-20Was: custom aggregate type for Formidable stats shortcode; replaced by BW Activity Plugin
32Add Formidable Activity Bars for Form 69Deactivated 2026-03-20Was: activity bar visualizations from Form 69; replaced by [bw_activity_bars]
33Add Formidable Activity STREAKDeactivated 2026-03-20Was: streak calculation from Form 69; replaced by [bw_activity_streak]
34Add Formidable Activity Dots ShortcodeDeactivated 2026-03-20Was: dot-grid visualization from Form 69; replaced by BW Activity Plugin
40[bbp-topic-index-filtered]ActivePermission-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 — the pp_video_block post ID for the completed video
  • PRESTOVIDEO_POST_SLUG — the post_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.


IDPurpose
68Primer progress bar data
69Core activity logLegacy. Data migrated to wp_bw_activity on 2026-03-20. Form deactivated; kept for legacy data access.
70Smart Revisit suggestions
71User 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:

  1. User logs into Site A
  2. WPRUS enqueues an async login action and renews an authentication token with Site B
  3. User’s browser is redirected to Site B’s WPRUS endpoint with a signed payload
  4. 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:

Personbaseworks.com usernamepractice usernameShared email
Patrickbaseworkpatrickpat@baseworks.com
Asiapandasiaasiaasia@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.


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)

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

  1. Header pill — dark blue rounded bar with Baseworks hexagon logo + title
  2. What to Expect — session format, 70min, instructor-led
  3. How to Prepare — fresh eyes, precise instructions, natural breathing, perceptual focus
  4. Considerations — 2x3 grid: clothing, equipment, shoes, socks, temperature, food
  5. The Venue — Proto Studio address bar with directions link, contained photo
  6. Add to Your Calendar — Google Calendar + Apple/Outlook subscribe buttons (Practice Sessions calendar)
  7. Event Participation Questionnaire — conceptual dark mock form UI + CTA button to /members/me/background/
  8. After Your Introductory Session — styled pricing card ($29-38 CAD, 4 tiers) + link to baseworks.com pricing
  9. Community Forum — contained screenshot with hairline border
  10. Resources — 3x2 grid of linked cards to baseworks.com articles

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/.

ImageSourcePhotographer
baseworks-what-to-expectStudy Group Winter 2026 (_PMP3148)Andrew Miller
baseworks-calendar-practiceStudy Group Winter 2026 (_PMP3196)Andrew Miller
baseworks-practice-community-forumScreenshot (Practice Community page)
baseworks-standard-pricingScreenshot (pricing table)

Two BuddyBoss menu items link to this page, both gated by WP Fusion to track-introductory:

MenuItem IDIconPosition
BuddyPanel sidebar (menu 551)22168bb-icon-clipboard (lined)1
Mobile menu (menu 665)22169bb-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.

  • 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 contained class (padding + rounded corners inside card)

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.


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

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”
SectionPractice Sessions (22134)Study Group (22172)
What to Expect70 min, instructor-led with real-time feedback~100 min, cohort-based, builds on Primer material
CalendarPractice Sessions calendar linksStudy Group calendar links
After Your Introductory SessionIncluded (pricing card)Removed (not applicable)
Community ForumPractice Community forum screenshotCohort Group / Forum screenshot (Spring 2026)
Resources (first card)Practice Sessions Program PageFrom Three Forms to Twenty-One (article, pending publish)
ImageCDN PathSource
baseworks-guided-practice-star-form-sessionstudy-groups/2026-spring-montreal/Winter Study Group media (_PMP3341), Andrew Miller
baseworks-study-group-spring-2026-cohort-forumstudy-groups/2026-spring-montreal/Screenshot (BuddyBoss group page)

Two menu items link to this page, both gated by WP Fusion to study-group---mtl-2026-spring:

MenuItem IDPosition
BuddyPanel sidebar (menu 551)221732
Mobile menu (menu 665)221742

When the Spring 2026 cohort concludes, these menu items and the page will only remain visible to users who retain the cohort tag.

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.


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:

  1. Add each cohort tag to Asia’s FluentCRM contact proactively when creating a group
  2. 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
  3. Submit a WP Fusion feature request to respect exclude_admins in update_group_access()
  4. Write a small plugin/snippet that hooks groups_remove_member and prevents removal of site admins

  • 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