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
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ Prefix the change with one of these keywords:

### Changed

- **WordPress.org plugin directory compliance:** PHP functions and hooks renamed from the core-style `wp_*` prefix back to `validation_api_*`. The `wp_*` prefix is reserved for WordPress core; the plugin directory's automated checks flag any plugin that uses it. The mapping is mechanical and one-directional: `wp_register_*_validation_check()` β†’ `validation_api_register_*_check()`, and `wp_validation_*` β†’ `validation_api_*`. The names will be restored to `wp_*` at core-merge time per [docs/gutenberg-alignment/core-pr-migration.md](docs/gutenberg-alignment/core-pr-migration.md). Companion plugins (`validation-api-integration-example`, `validation-api-settings`) updated in lockstep.
- **Gutenberg alignment refactor:** All public API surfaces renamed to core conventions
- PHP registration functions renamed: `wp_register_block_validation_check()`, `wp_register_meta_validation_check()`, `wp_register_editor_validation_check()`
- PHP hooks renamed from `validation_api_*` to `wp_validation_*` (e.g., `wp_validation_check_level`, `wp_validation_check_args`)
- PHP registration functions renamed: `wp_register_block_validation_check()`, `wp_register_meta_validation_check()`, `wp_register_editor_validation_check()` (subsequently renamed to `validation_api_register_*_check()` per the plugin-directory compliance entry above)
- PHP hooks renamed from `validation_api_*` to `wp_validation_*` (e.g., `wp_validation_check_level`, `wp_validation_check_args`) (subsequently renamed back to `validation_api_*` per the plugin-directory compliance entry above)
- JS filter hooks renamed: `editor.validateBlock`, `editor.validateMeta`, `editor.validateEditor`
- Data store renamed from `validation-api` to `core/validation`
- Plugin registration renamed from `registerPlugin('validation-api')` to `registerPlugin('core-validation')`
Expand Down
26 changes: 13 additions & 13 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ Three validation scopes, each with a PHP registry and JS filter:

| Scope | PHP Registry | Registration Function | JS Filter |
|---|---|---|---|
| Block attributes | `ValidationAPI\Block\Registry` | `wp_register_block_validation_check()` | `editor.validateBlock` |
| Post meta fields | `ValidationAPI\Meta\Registry` | `wp_register_meta_validation_check()` | `editor.validateMeta` |
| Editor / document | `ValidationAPI\Editor\Registry` | `wp_register_editor_validation_check()` | `editor.validateEditor` |
| Block attributes | `ValidationAPI\Block\Registry` | `validation_api_register_block_check()` | `editor.validateBlock` |
| Post meta fields | `ValidationAPI\Meta\Registry` | `validation_api_register_meta_check()` | `editor.validateMeta` |
| Editor / document | `ValidationAPI\Editor\Registry` | `validation_api_register_editor_check()` | `editor.validateEditor` |

All three concrete registries extend `ValidationAPI\AbstractRegistry`, which provides shared defaults, level validation, namespace stamping, priority sort, and `wp_validation_check_level` filter application.
All three concrete registries extend `ValidationAPI\AbstractRegistry`, which provides shared defaults, level validation, namespace stamping, priority sort, and `validation_api_check_level` filter application.

All registration functions require `namespace`, `name`, and `error_msg` in the `$args` array. Meta checks also require `meta_key`.

### Severity

Three levels: `error` (blocks save), `warning` (shows feedback), `none` (disabled). Filterable at runtime via `wp_validation_check_level`.
Three levels: `error` (blocks save), `warning` (shows feedback), `none` (disabled). Filterable at runtime via `validation_api_check_level`.

### Data flow

Expand All @@ -39,11 +39,11 @@ PHP registries (Block / Meta / Editor β€” all extend AbstractRegistry)

### Key PHP hooks

- `wp_validation_check_level` β€” Override check severity at runtime (the settings-addon extension point)
- `wp_validation_check_args` / `wp_validation_meta_check_args` / `wp_validation_editor_check_args` β€” Modify check config before registration
- `wp_validation_should_register_check` / `_meta_check` / `_editor_check` β€” Prevent specific checks from registering
- `wp_validation_initialized`, `wp_validation_ready`, `wp_validation_editor_checks_ready` β€” Lifecycle
- `wp_validation_check_registered`, `wp_validation_meta_check_registered`, `wp_validation_editor_check_registered` β€” Post-registration notifications
- `validation_api_check_level` β€” Override check severity at runtime (the settings-addon extension point)
- `validation_api_check_args` / `validation_api_meta_check_args` / `validation_api_editor_check_args` β€” Modify check config before registration
- `validation_api_should_register_check` / `_meta_check` / `_editor_check` β€” Prevent specific checks from registering
- `validation_api_initialized`, `validation_api_ready`, `validation_api_editor_checks_ready` β€” Lifecycle
- `validation_api_check_registered`, `validation_api_meta_check_registered`, `validation_api_editor_check_registered` β€” Post-registration notifications

### JS filters

Expand Down Expand Up @@ -137,7 +137,7 @@ TypeScript: `src/store/constants.ts` is the only `.ts` file. Other modules run a
## Companion plugins (same local `wp-content/plugins/`)

- **validation-api-integration-example** β€” Demo plugin with block, meta, and editor checks. Rebuild with `npm run build` in its directory after any JS filter-name changes.
- **validation-api-settings** β€” Admin settings page. Reads checks from `GET /wp-validation/v1/checks`, lets admins override severity via `wp_validation_check_level`. Rebuild with `npm run build` in its directory after REST path changes.
- **validation-api-settings** β€” Admin settings page. Reads checks from `GET /wp-validation/v1/checks`, lets admins override severity via `validation_api_check_level`. Rebuild with `npm run build` in its directory after REST path changes.

## Conventions

Expand All @@ -154,11 +154,11 @@ External plugins register checks like this:

```php
add_action( 'init', function() {
if ( ! function_exists( 'wp_register_block_validation_check' ) ) {
if ( ! function_exists( 'validation_api_register_block_check' ) ) {
return;
}

wp_register_block_validation_check( 'core/image', [
validation_api_register_block_check( 'core/image', [
'namespace' => 'my-plugin',
'name' => 'alt_text',
'level' => 'error',
Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ Register a validation check in two steps.

```php
add_action( 'init', function () {
if ( ! function_exists( 'wp_register_block_validation_check' ) ) {
if ( ! function_exists( 'validation_api_register_block_check' ) ) {
return;
}

wp_register_block_validation_check( 'core/image', [
validation_api_register_block_check( 'core/image', [
'namespace' => 'my-content-rules',
'name' => 'alt_text',
'level' => 'error',
Expand Down Expand Up @@ -58,9 +58,9 @@ Each registered check falls into one of three scopes, with a matching registrati

| Scope | Validates | PHP | JS filter |
|---|---|---|---|
| **Block** | Attributes on a specific block type | `wp_register_block_validation_check()` | `editor.validateBlock` |
| **Meta** | Post meta fields | `wp_register_meta_validation_check()` | `editor.validateMeta` |
| **Editor** | Document-level concerns (heading hierarchy, required sections) | `wp_register_editor_validation_check()` | `editor.validateEditor` |
| **Block** | Attributes on a specific block type | `validation_api_register_block_check()` | `editor.validateBlock` |
| **Meta** | Post meta fields | `validation_api_register_meta_check()` | `editor.validateMeta` |
| **Editor** | Document-level concerns (heading hierarchy, required sections) | `validation_api_register_editor_check()` | `editor.validateEditor` |

All three route through a single `core/validation` `@wordpress/data` store, so UI components subscribe once and see every issue.

Expand All @@ -72,10 +72,10 @@ All three route through a single `core/validation` `@wordpress/data` store, so U
| `warning` | Yellow indicator. Allows saving. |
| `none` | Skipped entirely. |

Every active check passes through the `wp_validation_check_level` filter at runtime. The core plugin has no storage β€” `wp_options`, admin pages, persistence of any kind are out of scope. Configurability is delegated entirely to the filter:
Every active check passes through the `validation_api_check_level` filter at runtime. The core plugin has no storage β€” `wp_options`, admin pages, persistence of any kind are out of scope. Configurability is delegated entirely to the filter:

```php
add_filter( 'wp_validation_check_level', function ( $level, $context ) {
add_filter( 'validation_api_check_level', function ( $level, $context ) {
// $context => [ 'scope' => 'block', 'block_type' => 'core/image', 'check_name' => 'alt_text' ]
if ( 'block' === $context['scope'] && 'alt_text' === $context['check_name'] ) {
return 'warning'; // soften from error to warning
Expand Down Expand Up @@ -108,7 +108,7 @@ A companion plugin ([validation-api-settings](https://github.com/troychaplin/val

## Related plugins

- **[validation-api-settings](https://github.com/troychaplin/validation-api-settings)** β€” Admin UI for overriding check severity. Hooks `wp_validation_check_level` and persists overrides in `wp_options`. Install only if you want a settings screen; the core plugin runs fine without it.
- **[validation-api-settings](https://github.com/troychaplin/validation-api-settings)** β€” Admin UI for overriding check severity. Hooks `validation_api_check_level` and persists overrides in `wp_options`. Install only if you want a settings screen; the core plugin runs fine without it.
- **[validation-api-integration-example](https://github.com/troychaplin/validation-api-integration-example)** β€” Demo plugin that registers 9 checks (4 block, 3 meta, 2 editor) against a "Band" custom post type. Useful as a reference when writing your own integration.

## Documentation
Expand Down
56 changes: 34 additions & 22 deletions docs/INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ These items were adapted from plugin conventions to core conventions and are now
| `ValidationSidebar` | Consolidated validation results panel |
| `ValidationToolbarButton` | Per-block validation toolbar UI |
| Block/Meta/Editor registries (+ AbstractRegistry base) | Declarative check registration |
| `wp_validation_check_level` filter | Runtime severity override |
| `validation_api_check_level` filter | Runtime severity override |
| `editor.preSavePost` gate | Async save-time safety net layered on `lockPostSaving` |
| REST `wp-validation/v1/checks` | Check introspection for admin tooling |

Expand Down Expand Up @@ -111,13 +111,13 @@ This is where the bulk of the integration lives:
### PHP Side

- New file (e.g., `wp-includes/validation.php`) or extend `wp-includes/blocks.php`
- Registration functions: `wp_register_block_validation_check()`, `wp_register_meta_validation_check()`, `wp_register_editor_validation_check()`
- Registration functions: `validation_api_register_block_check()`, `validation_api_register_meta_check()`, `validation_api_register_editor_check()`
- Registry classes following the `WP_Block_Type_Registry` singleton pattern
- Config export integrated into the editor settings bootstrap via `block_editor_settings_all`

## Current State and Upstream Strategy

The naming alignment refactor is complete. The plugin now uses core-style names for all public API surfaces. The remaining work is the actual Gutenberg contribution, structured as follows:
The naming alignment refactor is complete. JS filters and the store name are core-style and stay as-is at merge. PHP function/hook names use the `validation_api_*` prefix in the standalone plugin (a `wp_*` standalone plugin would fail WordPress.org plugin-check) and switch to `wp_*` at core merge β€” see the table at the bottom of this file. The remaining work is the actual Gutenberg contribution, structured as follows:

### Phase 1: RFC and Data Foundation

Expand All @@ -140,11 +140,11 @@ The naming alignment refactor is complete. The plugin now uses core-style names
**Goal**: Land the server-side check registration system.

**Deliverables**:
- `wp_register_block_validation_check( $block_type, $args )` -- Register checks for block attributes
- `wp_register_meta_validation_check( $post_type, $args )` -- Register checks for post meta
- `wp_register_editor_validation_check( $post_type, $args )` -- Register checks for document state
- `wp_validation_check_level` filter for runtime severity override
- `wp_validation_check_args` filter for check modification before registration
- `validation_api_register_block_check( $block_type, $args )` -- Register checks for block attributes
- `validation_api_register_meta_check( $post_type, $args )` -- Register checks for post meta
- `validation_api_register_editor_check( $post_type, $args )` -- Register checks for document state
- `validation_api_check_level` filter for runtime severity override
- `validation_api_check_args` filter for check modification before registration
- Validation config passed to JS via `block_editor_settings_all` filter

**Check args structure**:
Expand Down Expand Up @@ -203,30 +203,42 @@ The naming alignment refactor is complete. The plugin now uses core-style names
- `block.json` declarative validation rules
- Default check bundles

## Completed API Alignment
## Naming β€” standalone plugin vs. core merge

The following naming changes have been applied throughout the codebase. These reflect the current state of the plugin and the names that will be used in the Gutenberg PR.
The plugin's PHP API uses `validation_api_*` names. At core-merge time, these are renamed to `wp_*` per [docs/gutenberg-alignment/core-pr-migration.md](gutenberg-alignment/core-pr-migration.md). The JS filters and store name already match what core would use and don't need renaming.

The reason for the dual naming: WordPress.org's plugin directory reserves the `wp_*` prefix for core, so a standalone plugin can't ship under those names without triggering plugin-check warnings. The names below reflect the standalone plugin's current state on the left and the target post-merge names on the right.

### PHP

| Old (Plugin) | Current |
| Standalone plugin (current) | Target at core merge |
|---|---|
| `validation_api_register_plugin()` | Removed; `namespace` field in check args |
| `validation_api_register_block_check()` | `wp_register_block_validation_check()` |
| `validation_api_register_meta_check()` | `wp_register_meta_validation_check()` |
| `validation_api_register_editor_check()` | `wp_register_editor_validation_check()` |
| `validation_api_check_level` filter | `wp_validation_check_level` |
| `validation_api_check_args` filter | `wp_validation_check_args` |

### JavaScript

| Old (Plugin) | Current |
| `validation_api_meta_check_args` filter | `wp_validation_meta_check_args` |
| `validation_api_editor_check_args` filter | `wp_validation_editor_check_args` |
| `validation_api_should_register_check` filter | `wp_validation_should_register_check` |
| `validation_api_should_register_meta_check` filter | `wp_validation_should_register_meta_check` |
| `validation_api_should_register_editor_check` filter | `wp_validation_should_register_editor_check` |
| `validation_api_check_registered` action | `wp_validation_check_registered` |
| `validation_api_meta_check_registered` action | `wp_validation_meta_check_registered` |
| `validation_api_editor_check_registered` action | `wp_validation_editor_check_registered` |
| `validation_api_initialized` action | `wp_validation_initialized` |
| `validation_api_ready` action | `wp_validation_ready` |
| `validation_api_editor_checks_ready` action | `wp_validation_editor_checks_ready` |

### JavaScript (no rename β€” already core-style)

| Identifier | Notes |
|---|---|
| `validation_api_validate_block` filter | `editor.validateBlock` |
| `validation_api_validate_meta` filter | `editor.validateMeta` |
| `validation_api_validate_editor` filter | `editor.validateEditor` |
| Store: `validation-api` | `core/validation` |
| `window.ValidationAPI` | Config via `block_editor_settings_all` filter / editor settings |
| `editor.validateBlock` filter | Stays at core merge |
| `editor.validateMeta` filter | Stays at core merge |
| `editor.validateEditor` filter | Stays at core merge |
| Store: `core/validation` | Stays at core merge |
| Config via `block_editor_settings_all` filter / editor settings | Stays at core merge |

### REST API

Expand All @@ -248,7 +260,7 @@ The following naming changes have been applied throughout the codebase. These re

1. **Performance at scale** -- Validating every block change in posts with hundreds of blocks needs benchmarking. The current per-block debouncing (300ms) and single-`useValidationSync` computation pattern help, but core demands higher standards. Polish item 6 (deferred) covers measurement; see [docs/TODO.md](TODO.md).

2. **API permanence** -- Once filter names and function signatures land in core, they cannot change without deprecation cycles. The current naming has been chosen to align with existing core conventions.
2. **API permanence** -- Once filter names and function signatures land in core, they cannot change without deprecation cycles. The standalone plugin uses `validation_api_*` for plugin-directory compliance; the core-merge translation to `wp_*` is mechanical and tracked in [gutenberg-alignment/core-pr-migration.md](gutenberg-alignment/core-pr-migration.md).

3. **Scope creep** -- Discussions may pull in content linting, accessibility auditing, or editorial workflows. The framework/rules boundary must hold.

Expand Down
Loading
Loading