diff --git a/resources/boost/guidelines/core.blade.php b/resources/boost/guidelines/core.blade.php index b288700..15af43a 100644 --- a/resources/boost/guidelines/core.blade.php +++ b/resources/boost/guidelines/core.blade.php @@ -104,7 +104,7 @@ class InternalHelper {} - **WordPress objects** (`WP_Post`, `WP_Query`, `WP_User`) are auto-injected via type hints in controller methods - **Facades**: `Action`, `Filter`, `Ajax`, `Asset`, `Theme`, `PostType`, `Taxonomy`, `Option`, `Ability`, `PostQuery`, `MetaQuery`, `TaxQuery`, `Mail`, `Constant`. There is no `Loop` or `Query` facade: use Sage Directives in Blade, WordPress functions in PHP - **Translations**: `__('Text', 'my-domain')` goes to WordPress's catalogues; `__('key', ['name' => $x])` goes to Laravel; `__('Text')` tries Laravel, then WordPress's `default` domain -- **Blocks**: live in `resources/views/blocks/{slug}`, render with `render.blade.php` by default, and are registered by Pollora — never write a `BlocksServiceProvider` +- **Blocks**: live in `resources/views/blocks/{slug}`, render with `render.blade.php` by default, and are registered by Pollora — never write a `BlocksServiceProvider`; `` in `render.blade.php` marks where inner blocks go, edited in place in the editor (see the `pollora-blocks` skill) - **Which template answered?** With `WP_DEBUG` on, every page carries `` (hierarchy responses only, not `Route::wp()` or Laravel routes) - **CSRF**: WordPress endpoints are excluded from Laravel CSRF — WordPress uses its own nonce system - **Modules**: Use `nwidart/laravel-modules` for large projects — discovery works inside modules automatically diff --git a/resources/boost/skills/pollora-blocks/SKILL.md b/resources/boost/skills/pollora-blocks/SKILL.md index b7b45b6..e49c795 100644 --- a/resources/boost/skills/pollora-blocks/SKILL.md +++ b/resources/boost/skills/pollora-blocks/SKILL.md @@ -18,7 +18,7 @@ Options: - `--theme[=NAME]` — Create in a theme (default: the active theme) - `--plugin=NAME` — Create in a plugin - `--static` — A static block saved in `post_content` (`save.jsx`, no `render.blade.php`) -- `--inner-blocks` — Add InnerBlocks support +- `--inner-blocks` — Add inner blocks: `` in `render.blade.php` (Gutenberg's `InnerBlocks` in `edit.jsx`/`save.jsx` with `--static`) - `--namespace=NS`, `--title=TITLE`, `--category=CAT`, `--icon=ICON`, `--no-view-script`, `--force` - `--dynamic` is deprecated: blocks are dynamic by default @@ -69,30 +69,28 @@ Blocks are **dynamic by default**: `render.blade.php` renders them on each reque } ``` -## Editor Component (edit.jsx) +## Editor Component (edit.jsx) and save -For a dynamic block, the editor should show what the page shows: render the same markup (or use `ServerSideRender`). +A generated dynamic block is edited through the framework's editor runtime, `window.pollora.blocks`, which Pollora loads with every block that has a `render` template (handle `pollora-block-editor`). Nothing to install or import: ```jsx -import { useBlockProps, RichText } from '@wordpress/block-editor'; - -export default function Edit({ attributes, setAttributes }) { - return ( -
- setAttributes({ heading })} - placeholder="Enter heading..." - /> -
- ); -} +// edit.jsx +import metadata from './block.json'; + +export default window.pollora.blocks.bladeEdit(metadata); + +// index.jsx +registerBlockType(metadata.name, { + edit: Edit, + save: window.pollora.blocks.save, // stores the inner blocks, nothing else +}); ``` +`bladeEdit` previews `render.blade.php` through the core block-renderer REST route (again 200 ms after an attribute change) and makes its `` editable in place. Framework v13.32.0-beta.8 and earlier generate `ServerSideRender` and `save: () => null` instead — check `edit.jsx` before assuming. + ## Rendering with Blade (render.blade.php) -The template receives `$attributes` (array), `$content` (inner blocks HTML) and `$block` (`WP_Block`). Blade components work as in any view. +The template receives `$attributes` (array), `$content` (inner blocks HTML), `$block` (`WP_Block`) and `$isPreview` (true while it renders for the editor's preview). Blade components work as in any view. ```blade
'py-16']) !!}> @@ -100,14 +98,35 @@ The template receives `$attributes` (array), `$content` (inner blocks HTML) and {{ $attributes['ctaText'] ?? '' }} - {!! $content !!}
``` - `{{ }}` escapes; use `{!! !!}` only for `get_block_wrapper_attributes()` and `$content`. - For URLs use `esc_url_raw()` inside `{{ }}` — `esc_url()` would be encoded twice. - The render file must stay inside the block directory, or the block renders nothing and a warning is logged. -- A plain `render.php` still works. +- A plain `render.php` still works, with the same variables. + +## Inner Blocks: `` + +Write `` in the template where the inner blocks go (ACF-style). In the editor they are edited right there; on the page they replace the tag, inside a `div` with the tag's `class` (default `pollora-inner-blocks`) — the same `div` the editor renders. + +```blade +
'card']) !!}> +

{{ $attributes['title'] ?? '' }}

+ +
+``` + +- Options are Gutenberg's inner blocks options as attributes: `allowedBlocks`, `template`, `templateLock`, `orientation`, `defaultBlock`, `directInsert`… JSON for arrays/objects (write it with `{{ json_encode(...) }}`, which escapes quotes and `>`), `"true"`/`"false"` for booleans. +- One list per block: only the first tag gets the inner blocks; further tags are dropped. +- The inner blocks are saved in `post_content`; the rest of the block is not, so template changes reach existing blocks. +- In the preview, `$content` is empty and the tag stays for the editor; `