# 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. ## 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, front-end delegation to the page objects, preview-mode routing. - `tests/Unit/BlockPreviewTest.php` — preview markup mirrors the live CSS classes/ids and includes the editor note.