Three sidebar options on the Lesson Booking block, all mirrored as shortcode attributes and carried to the front end as data attributes on #us-booking-app (or as omitted containers): - Lesson type (lessonTypeId / lesson_type) pins the calendar to a single private-lesson type: only the times bookable as it are listed, and it is the only type bookable there, auto-selected on the registration form. A pinned type that is no longer offered says so instead of showing an empty calendar. - Show the lesson-type filter (showTypeFilter / show_filter) drops the "Show Only" control for studios that do not want it. - Sections (displayMode / show) embeds one half of the page — the booking calendar or the student's upcoming lessons — so the two can live on different pages. The script skips the work belonging to a missing half: no availability or catalog request for an upcoming-only embed, no bookings request for a booking-only one. An unrecognised value renders the whole page. The editor preview follows the same setting. Also fixes the expanded filter's first lesson type sharing a line with the "Lesson type" heading — the choices now sit in their own row beneath it. Co-Authored-By: Claude Opus 5 <[email protected]>
8.4 KiB
Editor Blocks
Gutenberg dynamic-block wrappers for the plugin's four front-end shortcodes, so the pages can be previewed and styled inside the block editor instead of appearing as grey shortcode text.
Blocks
| Block | Wraps shortcode | Front-end renderer |
|---|---|---|
us-scheduler/booking |
[us_booking] |
Booking\BookingPage::render() |
us-scheduler/student-login |
[us_student_login] |
Auth\LoginPage::render() |
us-scheduler/student-register |
[us_student_register] |
Auth\RegistrationPage::render() |
us-scheduler/group-classes |
[us_group_classes] |
GroupClass\GroupClassPage::render() |
The shortcodes remain registered for back-compat; blocks and shortcodes share
the same page objects (constructed once in Plugin::boot()), so front-end
output is identical either way. Pasting a shortcode into the block editor
auto-converts it to the matching block via a transforms.from shortcode
transform.
Block options
Four blocks have sidebar (inspector) options:
| Block | Attribute | Default | Effect |
|---|---|---|---|
us-scheduler/booking |
loginPageId (number) |
0 |
Page the "log in to book a lesson" link points to for logged-out visitors. 0 = the WordPress login screen (with a redirect back to the current page). |
us-scheduler/booking |
autoRedirect (boolean) |
false |
Send logged-out visitors straight to the login page instead of showing the link. |
us-scheduler/booking |
lessonTypeId (number) |
0 |
Pin the calendar to a single private-lesson type: only the times bookable as that type are listed, and it is the only type students can book here (auto-selected on the registration form). 0 = every type. Shortcode equivalent: [us_booking lesson_type="…"]. |
us-scheduler/booking |
showTypeFilter (boolean) |
true |
Whether students get the Show Only button that narrows the calendar to chosen lesson types. Unused when a single type is pinned (there is nothing to choose). Shortcode equivalent: [us_booking show_filter="no"]. |
us-scheduler/booking |
displayMode (string) |
both |
Which halves of the page to embed: both, booking (calendar only, no upcoming-lessons panel) or upcoming (the student's lessons only, nothing bookable) — so the two halves can live on different pages. Anything unrecognised falls back to both. Shortcode equivalent: [us_booking show="booking"]. |
us-scheduler/student-login |
bookingPageId (number) |
0 |
Page the "View available lessons" link points to for logged-in visitors, and the post-login redirect target. 0 = the current page. |
us-scheduler/student-login |
autoRedirect (boolean) |
false |
Send logged-in visitors straight to the booking page instead of showing the link. Does nothing until a booking page is chosen. |
us-scheduler/student-register |
loginPageId (number) |
0 |
Page students continue to once registration finishes — the "Sign in to your account" link after they confirm their email, and the "Continue to your account" link an invited student gets on the spot. 0 = the WordPress login screen for the confirmation link, and no link at all for the (already signed-in) invited student. Shortcode equivalent: [us_student_register login_page_id="…"]. |
us-scheduler/student-register |
autoRedirect (boolean) |
false |
Send students straight to that page instead of showing the link. Does nothing until a page is chosen — there is no login-screen fallback here. |
us-scheduler/group-classes |
offeringId (number) |
0 |
Restrict the page to a single group class, for embedding on a page dedicated to that class. The class description is then omitted — only the schedule, instructor, price and enrolment controls are shown, so the surrounding page's own copy is not repeated. 0 = browse all classes, descriptions included. Shortcode equivalent: [us_group_classes offering="…"]. |
The page selects list all published pages; if a chosen page is later deleted,
the blocks fall back to their defaults. The group-classes block's class
select is a dropdown of active group classes fetched from
GET /us-scheduler/v1/offerings?kind=group_class; a stored class that is no
longer offered shows as "Unavailable class #N" rather than silently falling
back to all classes. The booking block's lesson-type select works the same way
against ?kind=private_lesson ("Unavailable lesson type #N"), and the live
page says so plainly when the pinned type has been withdrawn.
The booking block's options reach the front end as data attributes on
#us-booking-app (data-lesson-type, data-type-filter) or as omitted
containers (displayMode), which assets/js/booking.js reads on load — see
lesson-booking.md. Its editor preview follows displayMode, showing the
calendar, the upcoming-lessons panel, or both. The link targets are also available
to the shortcodes as [us_booking login_page_id="…"] and
[us_student_login booking_page_id="…"]; auto-redirect is block-only.
Auto-redirect cannot happen during block rendering (output has already
started, so a Location header cannot be sent). Instead
BlockRegistrar::maybeAutoRedirect() runs on template_redirect, parses the
queried singular post's content for the block (including inside nested
blocks), and redirects when the block opts in. A block whose target is its
own page is ignored to avoid a redirect loop.
The registration block's auto-redirect additionally only fires on a
finished registration — RegistrationPage::isRegistrationComplete(): an
invited student who is now logged in (?us_registered=invite), or a
self-signup back from the emailed confirmation link (?us_confirmed=ready|1).
The intermediate "check your email" step and every failure (a validation
error, ?us_confirmed=expired) stay on the page so the student reads the
message. That check runs before the content is parsed, so an ordinary page
view does not pay for the extra block scan.
How it works
BlockRegistrar(src/BlockRegistrar.php) hooksinitand registers each block withregister_block_type(): arender_callbackper block, the shared editor script (assets/js/blocks.js, handleus-scheduler-blocks), and the front-end stylesheet (assets/css/frontend.css, handleus-scheduler) as the blockstyleso it also loads inside the editor and previews pick up theme styling.assets/js/blocks.js(vanilla JS, no build step) registers the client side of each block — title, icon, keywords, shortcode transform — and renders the editor preview withwp.serverSideRender, which fetches the server-rendered markup via the/wp/v2/block-rendererREST route.BlockPreview(src/BlockPreview.php) supplies static, script-free markup for editor previews.BlockRegistrar::isEditorPreview()detects the block-renderer context via theREST_REQUESTconstant (front-end template rendering never happens inside a REST request) and renders the preview instead of the live page.
Editor preview behaviour
Live pages cannot run in the editor: booking and group classes are populated by JavaScript making authenticated REST calls (and may load Stripe.js), registration requires a valid invite token, and login short-circuits for logged-in users (the editing admin always is). Each preview therefore reproduces the live wrapper elements and CSS classes with representative placeholder content:
- Booking —
#us-booking-appwith sample.us-day/.us-slotrows and disabled Book buttons. - Group classes —
#us-group-appwith a sample.us-classcard and a disabled Enrol button. WhenofferingIdpins a single class the preview drops the sample description, matching what the live page renders in that mode. - Login — the real
templates/frontend/login-page.phptemplate (it has no request-state dependencies). - Registration — a disabled sample of the
.us-register-formfields.
Each preview starts with a .us-editor-note paragraph explaining what the
published page shows instead. The note class only appears in editor previews.
Tests
tests/Unit/BlockRegistrarTest.php— hook registration, block/asset registration, attribute schemas, front-end delegation to the page objects, preview-mode routing, auto-redirect behaviour.tests/Unit/Booking/BookingPageTest.php— logged-out login-link targets and fallbacks.tests/Unit/Auth/LoginPageTest.php— logged-in booking-link targets and fallbacks.tests/Unit/BlockPreviewTest.php— preview markup mirrors the live CSS classes/ids and includes the editor note.