Plugin Settings
Lowercase letters and digits, words separated by single hyphens (
my-plugin).Use a valid PHP namespace such as
Acme\Tools.Use a valid PHP class name such as
Plugin.WordPress blocks the activation while a required plugin is missing or inactive.
The output is a plugin folder named after the slug: the main file
<slug>.php, readme.txt for wordpress.org and optionally uninstall.php. The Text Domain must match the plugin directory name. The main file gets a real PHP namespace with a final singleton class, declare(strict_types=1) and a defined( 'ABSPATH' ) || exit; guard. No load_plugin_textdomain() is needed: WordPress 6.8+ loads translations from the Domain Path automatically. Tested up to and Stable tag belong in readme.txt, not in the plugin header.
Generated files
Theme Settings
Lowercase letters and digits, words separated by single hyphens (
my-theme).Empty = standalone theme. For a child theme: the parent's directory name (the child's own slug must differ from it). A child theme gets no templates and enqueues its own
style.css (a classic child optionally the parent's, too). A child of a block theme (e.g. twentytwentyfive) is a block theme itself: check Block Theme.Suggested from the options until you edit it. Empty = no
Tags header.Standalone classic themes always get
index.php, header.php (wp_head()) and footer.php (wp_footer()); child themes use the parent's templates.In a child theme
get_stylesheet_uri() points to the child's style.css, so such a parent loses its own stylesheet. On: the child registers the parent's style.css (get_parent_theme_file_uri()) under the parent's handle <parent>-style and loads it before its own. Off: the child enqueues only its own style.css, at priority 20 so it loads after the parent's stylesheet — right for parents that load theirs with get_template_directory_uri() or get_parent_theme_file_uri().Only for editor validation and autocomplete (
version stays 3). Older WordPress versions silently ignore newer keys; the version next to an option says since when WordPress applies it.
Child theme:
theme.json gets only $schema, version and empty settings/styles for your own overrides. WordPress merges it onto the parent's theme.json, and presets in the child (palette, gradients, font sizes, font families) replace the parent's whole lists instead of adding to them — the parent's own styles and patterns would lose the colors and fonts they reference. So the parent's palette, fonts and styles stay in effect; the colors, fonts and other theme.json options here, the style variations and the section style (both use this generator's palette) do not apply. Templates and template parts come from the parent theme, too.
Always written: the palette slugs
base/contrast/primary/secondary, a primary-to-secondary gradient and defaultPalette/defaultGradients: false. With the duotone filter defaultDuotone: false shows only this filter in the duotone picker; without it the key is left out and the core duotone presets stay available. Hidden core presets remain defined as CSS variables, only the pickers leave them out.Used until the font file has loaded, or when it is missing.
Sets
typography.textIndent and a 1.5em indent for core/paragraph.Breakpoints:
px, em or rem (em/rem count as 16px), tablet larger than mobile. Without them WordPress uses 480px/782px. @mobile = up to mobile, @tablet = above mobile up to tablet; there is no @desktop.
The slug names the theme folder (and the ZIP root) and gives the function prefix, the style/script handles and the pattern namespace; the text domain should match it (a child theme may reuse its parent's text domain). Translations load automatically (no
load_theme_textdomain()). Tested up to is a theme directory convention.
Generated files
Block Settings
Lowercase letters, digits and hyphens, starting with a letter.
Lowercase letters, digits and hyphens, starting with a letter.
Lowercase letters, digits and hyphens, starting with a letter.
Adds a
block_categories_all filter to the PHP file.
PHP only (WordPress 7.0): one PHP file, no JavaScript.
supports.autoRegister generates the inspector controls for string, number, integer and boolean attributes (enums become a select). No media, InnerBlocks, RichText or HTML sources; the editor preview is ServerSideRender.
Build step: run
npm install --save-dev @wordpress/scripts, then npm run build. The sources live in src/<block>/; wp-scripts writes build/<block>/ and build/blocks-manifest.php, which the PHP file registers.
| Name | Type | Default | Enum | Source | Selector | Attribute | Role | Label | Remove |
|---|
Give text and URL attributes the role
content: in WordPress 7.0 patterns only show content-role attributes of blocks for editing (fallback for a whole block: supports.contentRole, for containers: supports.listView). local attributes are never serialized. Enum = comma-separated values.
Adds a
block_bindings_supported_attributes_<namespace/name> filter (WordPress 6.9) to the PHP file: these attributes can then be bound to a source (core/post-meta, your own) and overridden in synced patterns (Pattern Overrides, WordPress 7.0).
Static block: a bound value only replaces saved markup for attributes with the source
html, rich-text or attribute and a plain tag selector (h2, p, a) — WordPress matches tag names only, a class selector such as .title is ignored.
Dynamic block: bound values arrive in $attributes of the render code — escape them yourself (esc_html(), esc_url()); the generated render code escapes string attributes.
Pattern Overrides: the block needs a name (metadata.name) and the binding __default → core/pattern-overrides inside the synced pattern (“Enable overrides” in the editor). The editor's field picker skips attributes with an enum and only offers fields of the same type.
Many style controls only appear when the theme enables them (
settings.* or appearanceTools in theme.json).Positions:
before, after, firstChild, lastChild. Hooked blocks should be dynamic.
Block name format:
namespace/block-name — lowercase letters, digits and hyphens. The default output is a ready-to-use plugin without a build step: register_block_type( __DIR__ ) reads block.json, index.js uses the window.wp globals, and dynamic blocks render through render.php (no PHP render callback; save() is omitted and defaults to null). apiVersion 3: since WordPress 7.1 the editor is always iframed, so edit() must not touch document/window of the admin page. In static mode save() must return the same markup for the same attributes (placeholder text is not translated, otherwise block validation breaks per locale). PHP only (WordPress 7.0) is the no-JavaScript alternative.
Generated files
Hook Settings
Action callbacks return
void; Filter callbacks must return the (modified) value. Lower priority number = earlier execution (default 10). Accepted Args must match the number of parameters the hook actually passes. Picking a known hook from the list sets the type and the accepted args; with Typed parameters the callback gets the parameter types from the core docblocks (a filter returns the type of its first parameter). Unknown hooks use mixed.
hooks.php
Cron Event Settings
WP-Cron fires on page load, not a real server clock — for reliability, set
DISABLE_WP_CRON in wp-config.php and call wp-cron.php via a real system cron. The hook name is the event identifier for wp_next_scheduled() and wp_clear_scheduled_hook(). Generated code guards against double-scheduling with wp_next_scheduled() and removes every occurrence on deactivation with wp_clear_scheduled_hook(). register_activation_hook() only fires from the main plugin file — choose init for themes, mu-plugins or included files.
cron.php
Asset Settings
Relative path (default per type),
https://… URL, or a raw PHP expression (contains (, $ or ').
The handle must be globally unique — WordPress silently skips re-registering duplicate handles. Dependency handles must match their exact registered names (e.g.
jquery, wp-blocks, wp-element). filemtime versioning uses the file's last-modified timestamp; build/*.asset.php takes dependencies and version from the file @wordpress/scripts writes next to the build. Since WordPress 7.1 the post editor is always iframed: content CSS belongs in enqueue_block_assets or block.json; enqueue_block_editor_assets is for the editor UI around the canvas. Script modules (wp_register_script_module()) take module IDs as dependencies.
enqueue.php
Shortcode Settings
No spaces or
& / < > [ ] = — WordPress rejects such tags.| Attribute Name | Default Value | |
|---|---|---|
Tag names must not contain spaces or
& / < > [ ] =; stick to lowercase letters, numbers, hyphens and underscores. The shortcode is registered on init; the callback always receives an array of attributes (WordPress 6.5+) and null content for self-closing usage. Always sanitize attribute values before output: esc_html(), esc_url(), intval() etc. Shortcodes are not processed in widget text by default; add add_filter( 'widget_text', 'do_shortcode' ) if needed.
shortcode.php
Custom Post Type Settings
Not a valid JSON array of
[ "block/name", { attributes }, [ inner blocks ] ].
Block Bindings (post meta in blocks,
core/post-meta).
Without show_in_rest this post type has no block editor, so its meta cannot be bound or edited there.
Without custom-fields support the REST API leaves out the meta, so the editor neither lists nor shows the fields (enable “custom-fields” under Supports).
Bound blocks in templates still render the values on the front end.
Slug max 20 characters — it becomes the database
post_type value, URL segment and query var. Without show_in_rest there is no block editor and no REST API. Registered meta only reaches the REST API and Block Bindings with custom-fields support. A capability_type other than post/page adds map_meta_cap (core leaves it off otherwise and the capabilities do not work). Hierarchical CPTs support parent–child relationships (like Pages); non-hierarchical do not (like Posts).
cpt.php
Taxonomy Settings
Taxonomy slug max 32 characters.
hierarchical: true → category-like (parent terms, checkbox UI); false → tag-like (free-form text). The block editor panel needs show_in_rest on the taxonomy and on the post type. A default term is created on registration and assigned to new posts; sort keeps the order in which terms were added. Assign to additional post types later with register_taxonomy_for_object_type().
taxonomy.php
Post Status Settings
Slug must not conflict with built-in statuses:
publish, draft, pending, private, trash, auto-draft, inherit. publicly_queryable controls whether front-end single-post URLs are accessible; date_floating gives posts a floating date that is only fixed on publishing (like drafts). The block editor only offers draft, pending, private, scheduled and published — set a custom status via code, Quick Edit or a custom editor plugin. Register on init before any posts are queried.
post-status.php
Meta Box Settings
| Type | Meta Key | Label | |
|---|---|---|---|
Context:
normal = main editing column, side = right sidebar, advanced = below normal. Priority: high = near top within context, low = near bottom. Data is saved on save_post_{post_type} with nonce, capability, revision and autosave checks. Meta boxes render outside the editor iframe (WordPress 7.1) — use wp.data in JavaScript to talk to the editor; for new UI prefer registered post meta with a block editor panel.
meta-box.php
Dashboard Widget Settings
The widget ID must be site-wide unique — duplicate IDs silently overwrite earlier registrations. Capability restricts visibility:
manage_options = admins, edit_posts = editors and above. An optional 4th $control_callback argument to wp_add_dashboard_widget() adds a widget settings form. Column and Priority are the 6th/7th arguments (defaults normal / core); users can still drag the widget elsewhere.
dashboard-widget.php
Settings Page Settings
Every field is a password, and passwords never enter the REST API: the setting is not exposed in
/wp/v2/settings. Add a field of another type to expose it.
| Section ID | Section Title | Description | |
|---|---|---|---|
| Field ID | Label | Type | Section ID | Help text | |
|---|---|---|---|---|---|
Section ID in the Fields table must match an existing section. The Option Name is the key stored in
wp_options — prefix it to avoid conflicts with other plugins. A sanitize_callback is generated per field type (it accepts mixed input: options.php passes null when no field was posted); always review it before deploying. A capability other than manage_options also gets the matching option_page_capability_* filter so saving works. Expose in REST adds a schema built from the fields and also registers the setting on rest_api_init (REST requests never run admin_init). Password fields never print the stored value (an empty field keeps it) and stay out of the REST schema; if every field is a password, the setting is not exposed in REST at all. Help text is shown below the field, or as a toggletip with WordPress 7.1 (wp_get_toggletip(), guarded by function_exists()).
settings-page.php
Admin Bar Settings
| Node ID | Title | Parent ID | href | Meta (optional) | _blank | |
|---|---|---|---|---|---|---|
Parent ID: Leave empty for top-level nodes; set to a Node ID to nest as child. Built-in parents:
href: A plain URL or a PHP expression, e.g.
Meta: extra CSS
Capability: only add the nodes for users with this capability (e.g.
Priority: Higher numbers = later in the bar. Default WP nodes use 0–100; use ≥ 100 to append after them.
my-account, site-name, top-secondary.href: A plain URL or a PHP expression, e.g.
admin_url('admin.php?page=my-page'). PHP expressions (containing ()) are output as-is; plain URLs are wrapped with esc_url().Meta: extra CSS
class, a title tooltip and menu_title (the accessible name of the node's sub menu, WordPress 6.5+). _blank adds target="_blank" with rel="noopener noreferrer".Capability: only add the nodes for users with this capability (e.g.
manage_options); empty = everyone who sees the toolbar.Priority: Higher numbers = later in the bar. Default WP nodes use 0–100; use ≥ 100 to append after them.
admin-bar.php
Contact Methods Settings
| Field Key (becomes user meta key) | Label | |
|---|---|---|
| Field Key to Remove |
|---|
The Field Key becomes the user meta key:
Since WordPress 6.9 core registers no contact methods (
get_user_meta( $user_id, 'twitter', true ). Use only lowercase letters, numbers and underscores.Since WordPress 6.9 core registers no contact methods (
aim, yim and jabber were removed) — Remove only affects keys that other plugins or themes add. The filter receives ( array $methods, ?WP_User $user ).
contact-methods.php
wp-config.php Settings
Only letters, numbers and underscores.
true, false, -1 or a number.
Connector API keys (7.0) are better kept in environment variables of the same name than in
wp-config.php.
Fetches 8 unique 64-char keys from the local generator API and inserts them into the output.
Only settings you choose are written; booleans are unquoted. Place custom constants above the
/* That's all, stop editing! */ line. FORCE_SSL_ADMIN is set automatically for an https site URL; FORCE_SSL_LOGIN (deprecated since 4.0) and WORDPRESS_ENV (not a core constant) are no longer generated. Sensitive values (credentials, salts) should never be committed to version control — use server environment variables or a .env file outside the webroot instead. Rotate salt keys after any security incident.
wp-config.php
Query Builder
| Key | Value | Compare | Type |
|---|
| Taxonomy | Field | Terms | Operator |
|---|
| Taxonomy | Field | Terms | Operator | Children | |
|---|---|---|---|---|---|
| Key | Value | Compare | Type | |
|---|---|---|---|---|
| After (YYYY-MM-DD) | Before (YYYY-MM-DD) | Inclusive | |
|---|---|---|---|
query.php
Post Meta Field Settings
Leave empty to register for all post types.
The meta key is stored in
wp_postmeta — prefix it (e.g. my_plugin_isbn) to avoid conflicts. A leading underscore (_my_plugin_isbn) makes the key protected: hidden from the Custom Fields panel and never bound by Block Bindings (core/post-meta). single: true returns a scalar from get_post_meta(); false returns all values as an array. show_in_rest: true requires an auth_callback and exposes the meta to the Block Editor and REST API (the post type needs custom-fields support). REST needs a schema for array meta (items, otherwise register_meta() fails) and for object meta (properties). The recommended auth callback checks edit_post for the post being edited. Block Bindings (WordPress 6.5+, core/post-meta) show the value in blocks such as Paragraph, Heading, Button or Image: they need show_in_rest, single, and a key without a leading underscore; the label names the field in the editor's field picker, which only offers fields whose type matches the attribute (text = string). With Block Bindings on, an empty key becomes my_meta_key.
post-meta.php
Term Meta Field Settings
Term meta is stored in
wp_termmeta — prefix the key to avoid collisions. Access with get_term_meta( $term_id, 'key', true ) / update_term_meta() / delete_term_meta(). When "Generate form field integration" is enabled, save hooks created_{taxonomy} and edited_{taxonomy} are included automatically. REST needs a schema for array meta (items) and object meta (properties); the recommended auth callback checks edit_term for the term being edited.
term-meta.php
Sidebar Settings
| Area ID (slug) | Name | Description | |
|---|---|---|---|
Widget areas require the Classic Widgets plugin or a non-block theme — block themes use Block Patterns and Template Parts instead.
%1$s in before_widget is replaced with the widget's HTML id; %2$s with its CSS class. Register on widgets_init — calling it earlier may cause widgets not to appear.
sidebars.php
Command Settings
The generated
final class extends WP_CLI_Command; WP-CLI reads PHPDoc to build --help output automatically. Subcommand names use a-z, 0-9 and -; names with a hyphen get an @subcommand tag, the optional alias an @alias tag. Flags are read with Utils\get_flag_value() so --no-flag works. There is no ABSPATH guard on purpose: files loaded via --require or wp-cli.yml run before WordPress defines ABSPATH. Argument syntax in docblocks: <name> = positional required, [<name>] = positional optional, [--key=<value>] = associative, [--flag] = boolean flag. The --- block inside ## OPTIONS defines the default value and allowed options. Load the file early — from a plugin or MU-plugin, not a theme — and keep the WP-CLI guard enabled so the file is a no-op on regular web requests.
Subcommands
No subcommands yet — click "Add Subcommand" above.
wpcli-commands.php
oEmbed Provider Settings
| URL Pattern | oEmbed Endpoint | Regex | |
|---|---|---|---|
URL Pattern: Use a wildcard (
*) for simple matching, e.g. https://example.com/video/*. Enable Regex for advanced PHP regex patterns, e.g. #https?://example\.com/video/\d+#i.
oembed-providers.php
Dashicons Browser 349 icons — click to copy
Code Snippet
Generated Snippet
Ability Settings
Lowercase letters, digits and hyphens only (
a-z 0-9 -).Lowercase letters and digits, single hyphens between them (
my-category).Lowercase letters, digits and hyphens only — no slash, the namespace adds it.
Name:
my-plugin/get-recent-postsWritten for agents: say what the ability does and when to use it — AI clients pick abilities by this text.
| Key | Type | Description | Required | Default | Enum | Minimum | Maximum | minLength | maxLength | Pattern | Items type | Format | Remove |
|---|
Keys are PHP identifiers (letters, digits, underscores). Enum = comma-separated values; array/object defaults as JSON.
required becomes one object-level list; without required properties the schema gets 'default' => array(), so the ability also runs without input. WordPress does not inject property defaults — the generated callback applies them with ??; the JavaScript client does insert them and validates them, so a default that breaks its own constraints is skipped. Patterns are checked by PHP (PCRE) on the server and by JavaScript in the client: type characters instead of \u escapes and use short Unicode classes such as \p{L}. Formats: email, date-time and uuid are checked by WordPress and by the JavaScript client, uri only by the JavaScript client.
| Key | Type | Items type | Format | Description | required | Remove |
|---|
WordPress validates the result against this schema after the execute callback — a mismatch returns
ability_invalid_output instead of the result.Enter a capability name (letters, digits, underscores, hyphens).
Public: anyone — including logged-out visitors and, with REST exposure, anonymous HTTP clients — can run this ability. Only use it for harmless, read-only data.
REST method: GET
Extras
Abilities (WordPress 6.9+) are self-describing units of work for the REST API, MCP and AI agents. The category registers on
wp_abilities_api_categories_init, the ability on wp_abilities_api_init — both registries initialize lazily on first use after init; wp_register_ability() anywhere else fails with a notice. Callbacks take mixed $input: the schema validates but does not convert ('3' passes as integer), so the execute callback casts every value. public (7.1) also writes 'show_in_rest' => true, because WordPress 7.0 only reads show_in_rest. The REST method follows the annotations: readonly ⇒ GET, destructive + idempotent ⇒ DELETE, otherwise POST. public and the lifecycle hooks added in 7.1 do nothing on WordPress 7.0.
Generated files
Icon Settings
Lowercase letters, digits, hyphens and underscores; start and end with a letter or digit.
Icons
| Name | Label | Source | SVG markup | Remove |
|---|
Enter the name without the collection:
star registers my-plugin/star. Source inline passes the markup as content; file adds icons/<name>.svg to the output and registers its file_path (read on first use).
Runs on
init with priority 20, after core registered its icons (priority 10). plus means core/plus.
Icons API (WordPress 7.1): the collection and its icons register on
init; a function_exists() guard skips them on WordPress 7.0. Names are collection/name — lowercase letters, digits, hyphens and underscores; the collection core belongs to WordPress. Sanitizer: only <svg> (class, xmlns, width, height, viewBox, aria-hidden, role, focusable), <path> (fill, fill-rule, d, transform) and <polygon> (fill, fill-rule, points, transform, focusable) survive — convert shapes to paths, outline strokes and use fill="currentColor". A circle-only icon registers fine but renders empty. wp_get_icon() returns the sanitized markup: with label it adds role="img" + aria-label, otherwise aria-hidden="true". The REST routes /wp/v2/icons are only readable for users who can edit posts.
Generated files
Block Bindings Settings
Lowercase letters and digits, words joined by single hyphens (
my-bindings).A PHP namespace such as
Acme\Bindings: letters, digits and underscores, segments joined by \, no leading digit.Lowercase
namespace/name: letters, digits and hyphens with exactly one slash.Blocks refer to it in
metadata.bindings.<attribute>.source.
Context (
uses_context)
postId and postType are always included: the values are post meta. termId/taxonomy come from a Terms Query (core/term-template).Context keys that a parent block provides (
providesContext); the value callback reads them from $block_instance->context.The meta is registered for these post types. Custom post types need
'supports' => array( 'custom-fields' ) and show_in_rest, otherwise the editor cannot read or save the values.
Fields
Field (args.field) |
Label | Type | Meta key | Sanitize | Remove |
|---|
Block markup selects a field with
"args":{"field":"isbn"}. An empty meta key becomes slug + field in snake case (my_bindings_isbn). The type decides which attributes a field can bind to in the editor: string fields bind to text and URL attributes (paragraph, heading, button, image …), integer/number/boolean fields to attributes of that type (e.g. of your own block); integer fields are offered for number attributes too, such as the image ID (core/image id). An integer, number or boolean field without a stored value returns null, so the block keeps its own attribute value (its default) — on the site and in the editor.
A block name: lowercase
namespace/name with letters, digits and hyphens.
Opts the block into Block Bindings and — since WordPress 7.0 — Pattern Overrides via
block_bindings_supported_attributes_{block-name}. Static blocks: each attribute needs source html, rich-text or attribute with a plain tag selector (h2, not .title). Dynamic blocks receive the bound values in $attributes and must escape them.
Block Bindings:
register_block_bindings_source() (6.5) on init accepts only label, get_value_callback and uses_context; the callback returns null to keep the block's fallback content and repeats the visibility checks of core/post-meta (private or password-protected posts). Editing happens only in JavaScript: registerBlockBindingsSource() (6.7) with getValues, setValues + canUserEditValue, and getFieldsList (6.9) for the field picker; assets/editor.js is a classic script with the dependencies wp-blocks and wp-core-data (never wp-editor: it breaks the widgets editor). The meta is registered with show_in_rest (the editor reads and saves it through the REST API); keys starting with _ are protected meta that core/post-meta and the Custom Fields panel skip. The block_bindings_supported_attributes filters exist since 6.9, Pattern Overrides for such custom blocks since 7.0, bindings for core/list-item since 7.1. Pattern Overrides only work in synced patterns (wp_block) and need metadata.name — not in theme pattern files or unsynced patterns.
Generated files
Block Pattern Settings
Themes: WordPress reads the headers of every
patterns/*.php file. Plugins register each pattern in PHP.Lowercase letters and digits, words joined by single hyphens or underscores (
my-theme).Lowercase letters and digits, words joined by single hyphens or underscores (
hero).
Preset Texts empty = default text
Written as translatable strings with
esc_html_e() and the text domain above: WordPress escapes them when the pattern is loaded, so HTML in a text shows as text.Paste the block markup of the pattern.
Written into the pattern file as it is.
<?php … ?> and <?= … ?> run as PHP each time WordPress loads the pattern, e.g. <?php esc_html_e( 'Hello', 'my-theme' ); ?> for translatable text — you are responsible for valid PHP (an error breaks the pattern, and a fatal one the page; the file declares strict_types=1). Any other <? (such as <?xml) stays plain text.
Core Categories
Registered by WordPress on
init. A pattern without any category is listed under Uncategorized.Lowercase letters and digits, words joined by single hyphens or underscores.
Offers the pattern for these blocks (placeholders, transforms);
core/post-content + post type page makes it a starter pattern for new pages, core/template-part/header one for header parts.Empty = everywhere. Otherwise the pattern is only available while editing these post types.
Templates the pattern fits (offered when a template is created in the Site Editor).
A whole number of pixels, e.g.
1200.
Block patterns: a theme only needs
patterns/<name>.php — WordPress reads its headers (Title and Slug are required) and registers it on init, translating title and description with the theme's text domain. List headers are split at commas and spaces. A plugin registers every pattern with register_block_pattern() on init; filePath (6.5) loads the markup file only when the pattern is used. Own categories need register_block_pattern_category() in both cases — a theme loads inc/block-pattern-categories.php from its functions.php. Patterns are unsynced: inserted blocks become independent copies. With Inserter off the pattern stays registered but hidden, e.g. for templates that place it with <!-- wp:pattern {"slug":"my-theme/hero"} /-->.
Generated files
Block Style Settings
One block or several (6.6): the same style is offered in the Styles panel of each.
Lowercase letters, digits, hyphens and underscores, starting with a letter or digit (
card).A theme color (
var:preset|color|base) or a CSS color (#f5f5f5).A theme color (
var:preset|color|contrast) or a CSS color (#111111).One to four lengths like CSS
padding (1.5rem, 1rem 2rem) or spacing presets (var:preset|spacing|40).A CSS radius (
8px, 0.5rem) or a radius preset (var:preset|border-radius|md).A CSS width (
1px, thin).A theme color (
var:preset|color|contrast) or a CSS color.Empty fields are left out.
var:preset|color|<slug> refers to a color of the active theme's palette and follows it when the palette changes.Letters, digits, hyphens, underscores and dots (
my-plugin-block-styles).Decides how the URL and the path for the
filemtime() version are built.A relative path to a
.css file inside the plugin or theme, without .. or . path segments (assets/block-styles.css).Enter the CSS of the style.
Added with
wp_add_inline_style() to the block's stylesheet (or wp-block-library). Target the class .is-style-<name>.Content of the stylesheet file (an extra file tab below). Target the class
.is-style-<name>.Removes styles other code offers, e.g.
core/quote:plain or core/button:outline. Styles registered in PHP (register_block_style()) are removed with unregister_block_style() in the editor and on the site, including their CSS. Styles from a block.json (all core styles) are only hidden in the editor; their CSS stays. theme.json section styles (e.g. Twenty Twenty-Five core/group:section-1) are hidden in the editor too, but blocks that already use them also lose their look in the editor while the site keeps it — remove those only when no content uses them.
Block styles:
register_block_style() on init adds an entry to the block's Styles panel; choosing it adds the class is-style-<name>. The CSS comes from exactly one source: style_data (6.6) is merged into the theme's global styles like a block style variation in theme.json (presets, editor preview, overridable in the Site Editor); inline_style adds CSS text to the block's stylesheet; style_handle enqueues a registered stylesheet wherever the block appears — the file registers it with wp_register_style() on init, from the plugin (plugins_url( …, __FILE__ )) or the theme (get_theme_file_uri(), a child theme's copy first), versioned with filemtime() so browsers reload it after every change. The label is translated with the context block style label, like the styles in a block.json.
Generated files
Block Variation Settings
Filter: adds the variations to any block registered in PHP (all core blocks,
block.json blocks); a block registered only in JavaScript needs wp.blocks.registerBlockVariation(). File: the variations of your own block, referenced from its block.json.A block name such as
core/group (lowercase, namespace/name).
Variations one registration per row
| Name / Title | Description / Icon (Dashicon) | Attributes JSON object | Inner blocks JSON array | isActive / Keywords | Scope / Default | Remove |
|---|
name: lowercase letters, digits, hyphens and underscores, optionally with one namespace (
my-plugin/books-list); each name only once. The title follows the name until you edit it. icon: a Dashicon name such as id-alt (see the Dashicons browser). attributes: initial attribute values of the inserted block. inner blocks: template form [name, attributes, innerBlocks] or objects {"name":…,"attributes":…,"innerBlocks":…}. isActive: comma-separated attribute names — the block shows as this variation while they equal the values in attributes (dot paths like style.color.text work). keywords: comma-separated. scope: none checked = WordPress default: block + inserter. default: isDefault.
Put
variations.php next to your block's block.json and reference it there (6.7):
"variations": "file:./variations.php". WordPress requires the file the first time the variations are needed and uses the returned array; register_block_type( __DIR__ ) does the rest.
Block variations are presets of an existing block: another title and icon in the inserter, preset attributes and inner blocks. The filter
get_block_type_variations (6.5) adds them in PHP to every block registered on the server (all core blocks and block.json blocks), so no editor script is needed. Scope: inserter lists it in the inserter, transform offers it in the block toolbar's variation switcher, block in placeholders such as the Group or Columns picker. isDefault replaces the block's own inserter entry. Title, description and keywords are translated with the contexts core uses for block.json variations.
block-variations.php
REST Route Settings
Segments of letters, digits, dots, hyphens and underscores separated by single slashes, no slash at the start or end (
my-plugin/v1).Path segments of letters, digits, hyphens and underscores (
/books or /shelves/books).Endpoint:
/wp-json/my-plugin/v1/books/{id}
Methods one handler each
Select at least one method.
Per-object checks need the ID segment: switch it on or pick a capability.
Per object checks
read_post (GET), edit_post (POST, PUT, PATCH) or delete_post (DELETE) against the route's id.Letters, digits, underscores and hyphens (
edit_posts).
Public: anyone — including logged-out visitors and anonymous HTTP clients — can call every method of this route. Use it only for harmless data. With the ID segment, the generated read handler only returns posts the visitor may see, and the edit/delete handlers still check
edit_post/delete_post for the item.
Arguments tick the methods each argument applies to
| Name | Type | Methods | Required | Default | Enum | Minimum | Maximum | Format | Description | Remove |
|---|
No extra arguments yet — the ID segment adds the argument
id itself (integer, minimum 1, required).
WordPress validates and sanitizes every argument with a
type itself (rest_parse_request_arg()) before the permission check and the handler run; an invalid value answers 400 rest_invalid_param, a missing required one 400 rest_missing_callback_param. Each argument is registered only for the handlers of the ticked methods (EDIT = POST, PUT, PATCH); GET handlers also get context (view or edit). array arguments get an items schema, object arguments a properties schema from the key:type list (other keys are then rejected); their defaults are JSON. Enum = comma-separated values. minimum/maximum apply to integer and number, format to strings: date-time, email, hex-color, ip and uuid are validated, uri is only cleaned with sanitize_url(). Defaults go through the same checks on every request that leaves the argument out, so a default that breaks its own constraints is left out.
Lowercase letters, digits, hyphens and underscores, at most 20 characters (
post, book).POST creates a draft of this type (or the status from a
status argument), EDIT updates, DELETE moves it to the trash. The arguments title, content, excerpt and status (strings) fill the post, every other argument is saved as post meta. With the ID segment, POST moves to the collection route.Start with a letter; letters, digits and spaces or underscores (
book, book review).Singular, for names and messages; empty = from the route.
Empty = from the namespace.
Empty = from the namespace.
register_rest_route() runs on rest_api_init. Every handler needs a permission_callback — without one WordPress 5.5+ reports _doing_it_wrong(); use __return_true for public endpoints. A false result answers 401 for guests and 403 for logged-in users. The handlers return WP_REST_Response or WP_Error ([ 'status' => 404 ] becomes the HTTP status). Items come back as id plus title with rendered (get_the_title()) and, only for ?context=edit and users who may edit the post, raw — like core's posts controller. With Real CRUD they also carry what POST and EDIT store (content/excerpt the same way, status, the post meta), and the schema lists exactly these fields. Without Real CRUD the create/edit/delete handlers are safe examples: they return the validated arguments and store or delete nothing — add that code where the TODO says. The route schema is served on OPTIONS requests.
rest-route.php
AI Prompt Settings
PHP does not accept this word as a function name.
Called as
my_plugin_ai_generate( $prompt ); it returns the answer or a WP_Error.A number from 0 to 2.
A whole number of at least 1.
Enter a JSON object.
Emitted as a PHP array and passed to
as_json_response(). The function decodes the answer with json_decode() and returns an array; the provider decides how strictly it follows the schema.Segments of letters, digits, dots, hyphens and underscores separated by single slashes, no slash at the start or end (
my-plugin/v1).Path segments of letters, digits, hyphens and underscores (
/generate).Letters, digits, underscores and hyphens (
edit_posts).A whole number of at least 1.
maxLength of the prompt argument; empty = no limit.Endpoint:
POST /wp-json/my-plugin/v1/generatewp_ai_client_prompt() (WordPress 7.0+) sends the prompt to an AI provider that a provider plugin adds (set up under Settings → Connectors). Without one, is_supported_for_text_generation() is false and the function returns a WP_Error — it never throws. Site owners can switch AI off with define( 'WP_AI_SUPPORT', false ); in wp-config.php or the wp_supports_ai filter; wp_supports_ai() tells you whether AI is available. Every call may be billed by the provider and can take up to the 30-second default timeout (wp_ai_client_default_request_timeout), so call it from a user action, not on every page load. The system instruction is not a security boundary: treat the answer as untrusted text and escape it before output. The REST route is POST only and checks the capability; errors keep their HTTP status via rest_ensure_response(). The REST route rejects prompts longer than Max prompt length characters with 400 before any provider is called. The capability gate adds a wp_ai_client_prevent_prompt filter right before the function's own prompt and removes it in a finally block, so prompts of other plugins, cron and WP-CLI are not affected. No model is picked here: model IDs depend on the provider plugins. WordPress has no JavaScript AI client — call the REST route from the browser.
ai-prompt.php
Admin Notice Settings
Enter the text of the notice.
Plain text is escaped with
esc_html__(). With markup the message goes through __() and wp_kses() with exactly these four tags (only href on links); every link target becomes a sprintf() placeholder, so translators never edit URLs. Admin pages such as options-general.php?page=my-plugin are linked with self_admin_url().Site admin, network admin, user admin, or every admin (
all_).PHP does not accept this word as a function name.
Hooked by name, so other code can
remove_action() it.Screen IDs are lowercase letters, digits, hyphens and underscores (
settings_page_my-plugin, edit-post, dashboard).Compared with
get_current_screen()?->id; separate several IDs with commas.Letters, digits, underscores and hyphens (
manage_options).Users without it see nothing (
current_user_can()).Letters, digits, hyphens and underscores, without spaces or quotes.
CSS class names of letters, digits, hyphens and underscores, separated by spaces.
Only what
wp_kses_post() keeps on a <div>: data-*, nine aria-* attributes (aria-label, aria-live, aria-describedby, aria-labelledby, aria-hidden, aria-expanded, aria-controls, aria-current, aria-details — not every aria-*), role, title, lang, dir, style, tabindex, hidden, popover, align, xml:lang. A name without a value becomes a boolean attribute.wp_admin_notice() (WordPress 6.4+) builds the notice notice-<type> markup and prints it through wp_kses_post(): links and basic formatting survive, but <form>, <input>, <select> and <script> are stripped (a <button> survives, but without a form it submits nothing). For a notice with a form, build the markup with wp_get_admin_notice(), escape every part yourself and echo it. Dismissible only adds the close button: it hides the notice in the browser, and it is back on the next page load — hiding it for good needs your own user meta plus an AJAX handler (not generated here). WordPress moves notices below the page heading; the extra class inline keeps the notice where it is printed, notice-alt gives it a tinted background. network_admin_notices and user_admin_notices only fire in the network or user admin of a multisite; screen IDs there end in -network or -user. Type none gives a plain grey notice without a notice-<type> class.
admin-notice.php
Disclaimer: The generated code is provided solely as a non-binding starting point. No representation or warranty of any kind, express or implied, is made regarding the accuracy, completeness, functionality, security, legal compliance, or fitness for a particular purpose of the generated code. Use of the generated code is entirely at your own risk. You are solely responsible for reviewing, testing, modifying, and validating any code before deploying it in a production environment.
This tool is an independent software product and is not affiliated with, endorsed by, sponsored by, or otherwise associated with WordPress, the WordPress Foundation, or Automattic Inc. “WordPress” is a registered trademark of the WordPress Foundation. All other trademarks, product names, and company names mentioned are the property of their respective owners. Any references to WordPress are for descriptive and compatibility purposes only.
The operator of this tool assumes no liability for any direct, indirect, incidental, consequential, or special damages arising out of or in connection with the use of the generated code or the use of this tool.
This tool is an independent software product and is not affiliated with, endorsed by, sponsored by, or otherwise associated with WordPress, the WordPress Foundation, or Automattic Inc. “WordPress” is a registered trademark of the WordPress Foundation. All other trademarks, product names, and company names mentioned are the property of their respective owners. Any references to WordPress are for descriptive and compatibility purposes only.
The operator of this tool assumes no liability for any direct, indirect, incidental, consequential, or special damages arising out of or in connection with the use of the generated code or the use of this tool.