diff --git a/src/content/docs/advanced/dashboard.md b/src/content/docs/advanced/dashboard.md index 70f8f1b..dc8b2bb 100644 --- a/src/content/docs/advanced/dashboard.md +++ b/src/content/docs/advanced/dashboard.md @@ -50,7 +50,7 @@ php artisan pollora:status Example output: ``` -Pollora v13.34.0 (latest: v13.34.0) ✓ +Pollora v13.34.1 (latest: v13.34.1) ✓ PHP 8.4.12 | Laravel 13.34 | WordPress 7.1 @@ -93,8 +93,8 @@ This outputs the complete system information as a JSON object: ```json { "framework": { - "current": "13.34.0", - "latest": "13.34.0", + "current": "13.34.1", + "latest": "13.34.1", "update_available": false, "development": false }, @@ -129,7 +129,7 @@ This outputs the complete system information as a JSON object: When running a dev branch (`dev-develop`, `13.x-dev`, etc.), the command adapts its output: ``` -Pollora dev-develop (latest stable: v13.34.0) +Pollora dev-develop (latest stable: v13.34.1) ``` No misleading "update available" warning is shown for development installations: `development` is `true` in the JSON output, and Site Health reports a development build instead of comparing it with releases. diff --git a/src/content/docs/advanced/modules.md b/src/content/docs/advanced/modules.md index 6b9495f..c4b9591 100644 --- a/src/content/docs/advanced/modules.md +++ b/src/content/docs/advanced/modules.md @@ -94,7 +94,7 @@ Each module can have its own dependencies defined in `composer.json`, but actual This approach ensures coherent, centralized package management while maintaining modular flexibility. -A module's `require` is merged; its `require-dev` is not (`merge-dev: false`). A module installed with Composer is merged too, and its development tools (PHPUnit, Rector…) would otherwise become requirements of the project: the next `composer install` then removed WordPress core from `public/cms`. Development dependencies belong in the project's own `require-dev`. The skeleton sets it after v13.34.0; an older project adds it to `extra.merge-plugin`. +A module's `require` is merged; its `require-dev` is not (`merge-dev: false`). A module installed with Composer is merged too, and its development tools (PHPUnit, Rector…) would otherwise become requirements of the project: the next `composer install` then removed WordPress core from `public/cms`. Development dependencies belong in the project's own `require-dev`. The skeleton sets it since v13.34.1; an older project adds it to `extra.merge-plugin`. ## Installing a Module with Composer @@ -119,7 +119,7 @@ The skeleton routes it there with one `installer-paths` rule, handled by `compos - **The rule must come last.** `composer/installers` applies the first rule that matches, and a `vendor:` rule ignores the package type: placed first, it would also send Pollora's WordPress plugins (`pollora/mcp-connector`, `pollora/ai-visibility`) to `Modules/`. Last, it only catches what the rules above did not, which are the `pollora/*` modules of type `laravel-library`; Pollora's other packages (`library`, `project`) are not handled by `composer/installers` and stay in `vendor/`. - **A module from another vendor needs its own line**, for instance `"Modules/{$name}/": ["vendor:pollora", "vendor:acme"]`. The rule does not target `type:laravel-library` alone: dozens of ordinary Laravel packages declare that type and would land in `Modules/`. -- The skeleton ships this rule after v13.34.0. A project created from v13.34.0 or earlier adds it to its `composer.json`, last, and `"merge-dev": false` to `extra.merge-plugin` (see Dependency Management). +- The skeleton ships this rule since v13.34.1. A project created from v13.34.0 or earlier adds it to its `composer.json`, last, and `"merge-dev": false` to `extra.merge-plugin` (see Dependency Management). ### Publishing a module diff --git a/src/content/docs/compare.md b/src/content/docs/compare.md index 60c57e3..741cdd9 100644 --- a/src/content/docs/compare.md +++ b/src/content/docs/compare.md @@ -28,7 +28,7 @@ Pollora's own WordPress models are built on **`pollora/colt`, a fork of Corcel** | **Testing** | Laravel's testing tools | Laravel's testing tools | Your setup | Pest, Playwright, linting in GitHub Actions | Your app's tests | | **AI tooling** | [Nectar](/nectar/overview/): guidelines, 9 agent skills and 10 MCP tools, on Laravel Boost | | | | | | **License and price** | MIT, free | MIT, free | MIT, free | One-time purchase: $80 for one site, $240 for unlimited sites | MIT, free | -| **Maturity** (October 2026) | v13.34.0 stable, a young project | v6.3.0, about 2.66M Packagist installs | v11.2.1, about 13.3k GitHub stars | Commercial product from Roots | v9.0.0, about 4.8k GitHub stars | +| **Maturity** (October 2026) | v13.34.1 stable, a young project | v6.3.0, about 2.66M Packagist installs | v11.2.1, about 13.3k GitHub stars | Commercial product from Roots | v9.0.0, about 4.8k GitHub stars | Sources: each project's GitHub repository, Packagist and product page (roots.io/acorn, roots.io/radicle), checked on 1 October 2026. diff --git a/src/content/docs/faq.md b/src/content/docs/faq.md index b13bb2d..17ba774 100644 --- a/src/content/docs/faq.md +++ b/src/content/docs/faq.md @@ -17,7 +17,7 @@ Yes. The framework (`pollora/framework`), the project skeleton (`pollora/pollora ## Is Pollora production ready? -Yes, the current release, v13.34.0, is a stable release, and `composer create-project pollora/pollora` installs it. Pollora has gone through several major versions: Nectar ships upgrade prompts from Pollora 12 to 13. Its community is still small compared with older WordPress tooling, which is worth weighing for long-lived projects. +Yes, the current release, v13.34.1, is a stable release, and `composer create-project pollora/pollora` installs it. Pollora has gone through several major versions: Nectar ships upgrade prompts from Pollora 12 to 13. Its community is still small compared with older WordPress tooling, which is worth weighing for long-lived projects. ## How do Pollora version numbers work? diff --git a/src/content/docs/getting-started/installation.md b/src/content/docs/getting-started/installation.md index 18e723d..5f564cd 100644 --- a/src/content/docs/getting-started/installation.md +++ b/src/content/docs/getting-started/installation.md @@ -29,7 +29,7 @@ number in its `composer.lock` — which is what `create-project` installs from, whatever constraint the `composer.json` carries. So one version number describes an install completely. -The current release is **v13.34.0**, a stable release: a plain +The current release is **v13.34.1**, a stable release: a plain `composer create-project pollora/pollora` installs it. ## Installation Methods @@ -74,7 +74,7 @@ With `--ddev`, the CLI configures DDEV (WordPress project type, PHP 8.4, MariaDB | `--ver=VERSION` | Install a specific version or constraint (e.g. `13.34.0`, `^13.34`) | | `--stable` | Install the latest stable release instead of the latest pre-release | -`pollora new` installs the latest release **including pre-releases**: today that is the stable v13.34.0, and a beta published after it would be picked up. Pass `--stable` to never get a pre-release, or `--ver` to pin an exact version. +`pollora new` installs the latest release **including pre-releases**: today that is the stable v13.34.1, and a beta published after it would be picked up. Pass `--stable` to never get a pre-release, or `--ver` to pin an exact version. ### 2. Composer create-project diff --git a/src/content/docs/getting-started/server-configuration.md b/src/content/docs/getting-started/server-configuration.md index b81cc45..75f0539 100644 --- a/src/content/docs/getting-started/server-configuration.md +++ b/src/content/docs/getting-started/server-configuration.md @@ -54,34 +54,21 @@ The fix is to ensure your web server **never resolves `DirectoryIndex`** for the ### Apache Configuration -The default `.htaccess` shipped with Pollora includes `Options -Indexes` to disable directory listing. To also prevent blank 200 responses from `index.php` files inside directories, add the following rule **before** the "Send Requests To Front Controller" block: +Since v13.34.1, the `.htaccess` shipped with the skeleton (`public/.htaccess`) sends these requests to the front controller, which answers with your site's own 404 page. A project created before that can add the same rule, **before** the "Redirect Trailing Slashes" block: ```apache - - Options -MultiViews -Indexes - - RewriteEngine On - - # Block direct directory browsing. - # All directory requests go through the framework (returns 404), - # except wp-admin which needs DirectoryIndex for its own index.php. - RewriteCond %{REQUEST_FILENAME} -d - RewriteCond %{REQUEST_URI} !^/cms/wp-admin - RewriteCond %{REQUEST_URI} !^/$ - RewriteRule ^ index.php [L] - - # Send Requests To Front Controller... - RewriteCond %{REQUEST_FILENAME} !-d - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule ^ index.php [L] - + # WordPress Content Directories Are Not Pages... + RewriteCond %{REQUEST_FILENAME} -d [OR] + RewriteCond %{REQUEST_FILENAME} /index\.php$ + RewriteRule ^(cms/wp-content|content)(/|$) index.php [L] ``` This ensures that: -- **Files** (CSS, JS, images, fonts) are served directly by Apache -- **Directories** are routed through the framework, which returns 404 -- **`/cms/wp-admin`** is excluded so WordPress admin works normally -- **`/`** (root) is excluded so the front controller's `index.php` is resolved +- **Directories** under `/cms/wp-content/` and `/content/` — and the empty `index.php` WordPress ships in some of them — answer your site's 404 instead of a blank 200 or a 403 +- **Files** in them (plugin CSS and JS, uploads, fonts) are served directly by Apache, as before +- **The rest of the site** is untouched: `/cms/wp-admin/` and the front controller keep their `index.php` + +`Options -Indexes`, also in the shipped `.htaccess`, keeps directory listing off everywhere else. ### Nginx Configuration diff --git a/src/content/docs/routing/middleware.md b/src/content/docs/routing/middleware.md index 6ec51e2..9c10f78 100644 --- a/src/content/docs/routing/middleware.md +++ b/src/content/docs/routing/middleware.md @@ -45,6 +45,21 @@ A route WordPress answers — `Route::wp()` and the template-hierarchy fallback Ensures WordPress shutdown hooks (`shutdown` action, output buffer flushing) are properly executed after the Laravel response is sent. +### WordPressTemplateEnhancement + +Gives a Blade page what WordPress gives a template it includes: its **template enhancement output buffer**. WordPress 7 relies on it for classic themes — block styles load on demand, are printed at `wp_footer` once the page's blocks are known, then are moved back into the `` with `global-styles` through the `wp_template_enhancement_output_buffer` filter. Without it, those styles end up at the bottom of the page, after the content they style. + +The middleware fires `wp_template_enhancement_output_buffer_started` before the view renders, then runs the filter and the `wp_finalized_template_enhancement_output_buffer` action on the HTML of the response. Any plugin built on that filter sees Pollora's pages too. JSON, redirects and streamed responses are left alone, and a site that opted out through `wp_should_output_buffer_template_for_enhancement` keeps its responses as they are. Since v13.34.1. + +A plain Laravel route does not get it. If its view prints `wp_head()` and `wp_footer()`, add the middleware yourself: + +```php +use Pollora\Route\Infrastructure\Middleware\WordPressTemplateEnhancement; + +Route::get('/dashboard', DashboardController::class) + ->middleware(WordPressTemplateEnhancement::class); +``` + ## Creating Custom Middleware Use Artisan to generate a new middleware: diff --git a/src/content/docs/routing/wordpress-routes.md b/src/content/docs/routing/wordpress-routes.md index d0af673..2175880 100644 --- a/src/content/docs/routing/wordpress-routes.md +++ b/src/content/docs/routing/wordpress-routes.md @@ -111,6 +111,7 @@ There are two main methods to define routes in your application: - `WordPressBindings`: Adds WordPress objects (post, query) to the route - `WordPressHeaders`: Manages HTTP headers for WordPress responses - `WordPressShutdown`: Runs WordPress's shutdown hooks before the response is sent + - `WordPressTemplateEnhancement`: Runs WordPress's template enhancement filter on the page, which moves block styles into the `` - WordPress's body classes and `is_404()` are left as WordPress resolved them; only routes WordPress does not answer are adjusted (see [Middleware](/routing/middleware/#body-classes-on-laravel-routes)) - They are processed through WordPress's conditional logic - `Route::wp()` accepts all HTTP verbs diff --git a/src/content/docs/why.md b/src/content/docs/why.md index d9c4303..88b3a25 100644 --- a/src/content/docs/why.md +++ b/src/content/docs/why.md @@ -112,6 +112,6 @@ class ContentHooks **Two frameworks to keep updated.** This is the most common concern, and Pollora's versioning is designed around it. Version numbers follow the Laravel release Pollora is built on: 13.34 means Laravel 13.34. The skeleton and the framework are tagged together, and a skeleton tag pins the framework tag of the same number, so one version number describes an install. WordPress core is a Composer dependency like the rest. For major upgrades, [Nectar](/nectar/overview/) ships upgrade prompts that walk AI coding agents through the steps. -**A smaller community.** Pollora is maintained by AmphiBee and its community is much smaller than that of the Roots projects. The current release, v13.34.0, is stable, but you will find fewer third-party tutorials. +**A smaller community.** Pollora is maintained by AmphiBee and its community is much smaller than that of the Roots projects. The current release, v13.34.1, is stable, but you will find fewer third-party tutorials. If those trade-offs work for you, [install Pollora](/getting-started/installation/) and try it, or read the [FAQ](/faq/). diff --git a/src/pages/index.astro b/src/pages/index.astro index 500f06c..82e9aaf 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -18,7 +18,7 @@ import { readFileSync } from 'node:fs'; import { resolve } from 'node:path'; // Current release, shown in the hero badge and in the structured data -const version = '13.34.0'; +const version = '13.34.1'; const siteUrl = 'https://pollora.dev/'; const ogImage = new URL('/og-image.png', siteUrl).href;