CI / Tests (PHP 8.2) (pull_request) Successful in 41s
CI / Tests (PHP 8.1) (pull_request) Successful in 46s
CI / No Debug Code (pull_request) Successful in 2s
CI / PHPStan (pull_request) Successful in 2m45s
CI / Coding Standards (pull_request) Successful in 2m55s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m35s
CI / Build Plugin Zip (pull_request) Skipped
Closes #67 When a student lands on the registration page from the confirmation email (?us_confirmed=1), replace the registration form with the confirmation message and a "Sign in to your account" link — the form is useless at that point and re-submitting would only produce an "account already exists" error. A confirmed-but-unapproved student can already log in (the pending gate only withholds booking), so signing in is the natural next step. The link target follows the booking block's pattern: a loginPageId block attribute (page picker in the editor sidebar) or login_page_id shortcode attribute, falling back to wp_login_url(). The expired-link notice keeps the form as before. Co-Authored-By: Claude Fable 5 <[email protected]>
100 lines
5.7 KiB
Markdown
100 lines
5.7 KiB
Markdown
# 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/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 the "Sign in to your account" link points to after a student confirms their email. `0` = the WordPress login screen. Shortcode equivalent: `[us_student_register login_page_id="…"]`. |
|
|
| `us-scheduler/group-classes` | `offeringId` (number) | `0` | Restrict the page to a single group class, for embedding on a page dedicated to that class. `0` = browse all classes. 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 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.
|
|
|
|
## How it works
|
|
|
|
- **`BlockRegistrar`** (`src/BlockRegistrar.php`) hooks `init` and registers
|
|
each block with `register_block_type()`: a `render_callback` per block, the
|
|
shared editor script (`assets/js/blocks.js`, handle
|
|
`us-scheduler-blocks`), and the front-end stylesheet
|
|
(`assets/css/frontend.css`, handle `us-scheduler`) as the block `style` so
|
|
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 with `wp.serverSideRender`, which fetches the
|
|
server-rendered markup via the `/wp/v2/block-renderer` REST route.
|
|
- **`BlockPreview`** (`src/BlockPreview.php`) supplies static, script-free
|
|
markup for editor previews. `BlockRegistrar::isEditorPreview()` detects the
|
|
block-renderer context via the `REST_REQUEST` constant (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-app` with sample `.us-day` / `.us-slot` rows and
|
|
disabled Book buttons.
|
|
- **Group classes** — `#us-group-app` with a sample `.us-class` card and a
|
|
disabled Enrol button.
|
|
- **Login** — the real `templates/frontend/login-page.php` template (it has
|
|
no request-state dependencies).
|
|
- **Registration** — a disabled sample of the `.us-register-form` fields.
|
|
|
|
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.
|