Skip to content

Connectors: Add a PHP field registry for typed connector configuration#79373

Open
andreilupu wants to merge 1 commit into
WordPress:trunkfrom
andreilupu:feature/register-connector-field
Open

Connectors: Add a PHP field registry for typed connector configuration#79373
andreilupu wants to merge 1 commit into
WordPress:trunkfrom
andreilupu:feature/register-connector-field

Conversation

@andreilupu

Copy link
Copy Markdown
Contributor

What?

Closes #78647

Why?

WordPress 7.0 shipped the Connectors screen, but the only field a connector can surface is a single API key. Connectors that need more — a server URL for a self-hosted service, a default model, an organisation ID — have no supported path today, so authors either build a separate admin page or replace the connector's React card wholesale via the experimental __experimentalRegisterConnector.

This adds the declarative counterpart, mirroring how register_block_type() relates to client-side block registration (as discussed on #75833): the JS renderer stays the escape hatch for complex UI; this is the convenience layer for the common case of a few typed fields.

How?

PHP (lib/compat/wordpress-7.1/)

  • WP_Connector_Field_Registry — stores per-connector fields (separate class because core's WP_Connector_Registry is final; intended to fold into it on the Core side).
  • Public API: register_connector_field(), unregister_connector_field(), wp_get_connector_field(), wp_get_connector_fields(), wp_get_connector_field_value() (resolves env var → constant → option → default).
  • Field args mirror register_setting() / register_meta(): type (data type), control (UI input), label, description, default, sanitize_callback, auth_callback, show_in_rest (bool|array), choices, setting_name, env_var_name, constant_name.
  • Each field is registered with the Settings API and exposed/persisted over /wp/v2/settings; sensitive fields are masked and gated by auth_callback.
  • Back-compat: connectors that declared api_key auth get an implicit api_key field synthesised automatically, reusing the existing option name — no migration, existing UIs unchanged.

JS (packages/connectors, routes/connectors-home)

  • DefaultConnectorSettings renders each field as a typed control (text / url / email / number / password / textarea / select / checkbox, plus a custom slot-fill placeholder) with a single Save button per connector that persists all changed fields in one request.
  • New types: ConnectorField, ConnectorFieldType, ConnectorFieldControl, FieldValueSource.

Testing Instructions

  1. Build: npm install && npm run build, then npm run wp-env start.
  2. In a plugin (or an mu-plugin), on wp_connectors_init, register a field on an existing connector:
    register_connector_field( 'openai', 'organization', array(
        'control' => 'text',
        'label'   => __( 'Organization ID' ),
    ) );
  3. Go to Settings → Connectors, expand the connector, and confirm the field renders, saves, and persists across reload.
  4. Confirm existing api_key-only connectors still render their key field unchanged.

PHP unit tests: npm run test:unit:php -- --filter=Tests_Connector_Field_Registry (39 tests). JS: npm run test:unit packages/connectors (14 tests).

Testing Instructions for Keyboard

  • Tab into the connector's Configure/Edit button (exposes aria-expanded / aria-controls), Enter to expand, Tab through the fields, and Save with Enter/Space.

Screenshots or screencast

I've tried to demonstrate these fields in my own AI Provider for Osaurus plugin, and I've created a temporary branch that adopts the field registry.

And here is the screenshot of that config.

Screenshot 2026-06-20 at 21 13 59
Before After

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code - Opus 4.8
Used for:

  • Review the current implementation of the Connector screen so I can continue in the same logic.
  • Scaffold the PHP registry and the JS renderer based on a specific Spec I've given.
  • Write this description and the @wordpress/connectors package docs
  • Draft the unit tests
  • Two rounds of self-review after my own review between them

Every line has been read and is understood, and I can explain the approach in review. The test suites were actually executed locally (not just generated): Tests_Connector_Field_Registry — 39 passing; packages/connectors — 14 passing; and phpcs / eslint / tsc run clean. All referenced functions, hooks, options, tickets, and PRs were verified to exist.

Open questions for reviewers

This is intentionally a proposal-stage PR; I'd value a steer on:

  1. Global function vs registry method. The existing Connectors API deliberately has no global wp_register_connector() — registration happens via $registry->register() on wp_connectors_init. Should register_connector_field() be a global (as proposed, matching register_setting()), or a registry method for consistency?
  2. Plugin-active gate. Core's settings registration skips connectors whose owning plugin isn't active; should field registration do the same?
  3. Scope. Happy to split into separate PHP-API and JS-rendering PRs if that reviews better.
  4. Dynamic choices. select needs concrete choices at registration; a future choices_callback would serve local-model providers better — in scope here or a follow-up?

@andreilupu andreilupu requested a review from spacedmonkey as a code owner June 20, 2026 18:17
@github-actions

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: andreilupu <euthelup@git.wordpress.org>
Co-authored-by: jeffpaul <jeffpaul@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions

Copy link
Copy Markdown

Warning: Type of PR label mismatch

To merge this PR, it requires exactly 1 label indicating the type of PR. Other labels are optional and not being checked here.

  • Required label: Any label starting with [Type].
  • Labels found: .

Read more about Type labels in Gutenberg. Don't worry if you don't have the required permissions to add labels; the PR reviewer should be able to help with the task.

Adds register_connector_field() so a connector can declare typed config
fields that the Connectors screen renders and persists automatically.

PHP (lib/compat/wordpress-7.1/): WP_Connector_Field_Registry + public API
(register_connector_field / unregister_connector_field / wp_get_connector_field
/ wp_get_connector_fields / wp_get_connector_field_value). Field args mirror
register_setting()/register_meta() — type, control, label, default,
sanitize_callback, auth_callback, show_in_rest (bool|array), choices,
setting_name, env_var_name, constant_name. Settings-API registration, REST
masking + auth gating, and a back-compat shim that synthesises the implicit
api_key field for existing api_key connectors.

JS (packages/connectors, routes/connectors-home): DefaultConnectorSettings
renders each field as a typed control with one Save button per connector
(batched save). New types ConnectorField / ConnectorFieldType /
ConnectorFieldControl / FieldValueSource.

Tests: 39 PHP + 14 JS. Provider-agnostic examples.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@andreilupu andreilupu force-pushed the feature/register-connector-field branch from 6d1140b to 8c36f0b Compare June 20, 2026 18:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Connectors: proposal for a PHP-side field registry for connector configuration

1 participant