Overview
Classerna is a self-contained course registration plugin for WordPress. It registers two custom post types — idcms_course for the course catalog and idcms_session for individual class sessions — adds a Stripe-backed checkout, a student dashboard, an instructor Collaborator role, and a small suite of admin screens for orders, email logs, and notification subscribers.
Nothing depends on WooCommerce, LearnDash, or a third-party LMS. Course data lives in the standard WordPress posts table; orders and order items live in plugin-owned tables (wp_idcms_orders, wp_idcms_order_items) so you keep ownership of your data and can export it at any time.
Requirements & Installation
Requirements
- WordPress 6.0 or newer
- PHP 7.4 or newer (8.x recommended)
- MySQL 5.7+ or MariaDB 10.3+
- A Stripe account if you plan to charge for enrollment
Install
- Upload
classerna.zipvia Plugins → Add New → Upload Plugin. - Activate. The plugin creates its custom tables on activation and adds the Student + Collaborator roles.
- Visit Classerna → Settings to pick a currency symbol, enable the student dashboard, and (if paid) drop in your Stripe keys.
Creating Courses
A course is a regular WordPress post of type idcms_course with a richer-than-usual editor split into tabs:
| Tab | What lives here |
|---|---|
| Details | Intro copy, byline, delivery type, location, online meeting link, capacity |
| Pricing | Single price, separate in-person/online pricing, or flexible tiered options |
| Schedule | Recurring weekly pattern or specific session dates |
| Sessions | The session posts generated from the schedule, drag-reorderable |
| Registration | Pre-qualifying questions, waivers, registration cutoff |
| Notifications | Coming-soon subscribers for this course |
| FAQs | Per-course question/answer pairs surfaced on the public page |
Categories
Courses use a hierarchical taxonomy called idcms_course_cat. Add categories the usual way (Courses → Categories), assign them on each course, and use the [idcms_category_courses cat="slug"] shortcode to render a single-category list anywhere on your site.
Pricing & Capacity
Three pricing modes on the Pricing tab:
- Single price — one number, applied to all enrollments.
- Separate online & in-person — two numbers, picked at checkout based on the URL's
delivery_typeparameter. - Flexible options — multiple tiers, each with its own price, session count, "must choose sessions" rule, and optional add-on (e.g. a gathering or materials fee).
Capacity is a per-course integer. When the course hits capacity, the front-end form shows "Sold out" and new submissions are rejected at the REST handler too — capacity is enforced server-side, not just in the UI.
Coming Soon
Toggle a course "coming soon" on the Details tab and the public page swaps the checkout form for a "Notify me" form. Subscribers are stored in the wp_idcms_notifications_subscribers table. Flip the course off coming-soon and Classerna queues a notification email to every subscriber.
[idcms_category_notify] shortcode and Classerna will notify them whenever any course in that category goes live.Recurring vs Specific
Each course picks one of two schedule methods:
Recurring
Enter a start date, end date, weekly class days (Mon/Wed/Fri…), and the daily start/end time. Click Generate Sessions and Classerna creates one idcms_session post per matching date.
Specific
Add session rows one at a time — each row has a title, date, and optional start/end time. Order doesn't matter; click Create Sessions and the session posts appear in the Sessions Manager below where you can drag-reorder them.
Sessions
A session is a regular WordPress post of type idcms_session. It belongs to one course (via the _session_course_id meta) and stores its own date, time, location, online toggle, and optional meeting link. Sessions can be drag-reordered on the parent course's Sessions tab — the order is saved server-side via the idcms_save_session_order AJAX action.
Session Materials
Each session can carry materials — uploaded files, video links, or external URLs. Access is gated to enrolled students; file URLs go through a permission-checked proxy rather than a guessable direct URL, so a student who isn't enrolled can't share the link to bypass the paywall.
Registration Questions
Each course can require pre-qualifying questions at checkout. As of 2.14.14, three answer types are supported:
- Free text — renders as a
<textarea>. Use for open-ended answers. - Yes / No — renders as a pair of pill buttons. The stored answer is the literal string "Yes" or "No".
- Multiple choice — admin enters one option per line (e.g. None, Beginner, Intermediate, Advanced); checkout renders the options as a row of pill buttons.
Server-side validation tightens the type. Yes/No answers are coerced to one of the two values; multiple-choice answers must match one of the configured options (case-insensitive) or the REST handler rejects the submission.
Answers are stored alongside the order item in the registration_answers JSON column as [{question, answer}] pairs — the admin order-detail and student-detail screens render them as simple key/value rows.
Waivers
Set a default waiver title + body on Settings → Waivers, then optionally override it per course on the Registration tab. When the course has waivers enabled, checkout shows the body inside a scrollable panel with a required acceptance checkbox. The accepted text is captured against the order item so you have a clean audit trail even if you edit the waiver later.
Per-Course FAQs
The FAQs tab on each course holds an ordered list of question/answer pairs. They surface on the public course page in an accordion below the registration form. Drag-reorder works the same way as sessions and registration questions.
Stripe Integration
Classerna talks to Stripe directly using the Payment Intents API. Drop your publishable + secret keys into Settings → Stripe, add your webhook secret, and you're done — there's no separate "Stripe for WordPress" plugin to wire up.
Webhook URL
https://your-site.com/wp-json/idcms/v1/stripe/webhook
Subscribe at minimum to payment_intent.succeeded, payment_intent.payment_failed, and charge.refunded.
Test mode
The Stripe settings panel has a Test/Live toggle. In test mode the test keys are used and the storefront badges the checkout page so you don't accidentally take real money during QA.
Coupon Codes
Create coupons under Classerna → Coupons. Each coupon supports:
- Percentage or fixed-amount discount
- Per-coupon and per-customer usage limits
- Minimum order amount (and an optional max for "between $X and $Y" tiered offers)
- Start/expiry date range
- Course/category restrictions
Refunds & Order Management
Open any order from Classerna → Orders. The detail view shows the line items, the registration answers and waiver capture, the transaction log, and a Refund button that initiates a Stripe refund (partial or full). Successful refunds:
- Mark the order status as
refundedorpartially_refunded - Record a row in the
wp_idcms_transactionstable - Trigger the refund-notification email to the customer
Student & Collaborator Roles
Classerna adds two roles on activation:
idcms_student
Front-end only. Cannot access /wp-admin/ in any meaningful way; the WP admin bar is suppressed automatically (a logged-in student sees a clean public site). Created automatically when someone completes their first paid enrollment.
idcms_collaborator
An instructor role. They get a filtered Classerna admin where the Course, Session, and Order list screens are scoped to only the courses they're assigned to via the _collaborator_user_ids course meta. The wider WP admin (Posts, Pages, Settings) is hidden.
Student Dashboard
Render the dashboard anywhere with the [idcms_my_courses] shortcode. It shows:
- Enrolled courses with quick-link to each course page
- Upcoming sessions calendar
- Downloadable materials per session (gated to enrolment)
- Online-session join links when the session's start time is near
- Account profile + bio for the optional Scholar Directory
Email Templates
Eight customizable templates ship with the plugin, each editable from Settings → Emails:
| Template | Fired by |
|---|---|
| Enrollment | Successful paid or free enrollment |
| New Sessions | Admin generates sessions for an already-enrolled course |
| Refund | Stripe refund completes |
| Coming Soon Notification | Subscribed course goes live |
| Account Created | Welcome email after first enrollment |
| Register Confirmation | User signs up via the public register form |
| Password Reset | Password reset flow |
| Admin Notification | Optional internal copy of any enrollment |
Email Log
Classerna → Email Log shows every email the plugin has dispatched in the last 30 days (the retention window is configurable in code via IDCMS_Email_Log::RETENTION_DAYS). Filter by status, template, or date range; click a row to preview the body; click Resend to send another copy.
Shortcodes
| Shortcode | Renders |
|---|---|
[idcms_courses] | Full course catalog with category + coming-soon filters |
[idcms_my_courses] | The student dashboard (logged-in students only) |
[idcms_category_courses cat="slug"] | Courses scoped to one category |
[idcms_category_notify] | "Notify me when courses in this category open" form |
[idcms_coming_soon id="42"] | Coming-soon badge inline |
[idcms_checkout] | The Classerna checkout (drop this on the checkout page) |
CSV Export
Three CSV exports are available from the admin:
- Students — every student with enrolled-course count and total spend
- Per-course roster — students enrolled in one course, with registration answers as columns
- Orders — filterable by status, date, and course
All exports are UTF-8 with a BOM so Excel opens them with the correct encoding.
Database Tables
Classerna creates the following custom tables on activation (with the standard $wpdb->prefix applied):
| Table | Contents |
|---|---|
wp_idcms_orders | One row per checkout: customer, totals, status, Stripe payment intent |
wp_idcms_order_items | Line items: course title, price, registration answers JSON, waiver text |
wp_idcms_transactions | Stripe transactions tied to orders (charges + refunds) |
wp_idcms_coupons | Discount codes with usage counts |
wp_idcms_email_log | Every email dispatched, pruned after 30 days |
wp_idcms_notifications_subscribers | Coming-soon notification subscribers, per course |
wp_idcms_notifications_subscribers_by_category | Same, but scoped to a category |
Hooks
Action hooks
Fired after a successful Stripe payment is confirmed. Receives the order ID. Used internally to enroll the customer and dispatch the enrollment email.
Fired when a student is added to a course (paid or free). Receives $user_id and $course_id.
Fired when a session's materials are saved. Receives $session_id and the new materials array.
Filter hooks
Filter the array of tag → value replacements before any template is rendered. Add your own merge tags here.
Return false to block enrollment on a specific course (e.g. you've reached a custom capacity rule).
Template Overrides
Classerna will prefer a theme-side template over its bundled one if it finds one at:
your-theme/
└── classerna/
├── single-idcms-course.php
├── archive-idcms-course.php
└── emails/
├── enrollment.php
├── refund.php
└── coming-soon-notification.php
The lookup happens through locate_template() so child themes work the usual way.