Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,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

Expand Down Expand Up @@ -86,8 +86,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
},
Expand Down Expand Up @@ -122,7 +122,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.
Expand Down
4 changes: 2 additions & 2 deletions getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,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
Expand Down Expand Up @@ -67,7 +67,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

Expand Down
15 changes: 15 additions & 0 deletions middleware.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,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 `<head>` 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:
Expand Down
4 changes: 2 additions & 2 deletions modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,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

Expand All @@ -112,7 +112,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

Expand Down
1 change: 1 addition & 0 deletions routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,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 `<head>`
- WordPress's body classes and `is_404()` are left as WordPress resolved them; only routes WordPress does not answer are adjusted (see [Middleware](middleware.md#body-classes-on-laravel-routes))
- They are processed through WordPress's conditional logic
- `Route::wp()` accepts all HTTP verbs
Expand Down
33 changes: 10 additions & 23 deletions server-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,34 +47,21 @@ The fix is to ensure your web server **never resolves `DirectoryIndex`** for the
<a name="apache-configuration"></a>
### 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
<IfModule mod_rewrite.c>
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]
</IfModule>
# 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.

<a name="nginx-configuration"></a>
### Nginx Configuration
Expand Down