From 925fcac9a20e8aa7954f4c52155c063c61a920d1 Mon Sep 17 00:00:00 2001 From: Olivier Gorzalka Date: Thu, 8 Oct 2026 11:45:00 +0200 Subject: [PATCH] docs: rewrite the pollora-modules skill for the modules overhaul --- CHANGELOG.md | 4 + resources/boost/guidelines/core.blade.php | 6 +- .../boost/skills/pollora-modules/SKILL.md | 155 +++++++----------- 3 files changed, 70 insertions(+), 95 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bd4a2d..e0c0081 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed +- `pollora-modules` skill rewritten for the modules work of the next framework release: `pollora:make:module` and its opt-in layers, `--module` generators, `@pollora/vite-config` and the `module.` asset container, `pollora:module:frontend`, Plugins › Modules, activation connectors and `config/modules.php`, locked modules, Composer modules and `pollora:module:outdated`. Its post type example used `Pollora\Attributes\PostType\PostType`, which does not exist: it is `Pollora\Attributes\PostType` +- Core guidelines list `pollora:make:module`, `pollora:module:connector|frontend|outdated` and `--module` on `pollora:make:block` + ## [1.5.0] - 2026-10-07 ### Added diff --git a/resources/boost/guidelines/core.blade.php b/resources/boost/guidelines/core.blade.php index 9698a6f..fe65239 100644 --- a/resources/boost/guidelines/core.blade.php +++ b/resources/boost/guidelines/core.blade.php @@ -134,7 +134,7 @@ class InternalHelper {} - **Which template answered?** With `WP_DEBUG` on, every page carries `` (hierarchy responses only, not `Route::wp()` or Laravel routes) - **Meta, roles, bindings**: declare a meta with `#[Meta]` on a typed property rather than calling `register_meta()` and casting `get_post_meta()` by hand (`pollora-typed-meta` skill); declare roles with `#[Role]` / `#[ModifyRole]` rather than `add_role()`, and check a capability (`can:`, `@can`) rather than a role (`pollora-roles` skill); bind core blocks to a `#[BlockBinding]` source or `pollora/post-meta` before writing a custom block (`pollora-block-bindings` skill) - **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 +- **Modules**: Use `nwidart/laravel-modules` for large projects — `pollora:make:module` creates a lean module (no provider: discovery works inside modules), built with `@pollora/vite-config`; switch modules with `module:enable|disable` or Plugins › Modules (see the `pollora-modules` skill) ### Available Artisan Commands @@ -142,7 +142,9 @@ class InternalHelper {} - `pollora:env:setup` — Install and configure WordPress - `pollora:make:theme` / `pollora:theme:delete` / `pollora:theme:status` — Themes - `pollora:make:plugin` / `pollora:plugin:list` / `pollora:plugin:status` — Plugins -- `pollora:make:block` — Generate a Gutenberg block (dynamic Blade by default, `--static` for `save.jsx`) +- `pollora:make:block` — Generate a Gutenberg block (dynamic Blade by default, `--static` for `save.jsx`; `--theme`, `--plugin` or `--module`) +- `pollora:make:module` — Generate a lean Laravel module (`--provider`, `--routes`, `--api`, `--config`, `--database`, `--tests`, `--full`, `--no-assets`) +- `pollora:module:connector` / `pollora:module:frontend` / `pollora:module:outdated` — Where module states live (and `--import` into another connector), move a module onto the template's Vite build, check Composer modules for updates - `pollora:make:post-type` / `pollora:make:taxonomy` — Generate post type and taxonomy classes - `pollora:make:action` / `pollora:make:filter` / `pollora:make:hook` — Generate hook classes (`pollora:make:action --async` adds `#[Async]`) - `pollora:async:list` — Asynchronous actions, their driver and options, and where the default driver comes from diff --git a/resources/boost/skills/pollora-modules/SKILL.md b/resources/boost/skills/pollora-modules/SKILL.md index 3fbf4b5..3b604a7 100644 --- a/resources/boost/skills/pollora-modules/SKILL.md +++ b/resources/boost/skills/pollora-modules/SKILL.md @@ -1,137 +1,106 @@ --- name: pollora-modules -description: Develop Laravel Modules (nwidart) within Pollora projects with auto-discovery of post types, taxonomies, hooks, and more. +description: Create and run Laravel Modules (nwidart) in Pollora projects — lean scaffold, shared Vite build, discovery, activation connectors, the Plugins › Modules view and update checks. --- # Pollora Module Development ## When to use this skill -Use this skill when creating or working with Laravel Modules (nwidart/laravel-modules) in a Pollora project to organize large applications into self-contained feature packages. +Use this skill when creating or working with Laravel Modules (nwidart/laravel-modules) in a Pollora project: a module groups a project's own features (post types, hooks, blocks, routes…) and can be switched on and off. ## Creating a Module ```bash -php artisan module:make Portfolio +php artisan pollora:make:module Portfolio ``` -## Module Structure +It downloads the Pollora/module-default template, enables the module, runs `composer dump-autoload` and npm. The default module has **no service provider**: classes in `app/` declared with attributes are discovered. ``` Modules/Portfolio/ -├── app/ -│ ├── Http/ -│ │ └── Controllers/ -│ ├── Models/ -│ │ ├── Project.php # Eloquent model + #[PostType] attribute -│ │ └── ProjectCategory.php # #[Taxonomy] attribute -│ ├── Hooks/ -│ │ └── ProjectHooks.php # #[Action] / #[Filter] attributes -│ ├── Schedule/ -│ │ └── ProjectSync.php # #[Schedule] attribute -│ ├── Api/ -│ │ └── ProjectAPI.php # #[WpRestRoute] attribute -│ └── Providers/ -│ └── PortfolioServiceProvider.php -├── config/ -│ └── config.php -├── database/ -│ ├── migrations/ -│ └── seeders/ -├── resources/ -│ ├── assets/ -│ └── views/ -├── routes/ -│ ├── api.php -│ └── web.php -├── tests/ -├── composer.json -├── module.json -└── package.json +├── app/Cms/Hooks/PortfolioHooks.php # #[Action] example, discovered +├── resources/assets/app.js, app.css # Tailwind CSS v4 (no preflight) +├── resources/views/blocks/ # Gutenberg blocks, registered by Pollora +├── composer.json # PSR-4 Modules\Portfolio\ → app/ +├── module.json # "providers": [] +├── package.json +└── vite.config.js # @pollora/vite-config, type "module" ``` -## Auto-Discovery in Modules +Laravel layers are opt-in: `--provider`, `--routes` (implies `--provider`), `--api` (implies `--routes`), `--config`, `--database`, `--tests` (Pest), `--full`; `--no-assets` for a PHP-only module; `--no-enable`, `--no-npm`, `--offline`. nwidart's `module:make` writes the same lean module unless the project published nwidart's own `config/modules.php`. -All Pollora attributes work inside modules without any additional configuration: +Generate into a module with `--module` — the class lands where nwidart found the module, under the namespace its `composer.json` maps onto `app/`: + +```bash +php artisan pollora:make:post-type Project --module=Portfolio +php artisan pollora:make:block project-card --module=Portfolio # block "portfolio/project-card" +``` + +## Discovery ```php -// Modules/Portfolio/app/Models/Project.php -namespace Modules\Portfolio\Models; +// Modules/Portfolio/app/Cms/PostTypes/Project.php +namespace Modules\Portfolio\Cms\PostTypes; -use Pollora\Attributes\PostType\PostType; -use Pollora\Attributes\PostType\PubliclyQueryable; +use Pollora\Attributes\PostType; use Pollora\Attributes\PostType\HasArchive; +use Pollora\Attributes\PostType\PubliclyQueryable; use Pollora\Attributes\PostType\ShowInRest; #[PostType('project')] #[PubliclyQueryable] #[HasArchive] #[ShowInRest] -class Project -{ - public function configuring(\Pollora\Entity\Domain\Model\PostType $postType): void - { - $postType->labels([ - 'name' => __('Projects', 'portfolio'), - 'singular_name' => __('Project', 'portfolio'), - ]); - } -} +class Project {} ``` -The discovery system scans module directories automatically — no manual registration needed. +Post types, taxonomies, `#[Action]`/`#[Filter]`, `#[WpRestRoute]`, `#[Schedule]` and blocks in `resources/views/blocks` are discovered in every enabled module. Run `php artisan discovery:clear` after adding such a class when the discovery cache is on. -## Module Routes with WordPress Conditions +## Frontend -```php -// Modules/Portfolio/routes/web.php -use Illuminate\Support\Facades\Route; -use Modules\Portfolio\Http\Controllers\ProjectController; +```js +// Modules/Portfolio/vite.config.js +import { defineConfig } from 'vite'; +import pollora from '@pollora/vite-config'; -Route::wp('single', [ProjectController::class, 'show']); -Route::wp('archive', [ProjectController::class, 'index']); +export default defineConfig({ + plugins: [pollora({ type: 'module', name: 'portfolio' })], +}); ``` -## Module Management +Builds into `public/build/module/portfolio` (hot file `public/portfolio.hot`, dev server port 5175 or `VITE_PORT`). Every enabled module with a `vite.config.js` gets the `module.` asset container: -```bash -php artisan module:make Portfolio # Create -php artisan module:enable Portfolio # Enable -php artisan module:disable Portfolio # Disable -php artisan module:list # List all modules -php artisan module:migrate Portfolio # Run migrations -php artisan module:seed Portfolio # Run seeders +```php +Asset::add('portfolio/app', 'app.js')->container('module.portfolio')->toFrontend()->useVite(); ``` -## Module Service Provider +A module made by nwidart's stock `module:make` builds into `public/build-`, where Pollora never looks: `php artisan pollora:module:frontend Portfolio` replaces its `package.json` and `vite.config.js` (keeping `.bak` copies). -```php -namespace Modules\Portfolio\Providers; - -use Illuminate\Support\ServiceProvider; - -class PortfolioServiceProvider extends ServiceProvider -{ - public function register(): void - { - $this->mergeConfigFrom( - module_path('Portfolio', 'config/config.php'), - 'portfolio' - ); - } - - public function boot(): void - { - $this->loadMigrationsFrom(module_path('Portfolio', 'database/migrations')); - $this->loadViewsFrom(module_path('Portfolio', 'resources/views'), 'portfolio'); - } -} +## Enabling and Disabling + +```bash +php artisan module:enable Portfolio +php artisan module:disable Portfolio ``` +Also from **Plugins › Modules** in wp-admin (capability `activate_plugins`). A change applies from the next request. `MODULES_ADMIN_TOGGLE=false` turns the admin switches off. + +Where the state lives is a **connector**, chosen in a published `config/modules.php` (`php artisan vendor:publish --tag=pollora-modules`) — nwidart reads its activator before any provider, so never configure it from a provider: + +- `json` (default): `modules_statuses.json` — reset by a deployment unless committed +- `database`: the `pollora_modules` WordPress option (survives deployments) +- `config`: `MODULES_ENABLED` / `MODULES_DISABLED`, read-only +- your own: a `ModuleStateConnector` class in `connectors..class`, or `ModuleConnectors::extend()` in `bootstrap/app.php` + +`MODULES_LOCKED_ENABLED` / `MODULES_LOCKED_DISABLED` force states. Switch connector with `php artisan pollora:module:connector database --import`, then `MODULES_CONNECTOR=database`. Switches fire `ModuleEnabled` / `ModuleDisabled`. + +## Composer modules and updates + +A module installed with Composer lands in `Modules/` through the skeleton's `installer-paths` rule and carries its package version; local modules have none. `php artisan pollora:module:outdated` checks for newer releases (also shown in Plugins › Modules, Site Health and `pollora:status`). + ## Important Notes -- **Auto-discovery works across modules** — post types, taxonomies, hooks, schedules, and REST routes defined in modules are discovered automatically -- Module views are namespaced: `view('portfolio::project.show')` -- Each module can have its own `composer.json` for module-specific dependencies -- Run `php artisan discovery:clear` after adding attribute-decorated classes in modules -- Modules can define their own Vite config and assets -- Use `module_path('ModuleName', 'relative/path')` to reference module files \ No newline at end of file +- Prefer attributes in `app/` over a service provider; add one with `--provider` only when the module registers services, config or routes +- Module views are namespaced by the lower-case module name: `view('portfolio::project.show')` (with `--provider`) +- `pollora:doctor` checks module builds and activation (fallback connector, states for missing modules, stale caches, ignored `MODULES_*` settings) +- Use `module_path('Portfolio', 'relative/path')` to reference module files