PHP Blueprints
Register objects on the vxframework/register action, which runs once during WordPress's init. Objects defined this way are read-only in the dashboard until someone overrides them.
php
use VxFramework\Config\Blueprint\Blueprint;
use VxFramework\Config\Blueprint\Field;
add_action( 'vxframework/register', function ( \VxFramework\Config\Code_Registry $vx ) {
$vx->define(
Blueprint::post_type( 'book' )
->name( 'Book', 'Books' )
->show_in_rest( true )
->has_archive( true )
->permalink_base( 'books' )
);
$vx->define(
Blueprint::taxonomy( 'genre' )
->name( 'Genre', 'Genres' )
->hierarchical()
->show_admin_column()
);
$vx->define(
Blueprint::fieldset( 'book_details' )
->label( 'Book details' )
->on_post_type( 'book' )
->fields( [
Field::text( 'tagline' )->label( 'Tagline' ),
Field::text( 'author_name' )->label( 'Author name' ),
Field::image( 'author_picture' )->label( 'Author picture' ),
Field::select( 'price_range' )->label( 'Price range' )->choices( [
'low' => '$',
'mid' => '$$',
'high' => '$$$',
] ),
Field::repeater( 'opening_hours' )->label( 'Opening hours' )->fields( [
Field::text( 'day' )->label( 'Day' ),
Field::make( 'time', 'opens' )->label( 'Opens' ),
Field::make( 'time', 'closes' )->label( 'Closes' ),
] ),
] )
);
} );Option pages and dictionaries
php
$vx->define(
Blueprint::option_page( 'site_settings' )
->label( 'Site settings' )
->submenu( 'options-general.php' )
->capability( 'edit_others_posts' )
);
$vx->define(
Blueprint::dictionary( 'formats' )
->label( 'Formats' )
->entries( [ 'hardcover' => 'Hardcover', 'paperback' => 'Paperback' ] )
);Link a choice field to a dictionary with Field::select( 'format' )->dictionary( 'formats' ). Option pages are top-level by default; submenu() without an argument nests the page under VX, and hidden() makes it reachable by URL only.
Field types without a shortcut
Field has shortcuts for common types (text(), number(), select(), repeater(), image() and more). For any other type, use Field::make( 'type', 'key' ). Any setting without its own method can be set with ->prop() or ->props():
php
Field::make( 'range_slider', 'price_band' )
->label( 'Price band' )
->props( [ 'min' => 0, 'max' => 200, 'step' => 5 ] );You can also register a raw config array, the same shape the dashboard stores:
php
$vx->fieldset( 'book_details', [
'label' => 'Book details',
'fields' => [ [ 'type' => 'text', 'key' => 'tagline', 'label' => 'Tagline' ] ],
'location' => [ 'groups' => [ [ 'object' => 'post_type', 'targets' => [ 'book' ] ] ] ],
] );Gotchas
- Always name targets.
on_post_type()andon_taxonomy()without an argument create a Location with nothing selected, which matches nothing. on_user()applies to every user. It takes no arguments. To limit a fieldset to certain roles, add a User role condition to the Location in the raw config.required()is accepted, but VX doesn't enforce required fields.- PHP wins over JSON. If a JSON file defines the same key, it's ignored, and Direct mode isn't available.
Technical details for LLMs
- Registry:
vxframework/register(action,initpriority 0) receives\VxFramework\Config\Code_Registrywithdefine( Blueprint )and rawpost_type(),taxonomy(),fieldset()methods. A registration, blueprint or method for an object type nothing registers is skipped without an error; the registration is reported as an unknown config type alongside the ones that failed validation. - Post type:
name( $singular, $plural ),singular(),plural(),description(),icon(),accent_color(),hierarchical(),block_editor(),show_in_rest(),rest_base(),has_archive(),permalink_base(),menu_position(),labels(). - Taxonomy:
name(),singular(),plural(),icon(),accent_color(),hierarchical(),is_public(),show_in_rest(),rest_base(),show_admin_column(),permalink_base(),labels(). - Fieldset:
label(),description(),description_display(),order(),active(),icon(),accent_color(),fields(),add_field(),on_post_type(),on_taxonomy(),on_user(),on( $object, $targets )for any Location object. - Field factories:
Field::{type}( $key )builds a field of any type by name; the type is checked when the fieldset is validated. Shortcuts:make,text,textarea,number,email,url,phone,switcher,color,rich_text,code,date,datetime,time,select,radio,checkboxes,multiselect,button_group,image,gallery,taxonomy,repeater,group,section(ui_section),tabs(ui_tabs, whosefields()are sections). Modifiers:label,description,required,default,placeholder,prop,props,min,max,step,choices,fields. Any object key:->set()/->props(). - Option page:
label(),description(),icon(),accent_color(),top_level(),submenu( $parent = 'vx-framework' ),hidden(),menu_title(),menu_position(),capability(),autoload(),active(). Dictionary:label(),icon(),accent_color(),entries()(map,{value,label}list, or strings). - Also on a fieldset:
rest_expose(),on_option_page(). More field factories:markdown,file(→files),post_relation,user_relation,location,table,content_sections. More modifiers:rest_expose( $tier )(setsrest.access),dictionary,layouts. permalink_base()is normalized to a slug (UTF-8 kept, percent-encoding decoded); a value with nothing usable fails validation and is reported on the Source tab.