# Voxycure Framework Developer Resources > Developer documentation for building WordPress blocks, fields, post types, taxonomies, option pages, and WooCommerce integrations with Voxycure Framework. Version: 2.0.0 Updated: 2026-08-16 Full machine-readable index: https://framework.voxycureinfotech.com/docs.json ## Getting started - [Voxycure Framework Developer Resources](https://framework.voxycureinfotech.com/): A lightweight, code-first toolkit for building WordPress themes with dynamic blocks, structured fields, content types, and settings pages. - What the framework does: Voxycure provides a single PHP registry and shared editor controls. Your theme or companion plugin owns every definition; WordPress owns every saved value. 01Define in codeReviewable definitions that move with Git and deployments. 02Store nativelyBlock attributes, post meta, and options—no framework tables. 03Render in PHPSecure dynamic templates controlled by the developer. - Where data is stored: FeatureDefinitionSaved values BlocksTheme/plugin PHPpost_content block attributes Document fieldsTheme/plugin PHPRegistered post meta Option pagesTheme/plugin PHPwp_options Post types & taxonomiesTheme/plugin PHPNative WordPress content tables - Requirements: PHP 8.0 or newer WordPress 6.0 or newer A block theme, classic theme, or companion plugin for registrations No Node.js or asset build requiredOfficial Voxycure releases already contain the compiled editor assets. Theme and plugin developers should not edit build/, src/, or any file inside Voxycure Framework. Put project definitions, PHP templates, and styles in your own theme or companion plugin; plugin updates can replace every Voxycure file. - [Installation](https://framework.voxycureinfotech.com/getting-started/installation): Install the framework and place project definitions in code that loads after the plugin. - Install from WordPress.org: Install the official plugin directly from the Voxycure Framework page on WordPress.org. In WordPress, open Plugins → Add New Plugin. Search for Voxycure Framework. Select Install Now, then Activate. Create a registration file in your theme or companion plugin. RecommendedFor reusable projects, keep registrations in a small companion plugin so changing themes does not unregister content types. - Manual installation: Download a packaged Voxycure release, upload its voxycure-framework folder to wp-content/plugins/, and activate it in WordPress. Do not install the unbuilt source repository on a client site and do not run npm commands inside the installed plugin. - Load a theme registration file: PHPCopy// functions.php require_once get_theme_file_path('inc/voxycure.php'); - Verify the installation: There is intentionally no Voxycure builder menu. Add a small registration, refresh WordPress, and confirm the content type or block appears in its native editor. - [Build your first project feature](https://framework.voxycureinfotech.com/getting-started/first-project): Register a post type, attach structured fields, and read the saved values in a theme template. - 1. Register the post type and fields: Place this complete code in inc/voxycure.php, then load that file from the theme’s functions.php. PHPCopyregister_post_type('project', [ 'name' => 'Projects', 'singular_name' => 'Project', 'show_in_rest' => true, 'supports' => ['title', 'editor', 'thumbnail'], ]); $registry->register_field_group('project-details', [ 'name' => 'Project details', 'post_types' => ['project'], 'fields' => [ ['field_key' => 'client_name', 'label' => 'Client', 'type' => 'text'], ['field_key' => 'launch_date', 'label' => 'Launch date', 'type' => 'date'], ], ]); }); - 2. Edit and save: Create a Project in WordPress. The document settings panel is loaded only in the block editor and only for the targeted post type. Saving the post sends the registered meta through the WordPress REST API. - 3. Render the values: PHPCopy

- [Architecture and lifecycle](https://framework.voxycureinfotech.com/getting-started/architecture): Understand when definitions load, when WordPress registers them, and how content is persisted. - Request lifecycle: Plugin bootstrapCore services and optional integration hooks load. voxycure/registerYour definitions are collected once per request. WordPress initContent types, blocks, and post meta are registered. Editor or frontendOnly the relevant adapter, assets, and definitions run for that screen. - Performance model: Definitions remain in memory for the request. There are no definition-table queries. Block output caching is disabled until a developer sets a positive TTL. ## Core concepts - [Registry API](https://framework.voxycureinfotech.com/core/registry): The registry is the public entry point for every framework definition. - Where does $registry come from?: You do not create $registry. Voxycure creates one shared Registry object and passes it as the first argument when the voxycure/register WordPress action runs. PHPCopyregister_post_type('project', [ 'name' => 'Projects', ]); });Read it in plain Englishadd_action() means: “When Voxycure announces that registration is open, run this function.” Voxycure supplies the registry object; the variable name $registry is chosen by you. - Load the callback from a theme: Create inc/voxycure.php in the active theme and require it once from functions.php. WordPress loads functions.php automatically; that file loads your definitions. PHPCopy// functions.php defined('ABSPATH') || exit; require_once get_theme_file_path('inc/voxycure.php');If Voxycure is inactive, the action is never fired and the callback does nothing. The theme must not call new Registry(). - Available methods: MethodPurpose register_post_type($slug, $definition)Register a WordPress post type. register_taxonomy($slug, $definition)Register a taxonomy and connect post types. register_block($id, $definition)Register a dynamic PHP block. register_field_group($id, $definition)Attach fields to WordPress documents or a supported integration such as WooCommerce products. register_option_page($slug, $definition)Create a code-defined settings screen. - Organize a larger project: TEXTCopyyour-theme/ ├── functions.php ├── inc/ │ ├── voxycure.php │ └── voxycure/ │ ├── post-types.php │ ├── taxonomies.php │ ├── fields.php │ ├── blocks.php │ └── options.php └── blocks/ └── hero/ ├── render.php └── style.css - Official WordPress reference: WordPress: add_action() explains how callbacks receive values passed by an action. WordPress: get_theme_file_path() explains child-theme-aware file paths. ## Content types - [Post types](https://framework.voxycureinfotech.com/content/post-types): Register editor-ready content types using familiar WordPress arguments. - Complete example: PHPCopyregister_post_type('project', [ 'name' => 'Projects', 'singular_name' => 'Project', 'show_in_rest' => true, 'supports' => ['title', 'editor', 'thumbnail'], ]); }); - Definition arguments: KeyTypeDefault / purpose namestringPlural label derived from the slug. singular_namestringFalls back to name. publicbooleantrue show_uibooleantrue show_in_restbooleantrue; required for the block editor. supportsstring[]title and editor. has_archiveboolean|stringtrue rewrite_slugstringThe post type slug. argsarrayOverrides or adds native WordPress arguments. - Pass current WordPress arguments: This is a complete inc/voxycure.php file. Put advanced native arguments inside args. PHPCopyregister_post_type('event', [ 'name' => 'Events', 'args' => [ 'rest_namespace' => 'wp/v2', 'template' => [['core/heading'], ['core/paragraph']], 'template_lock' => 'insert', ], ]); }); - [Register and use a taxonomy](https://framework.voxycureinfotech.com/content/taxonomies): A beginner-friendly, complete theme example that registers Project types and displays assigned terms. - 1. Create the theme files: This guide keeps registration code separate from the main theme file. TEXTCopyyour-theme/ ├── functions.php └── inc/ └── voxycure.php - 2. Load the registration file: Add this to the active theme’s functions.php. WordPress loads that file automatically on every request. PHPCopyregister_post_type('project', [ 'name' => 'Projects', 'singular_name' => 'Project', 'show_in_rest' => true, 'supports' => ['title', 'editor', 'thumbnail'], ]); $registry->register_taxonomy('project_type', [ 'name' => 'Project types', 'singular_name' => 'Project type', 'post_types' => ['project'], 'hierarchical' => true, 'show_in_rest' => true, 'show_admin_column' => true, 'rewrite_slug' => 'work/type', ]); }); - What $registry means: The anonymous function is your callback. Voxycure calls it and places its shared Registry object in the callback’s first parameter. That is why $registry exists inside the braces. CodeMeaning use Voxyframe\Core\Registry;Imports the class name so PHP can type-check the callback parameter. add_action("voxycure/register", ...)Asks WordPress to run your callback when Voxycure is ready. Registry $registryReceives the object supplied by Voxycure. Do not instantiate it yourself. $registry->register_taxonomy(...)Adds this taxonomy definition to that registry object. - Taxonomy fields explained: KeyWhat to enterWhat it changes project_typeA stable machine nameThe taxonomy key used by templates and WordPress APIs. Keep it lowercase and no longer than 32 characters. namePlural labelDisplayed as “Project types” in WordPress. singular_nameSingular labelDisplayed when referring to one “Project type”. post_typesPost type slugsConnects the taxonomy to project. The post type must also be registered. hierarchicaltrue or falsetrue behaves like Categories with parent/child terms; false behaves like Tags. show_in_resttrueMakes terms available to the block editor and REST API. show_admin_columntrueAdds a Project types column to the Projects list. rewrite_slugURL baseA term such as “Web” can use /work/type/web/. argsNative argument arrayAdds or overrides advanced WordPress register_taxonomy() arguments. - 4. Add and assign terms: Refresh the WordPress dashboard. Open Projects → Project types. Add terms such as Web, Mobile, or Branding. Edit a Project, select one or more Project types, and click Update. The relationship is saved by WordPress in its native taxonomy tables. Voxycure does not create a custom table. - 5. Display terms in a theme template: Place this where a Project is being rendered, for example in single-project.php or a template part. PHPCopy - 6. If the taxonomy URL returns 404: Open Settings → Permalinks and click Save Changes once after adding or changing a rewrite slug. Do not flush rewrite rules on every request. - Official WordPress references: register_taxonomy() — native arguments, reserved terms, and slug rules. get_the_terms() — retrieve terms assigned to a post. add_action() — understand the callback used by voxycure/register. ## Dynamic blocks - [Create your first dynamic block](https://framework.voxycureinfotech.com/blocks/registering-blocks): Build a complete Hero block in a theme: registration, fields, secure PHP rendering, CSS, editor use, and saving. - What you will build: The finished Hero block has editable heading, summary, image, button, and alignment fields. WordPress saves those values with the page, while render.php creates the frontend HTML on every render. Dynamic means rendered by local PHPThe customer’s own WordPress installation runs render.php. No block data is sent to Voxycure. The editor saves attributes instead of final HTML, so updating the template updates every existing Hero block. - 1. Create this folder structure: TEXTCopyyour-theme/ ├── functions.php ├── inc/ │ └── voxycure.php └── blocks/ └── hero/ ├── render.php └── style.cssUse the active theme or child theme. The examples below assume these exact paths. - 2. Load the Voxycure definitions: Add this once to the theme’s functions.php. get_theme_file_path() returns an absolute, child-theme-aware path. PHPCopyregister_block('hero', [ 'label' => 'Hero', 'description' => 'Primary page introduction.', 'category' => 'design', 'icon' => 'cover-image', 'keywords' => ['banner', 'header'], 'template' => get_theme_file_path('blocks/hero/render.php'), 'editor_scope' => ['post_types' => ['page']], 'fields' => [ [ 'field_key' => 'heading', 'label' => 'Heading', 'type' => 'text', 'default_value' => 'Build something useful', ], [ 'field_key' => 'summary', 'label' => 'Summary', 'type' => 'textarea', ], [ 'field_key' => 'image', 'label' => 'Image', 'type' => 'image', ], [ 'field_key' => 'primary_cta', 'label' => 'Primary action', 'type' => 'link_button', ], [ 'field_key' => 'alignment', 'label' => 'Text alignment', 'type' => 'select', 'default_value' => 'left', 'location' => 'inspector', 'options' => [ ['value' => 'left', 'label' => 'Left'], ['value' => 'center', 'label' => 'Center'], ], ], ], ]); }); add_action('after_setup_theme', function (): void { wp_enqueue_block_style('voxyframe/hero', [ 'handle' => 'my-theme-voxycure-hero', 'src' => get_theme_file_uri('blocks/hero/style.css'), 'path' => get_theme_file_path('blocks/hero/style.css'), 'ver' => wp_get_theme()->get('Version'), ]); }); - Registration fields explained: KeyValue in this guidePurpose heroStable block IDCreates the WordPress block name voxyframe/hero. labelHeroName developers and editors see in the inserter. descriptionShort explanationHelps editors choose the correct block. categorydesignPlaces it in the Design inserter category. iconcover-imageUses a WordPress Dashicon slug. keywordsbanner, headerAdditional inserter search terms. templateAbsolute PHP pathThe trusted PHP file that renders the block. editor_scopePagesOffers this Hero only in the block editor for the page post type. fieldsField definitionsBuilds editor controls and the block attribute schema. locationinspectorMoves alignment to the editor settings sidebar; other fields remain in the block. Keep the ID stableRenaming hero creates a different block. Existing pages would still reference voxyframe/hero. - Choose where the block appears: category only groups a block inside the inserter. It does not make a block a page, product, or WooCommerce block. Use editor_scope to control which WordPress editors offer it. Scope keyMatches post_typesPost, page, product, or any public custom post-type slug. post_idsExact numeric post or page IDs. post_slugsExact post slugs. template_slugsA template post such as single-product, when WordPress provides that template post in the editor context. editor_contextscore/edit-post, core/edit-site, or another WordPress block-editor context. PHPCopy// Every page, but not posts or other custom post types. 'editor_scope' => [ 'post_types' => ['page'], ], // Only one landing page. Conditions in one rule use AND logic. 'editor_scope' => [ 'post_types' => ['page'], 'post_ids' => [42], ], // Projects OR products. Rules in a list use OR logic. 'editor_scope' => [ ['post_types' => ['project']], ['post_types' => ['product']], ],No scope means everywhereOmit editor_scope when a block should be offered in every compatible block editor. Scope changes inserter availability only; already-saved block markup can still render on the frontend.Site Editor limitationWordPress loads some Site Editor settings before a specific template post is selected. Use editor_contexts => ['core/edit-site'] for reliable Site Editor-only visibility. Use template_slugs only when your tested WordPress editor context supplies the template post. - 4. Create the PHP render file: Paste this into blocks/hero/render.php. The framework provides $attributes; each array key matches a registered field_key. PHPCopy
'vc-hero vc-hero--' . $alignment, ]) ?>>

- Why the render code is safe: esc_html() escapes visible text. esc_url() escapes the link destination. wp_get_attachment_image() renders responsive WordPress image markup from a trusted attachment ID. The alignment is checked against an allow-list before becoming a CSS class. get_block_wrapper_attributes() preserves WordPress-generated block classes and attributes. WordPress output escaping guide · wp_get_attachment_image() - 5. Add the block styles: Paste this into blocks/hero/style.css. The earlier wp_enqueue_block_style() call makes it available in both the editor and frontend; themes that load block assets on demand can load it only when the Hero is rendered. CSSCopy.vc-hero { display: grid; grid-template-columns: minmax(0, 1fr) minmax(18rem, .8fr); gap: clamp(2rem, 6vw, 6rem); align-items: center; padding-block: clamp(3rem, 8vw, 7rem); } .vc-hero--center .vc-hero__content { text-align: center; } .vc-hero__heading { margin: 0; font-size: clamp(2.5rem, 6vw, 5.5rem); line-height: 1; } .vc-hero__summary { max-width: 42rem; font-size: 1.125rem; } .vc-hero__button { display: inline-flex; padding: .8rem 1.2rem; border-radius: .4rem; color: #fff; background: #1d49c3; text-decoration: none; } .vc-hero__media img { display: block; width: 100%; height: auto; border-radius: 1rem; } @media (max-width: 700px) { .vc-hero { grid-template-columns: 1fr; } }WordPress: wp_enqueue_block_style() - 6. Insert and save the block: Open Pages → Add New or edit an existing page. Click the + block inserter and search for Hero, banner, or header. Enter the heading and summary, choose an image, and fill in the button. Open the block settings sidebar to choose text alignment. Click Publish or Update, then view the page. - How the values are saved: Each field becomes a typed block attribute. The Voxycure editor calls WordPress setAttributes(); WordPress serializes the attributes into the block comment inside post_content. Autosaves, revisions, undo, and the normal page update flow continue to work. Voxycure does not submit a second request or store the values in a custom table. - Change an existing block later: Markup change: edit render.php; all existing Hero blocks use it immediately. Design change: edit style.css. New field: add its definition and read the new key with a fallback in render.php. Removed field: stop rendering it first. Old saved attributes may remain harmlessly in page content. - If the block does not appear: Confirm Voxycure Framework is installed and active. Confirm functions.php loads inc/voxycure.php. Do not place the registration inside init; use voxycure/register. Confirm blocks/hero/render.php exists and the filename case matches. Open the browser console and WordPress debug log for PHP or JavaScript errors. - Official WordPress references: Creating dynamic blocks — how blocks are rendered by PHP in WordPress. Registration of a block — current native registration guidance. get_theme_file_path() — resolve theme files safely. - When to use block.json instead: Voxycure is well suited to PHP-rendered theme sections with shared fields. Use a native block.json build when a block needs custom editor JavaScript, variations, bindings, advanced supports, or the Interactivity API. - [PHP block templates](https://framework.voxycureinfotech.com/blocks/templates): Render attributes safely while keeping markup in your theme. - Template contract: The template runs inside the render callback and receives $attributes. It must be a PHP file below WP_CONTENT_DIR or another explicitly trusted root. PHPCopy
'hero']) ?>>

- Escape for the output context: ContextFunction Visible textesc_html() HTML attributeesc_attr() URLesc_url() Trusted rich HTMLwp_kses_post() Attachment imagewp_get_attachment_image() - Additional trusted roots: PHPCopyadd_filter('voxycure_template_roots', function (array $roots): array { $roots[] = '/srv/shared-wordpress-templates'; return $roots; });Security boundaryOnly add directories controlled by trusted developers. Never add an uploads directory. - [Attributes and persistence](https://framework.voxycureinfotech.com/blocks/attributes): Block field values are serialized by WordPress into the block comment stored in post content. - Field-to-attribute mapping: FieldBlock attribute type Text, textarea, select, radio, date, colorstring Number, range slidernumber Toggle, single checkboxboolean Multi-select, gallery, repeaterarray Image, link buttonobject - How saving works: The shared editor calls setAttributes(). WordPress includes the new attributes in the normal post save, undo history, autosaves, and revisions. Voxycure does not create a second save request. - [Block output caching](https://framework.voxycureinfotech.com/blocks/caching): Opt in to WordPress object-cache storage for expensive, context-stable dynamic output. - Enable per block: Register this from the theme file loaded by functions.php. A TTL of 300 caches matching output for five minutes. PHPCopyregister_block('project-grid', [ 'label' => 'Project grid', 'template' => get_theme_file_path('blocks/project-grid.php'), 'cache_ttl' => 300, 'fields' => [], ]); }); - Cache key inputs: The cache key contains the block ID, serialized attributes, current post ID, and locale. A persistent object-cache plugin is required for values to survive between PHP requests. - Central cache policy: PHPCopyadd_filter('voxycure_block_cache_ttl', function (int $ttl, string $blockId): int { return 'project-grid' === $blockId ? HOUR_IN_SECONDS : $ttl; }, 10, 2);Avoid personalized outputDo not cache blocks containing user-specific, nonce, cart, session, or capability-dependent markup. ## Field reference - [Field reference](https://framework.voxycureinfotech.com/fields/overview): Every field uses a consistent definition shape and is sanitized according to its saved value type. - Field anatomy: PHPCopy[ 'field_key' => 'heading', 'label' => 'Heading', 'type' => 'text', 'default_value' => '', 'required' => true, 'location' => 'default', ]Storage keyUse a stable, unique field_key. Changing it after content exists starts reading and writing a new value. - Available field types: Choose a field below for its value shape, complete definition, sanitization behavior, and rendering example. TexttextTextareatextareaNumbernumberRange sliderrange_sliderToggletoggleCheckboxcheckboxRadioradioSelectselectMulti selectmulti_selectDatedateColorcolorImageimageGallerygalleryLink buttonlink_buttonRepeaterrepeater - Conditional logic: PHPCopy'conditional_logic' => [ ['field' => 'show_cta', 'operator' => '==', 'value' => true], ]Conditional logic changes editor visibility. It is not a security control and does not remove an already-saved value. - [Document field groups](https://framework.voxycureinfotech.com/fields/groups): Attach registered fields to posts, pages, products, or your own REST-enabled post types. - Register a group: Paste this complete example into the registration file loaded by your theme. PHPCopyregister_field_group('page-details', [ 'name' => 'Page details', 'post_types' => ['page'], 'fields' => [ ['field_key' => 'kicker', 'label' => 'Kicker', 'type' => 'text'], ['field_key' => 'featured', 'label' => 'Featured', 'type' => 'toggle'], ], ]); }); - Persistence and permissions: Voxycure registers each key with register_post_meta(), adds custom-fields support when needed, and authorizes writes with current_user_can("edit_post", $post_id). Complex types receive explicit REST schemas. - Read a field: PHPCopy$value = voxycure_get_field('kicker'); $otherPostValue = voxycure_get_field('kicker', 42, 'Fallback'); - [Text field](https://framework.voxycureinfotech.com/fields/text): A single-line value for titles, labels, IDs, and short content. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'eyebrow', 'label' => 'Eyebrow', 'type' => 'text', 'default_value' => 'Featured'] - Saved value: PropertyValue Field typetext PHP / REST valuestring Empty value"" or the configured default SanitizationSanitized with sanitize_text_field(). HTML is removed. - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopy$value = $attributes['eyebrow'] ?? ''; echo esc_html(is_array($value) ? implode(', ', $value) : (string) $value); - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. - [Textarea field](https://framework.voxycureinfotech.com/fields/textarea): Multi-line plain text such as summaries, notes, or addresses. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'summary', 'label' => 'Summary', 'type' => 'textarea', 'required' => true] - Saved value: PropertyValue Field typetextarea PHP / REST valuestring Empty value"" or the configured default SanitizationSanitized with sanitize_textarea_field(). Use a block or rich-text implementation when formatting is required. - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopy$value = $attributes['summary'] ?? ''; echo esc_html(is_array($value) ? implode(', ', $value) : (string) $value); - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. - [Number field](https://framework.voxycureinfotech.com/fields/number): A numeric value stored through the REST API as a number. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'items_per_row', 'label' => 'Items per row', 'type' => 'number', 'default_value' => 3] - Saved value: PropertyValue Field typenumber PHP / REST valuenumber Empty value"" or the configured default SanitizationNon-numeric input becomes 0. Validate business limits in your rendering or save hook. - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopy$value = $attributes['items_per_row'] ?? ''; echo esc_html(is_array($value) ? implode(', ', $value) : (string) $value); - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. - [Range slider field](https://framework.voxycureinfotech.com/fields/range-slider): A visual numeric range control with an optional minimum, maximum, and step. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'overlay', 'label' => 'Overlay', 'type' => 'range_slider', 'default_value' => 40, 'range_config' => ['min' => 0, 'max' => 100, 'step' => 5]] - Saved value: PropertyValue Field typerange_slider PHP / REST valuenumber Empty value"" or the configured default SanitizationStored as a number. Keep the default inside the configured range. - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopy$value = $attributes['overlay'] ?? ''; echo esc_html(is_array($value) ? implode(', ', $value) : (string) $value); - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. - [Toggle field](https://framework.voxycureinfotech.com/fields/toggle): A true/false switch for feature flags and display decisions. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'show_cta', 'label' => 'Show call to action', 'type' => 'toggle', 'default_value' => true] - Saved value: PropertyValue Field typetoggle PHP / REST valueboolean Empty value"" or the configured default SanitizationValues are normalized with rest_sanitize_boolean(). - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopyif (!empty($attributes['show_cta'])) { echo 'Contact us'; } - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. - [Checkbox field](https://framework.voxycureinfotech.com/fields/checkbox): A single checkbox stores a boolean. Supplying options turns it into a multiple-choice checkbox group. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'features', 'label' => 'Features', 'type' => 'checkbox', 'options' => [['value' => 'fast', 'label' => 'Fast'], ['value' => 'secure', 'label' => 'Secure']]] - Saved value: PropertyValue Field typecheckbox PHP / REST valueboolean or string[] Empty value"" or the configured default SanitizationAn option group is stored as a sequential array of sanitized strings. - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopy$value = $attributes['features'] ?? ''; echo esc_html(is_array($value) ? implode(', ', $value) : (string) $value); - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. - [Radio field](https://framework.voxycureinfotech.com/fields/radio): A single value selected from a short, visible list of choices. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'alignment', 'label' => 'Alignment', 'type' => 'radio', 'default_value' => 'left', 'options' => [['value' => 'left', 'label' => 'Left'], ['value' => 'center', 'label' => 'Center']]] - Saved value: PropertyValue Field typeradio PHP / REST valuestring Empty value"" or the configured default SanitizationUse select when the option list is long. - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopy$value = $attributes['alignment'] ?? ''; echo esc_html(is_array($value) ? implode(', ', $value) : (string) $value); - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. - [Select field](https://framework.voxycureinfotech.com/fields/select): A compact single-choice dropdown. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'heading_level', 'label' => 'Heading level', 'type' => 'select', 'default_value' => 'h2', 'options' => [['value' => 'h2', 'label' => 'H2'], ['value' => 'h3', 'label' => 'H3']]] - Saved value: PropertyValue Field typeselect PHP / REST valuestring Empty value"" or the configured default SanitizationAlways escape the selected value before using it in HTML attributes. - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopy$value = $attributes['heading_level'] ?? ''; echo esc_html(is_array($value) ? implode(', ', $value) : (string) $value); - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. - [Multi select field](https://framework.voxycureinfotech.com/fields/multi-select): A token-based control for choosing more than one value. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'audiences', 'label' => 'Audiences', 'type' => 'multi_select', 'options' => [['value' => 'agency', 'label' => 'Agency'], ['value' => 'startup', 'label' => 'Startup']]] - Saved value: PropertyValue Field typemulti_select PHP / REST valuestring[] Empty value[] SanitizationStored as a sequential string array with an explicit REST item schema. - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopy$value = $attributes['audiences'] ?? ''; echo esc_html(is_array($value) ? implode(', ', $value) : (string) $value); - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. - [Date field](https://framework.voxycureinfotech.com/fields/date): A calendar date value for events, deadlines, or publishing context. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'launch_date', 'label' => 'Launch date', 'type' => 'date'] - Saved value: PropertyValue Field typedate PHP / REST valuestring Empty value"" or the configured default SanitizationTreat the saved value as a date string. Convert with WordPress date helpers before presentation. - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopy$value = $attributes['launch_date'] ?? ''; echo esc_html(is_array($value) ? implode(', ', $value) : (string) $value); - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. - [Color field](https://framework.voxycureinfotech.com/fields/color): A color picker that stores a CSS color value. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'accent_color', 'label' => 'Accent color', 'type' => 'color', 'default_value' => '#1d49c3'] - Saved value: PropertyValue Field typecolor PHP / REST valuestring Empty value"" or the configured default SanitizationEscape for the destination context. Use esc_attr() inside a style attribute. - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopy$value = $attributes['accent_color'] ?? ''; echo esc_html(is_array($value) ? implode(', ', $value) : (string) $value); - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. - [Image field](https://framework.voxycureinfotech.com/fields/image): A Media Library selection stored as an object containing an attachment ID and URL. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'portrait', 'label' => 'Portrait', 'type' => 'image'] - Saved value: PropertyValue Field typeimage PHP / REST valueobject Empty value"" or the configured default SanitizationPrefer the attachment id with wp_get_attachment_image(); the stored URL is convenient but less adaptable. - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopy$image = $attributes['portrait'] ?? []; echo wp_get_attachment_image((int) ($image['id'] ?? 0), 'large'); - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. - [Gallery field](https://framework.voxycureinfotech.com/fields/gallery): An ordered list of Media Library images. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'gallery', 'label' => 'Gallery', 'type' => 'gallery'] - Saved value: PropertyValue Field typegallery PHP / REST valueobject[] Empty value[] SanitizationEach item has an integer id and sanitized url. The REST schema validates every item. - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopyforeach ((array) ($attributes['gallery'] ?? []) as $image) { echo wp_get_attachment_image((int) $image['id'], 'large'); } - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. - [Link button field](https://framework.voxycureinfotech.com/fields/link-button): A paired button label and destination URL. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'primary_cta', 'label' => 'Primary action', 'type' => 'link_button', 'default_value' => ['text' => 'Learn more', 'url' => '/about/']] - Saved value: PropertyValue Field typelink_button PHP / REST valueobject Empty value"" or the configured default SanitizationThe URL is sanitized with esc_url_raw() when saved. Escape it again with esc_url() when rendered. - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopy$link = $attributes['primary_cta'] ?? []; printf('%s', esc_url($link['url'] ?? ''), esc_html($link['text'] ?? '')); - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. - [Repeater field](https://framework.voxycureinfotech.com/fields/repeater): A repeatable list of rows with a defined child-field schema. - Field definition: Add this array inside a block, field group, or option page fields list. PHPCopy['field_key' => 'stats', 'label' => 'Statistics', 'type' => 'repeater', 'fields' => [['field_key' => 'value', 'label' => 'Value', 'type' => 'text'], ['field_key' => 'label', 'label' => 'Label', 'type' => 'text']]] - Saved value: PropertyValue Field typerepeater PHP / REST valueobject[] Empty value[] SanitizationChild keys become the REST object properties. Define every child explicitly so invalid properties are rejected. - Rendering example: Read block fields from $attributes. Post fields use voxycure_get_field(); option fields use voxycure_get_option(). PHPCopyforeach ((array) ($attributes['stats'] ?? []) as $row) { printf('%s%s', esc_html($row['value'] ?? ''), esc_html($row['label'] ?? '')); } - Common field options: KeyTypePurpose field_keystringRequired unique storage key using lowercase letters, numbers, underscores, or hyphens. labelstringHuman-readable editor label. default_valuemixedValue used before content is saved. Match the field value type. requiredbooleanRejects an empty option-page submission. conditional_logicarrayControls editor visibility based on another field. locationstringdefault or inspector for block fields. ## Options - [Option pages](https://framework.voxycureinfotech.com/options/registering-pages): Create settings screens from PHP while saving only explicitly registered and sanitized fields. - Complete page: Paste this complete example into the registration file loaded by your theme. PHPCopyregister_option_page('theme-settings', [ 'name' => 'Theme settings', 'page_title' => 'Theme settings', 'option_key' => 'theme_settings', 'capability' => 'manage_options', 'icon' => 'dashicons-admin-customizer', 'position' => 58, 'autoload' => false, 'fields' => [ ['field_key' => 'brand_color', 'label' => 'Brand color', 'type' => 'color'], ['field_key' => 'support_email', 'label' => 'Support email', 'type' => 'text'], ], ]); }); - Save security: The REST route rejects unregistered option keys, checks the page capability, ignores unregistered fields, validates required values, sanitizes by field type, and then calls update_option(). - Read an option: PHPCopy$color = voxycure_get_option('theme_settings.brand_color', '#1d49c3'); - [Tabbed option pages](https://framework.voxycureinfotech.com/options/tabs): Group larger settings screens into predictable nested arrays. - Define tabs and assignments: PHPCopy'tabs' => [ ['value' => 'branding', 'label' => 'Branding'], ['value' => 'social', 'label' => 'Social profiles'], ], 'fields' => [ ['field_key' => 'logo_text', 'label' => 'Logo text', 'type' => 'text', 'tab' => 'branding'], ['field_key' => 'linkedin', 'label' => 'LinkedIn URL', 'type' => 'text', 'tab' => 'social'], ], - Saved option shape: PHPCopy[ 'branding' => ['logo_text' => 'Voxycure'], 'social' => ['linkedin' => 'https://linkedin.com/company/example'], ] - Read a nested value: PHPCopy$linkedin = voxycure_get_option('theme_settings.social.linkedin'); ## API reference - [Template helpers](https://framework.voxycureinfotech.com/api/helpers): Read native WordPress values with defaults and nested option paths. - voxycure_get_field(): PHPCopyvoxycure_get_field(string $key, ?int $postId = null, mixed $default = null): mixedArgumentMeaning $keyRegistered meta key. $postIdDefaults to get_the_ID(). $defaultReturned when no post/value exists. - voxycure_get_option(): PHPCopyvoxycure_get_option(string $key, mixed $default = null): mixedDot notation traverses nested arrays and objects, for example theme_settings.branding.logo. - voxycure_registry(): Returns the shared Voxyframe\Core\Registry. Prefer the registration action so other extensions can predict the load order. - [Hooks and filters](https://framework.voxycureinfotech.com/api/hooks): Adjust definitions, native registration arguments, caching policy, and save behavior. - Registration hooks: HookTypePurpose voxycure/registerActionPrimary definition entry point. voxycure_register_post_typesFilterFilter collected post-type definitions. voxycure_register_taxonomiesFilterFilter taxonomy definitions. voxycure_blocksFilterFilter dynamic blocks. voxycure_meta_fieldsFilterFilter document field groups. voxycure_option_pagesFilterFilter option pages. - Runtime hooks: HookPurpose voxycure_post_type_argsModify final native post-type arguments. voxycure_taxonomy_argsModify final native taxonomy arguments. voxycure_block_cache_ttlSet output cache lifetime. voxycure_block_editor_scope_matchOverride the final inserter-visibility decision for one Voxycure block and editor context. voxycure_template_rootsAdd a trusted PHP-template root. voxycure_options_savedRun after a registered option page saves. - [Security model](https://framework.voxycureinfotech.com/api/security): Understand the trust boundaries and the responsibilities that remain in theme templates. - Input protection: Option writes are allow-listed by page and field. Post meta uses type-specific sanitizers and REST schemas. Post writes require permission for the exact post. Option pages require their configured capability. Template paths must resolve to approved PHP files. - Output escaping is your responsibility: Sanitizing stored data does not replace context-aware output escaping. Escape at the last possible moment in PHP templates. PHPCopy - Caching security: Cached HTML can cross user requests when persistent object caching is enabled. Never cache output containing nonces, private data, account state, or cart/session content. - Privacy and outbound requests: Voxycure Framework contains no telemetry client and sends no activation, deactivation, update, usage, site URL, content, field, block, or option data to Voxycure. Plugin activation only creates a short-lived local transient so WordPress can refresh rewrite rules once. Local WordPress processing“PHP-rendered” and “registered with WordPress using PHP” refer to code running on the customer’s own hosting server. They do not mean the Voxycure website or a remote API. ## Integrations - [Modern WordPress development](https://framework.voxycureinfotech.com/integrations/wordpress): Use Voxycure for concise theme features while following current WordPress block and REST conventions. - Block registration direction: Voxycure registers dynamic blocks with WordPress using PHP and Block API version 3. All registration and rendering happen inside the customer’s WordPress installation; Voxycure does not receive block definitions or saved values. For independent blocks with scripts, styles, variations, bindings, or interactive directives, use block.json. WordPress 6.8+ recommends metadata collections for registering many metadata-based blocks. WordPress block registration guide - REST meta requirements: REST-visible array meta must declare an item schema, and the post type must support custom-fields. Voxycure handles both when registering field groups. WordPress REST response guide - Prefer native APIs: Use WordPress template, escaping, media, capability, translation, and cache functions inside framework callbacks. Voxycure does not replace those APIs. - [WooCommerce Product Editor and product blocks](https://framework.voxycureinfotech.com/integrations/woocommerce-product-editor): Understand the Product Editor v3 status, add supported product fields, and build a dynamic block for the Single Product template. - Product Editor v3 status: No stable v3 extension APIAs of August 2026, theme and extension developers cannot register blocks inside a released WooCommerce Product Editor v3. WooCommerce retired the previous block-based Product Editor beta in WooCommerce 11.0. The proposed v3 direction uses WordPress DataForms and DataViews, but WooCommerce has not published a stable production API for adding v3 editor blocks.Do not use @woocommerce/product-editor, product-block-editor-v1, @woocommerce/create-product-editor-block, or editor APIs marked __experimental. Those belong to the retired beta and are not a future-safe Voxycure integration. - Do not confuse these three editor surfaces: SurfaceWhat developers customizeCurrent approach WooCommerce Admin product editorThe form merchants use to edit price, stock, shipping, and custom product data.Use the supported classic product editor hooks and WooCommerce CRUD today. Product Editor v3 has no stable public block API. Single Product template editorThe storefront layout shoppers see for one product.Build product-display blocks and insert them into the WooCommerce Single Product template in the Site Editor. Product Collection and catalog blocksProduct grids, catalog queries, filters, Cart, and Checkout.Use the documented WooCommerce Blocks extension surfaces for that specific block. - WooCommerce version matrix: WooCommerceProduct editor stateWhat your code should do 10.8 and earlierOld block-based editor beta may exist behind a feature flag.Do not begin new integrations with its experimental APIs. 10.9Deprecation window and warnings.Remove beta-only imports, blocks, slots, and feature declarations. 11.0 and newerOld beta editor and @woocommerce/product-editor are removed.Use the Voxycure editor => woocommerce adapter, which wraps the stable classic editor and product CRUD. - Theme or companion plugin?: The examples below can live in a theme because this guide targets theme developers. Product data usually belongs in a small companion plugin, however, so merchants can still edit the field after changing themes. The frontend display block and CSS naturally belong in the theme. - 1. Create the files: TEXTCopyyour-theme/ ├── functions.php ├── inc/ │ ├── voxycure.php │ └── blocks.php └── blocks/ └── product-delivery-note/ ├── render.php └── style.css - 2. Load the integration from functions.php: WordPress loads the active theme’s functions.php. Load the child-theme-aware registration files; developers do not add WooCommerce rendering or save hooks themselves. PHPCopy woocommerce, renders the field in Product data → Inventory, verifies WooCommerce’s save nonce, sanitizes the submitted value by field type, checks the product-edit capability, and updates the same WC_Product object that WooCommerce saves. PHPCopyregister_field_group('product-delivery', [ 'name' => 'Delivery details', 'post_types' => ['product'], 'editor' => 'woocommerce', 'woocommerce_tab' => 'inventory', 'fields' => [ [ 'field_key' => '_vc_delivery_note', 'label' => 'Delivery note', 'type' => 'text', 'description' => 'Shown on the product page, for example “Usually ships in 2 days”.', 'desc_tip' => true, 'placeholder' => 'Usually ships in 2 business days', ], ], ]); });KeyPurpose post_types => ['product']Connects the field group to WooCommerce products. editor => 'woocommerce'Uses the Voxycure WooCommerce adapter instead of the WordPress document settings panel. woocommerce_tabChoose general, inventory, shipping, linked, or advanced. field_keyThe stable product-meta key read through WC_Product::get_meta(). No manual WooCommerce hooksDo not call woocommerce_wp_text_input(), read $_POST, or call save_meta_data() in the theme. Voxycure owns that adapter and WooCommerce performs the final product save.Stable developer definitionKeep this registry definition in project code. If WooCommerce publishes a future stable Product Editor v3 extension API, Voxycure can update its internal adapter without forcing theme developers to rewrite the field definition.Supported product controlsThe stable adapter supports text, textarea, number, range, date, color, URL, select, radio, checkbox, and toggle controls. Complex media, gallery, repeater, and multi-select product controls are not silently downgraded; use a purpose-built WooCommerce extension UI for those until Voxycure documents support. - 4. Test product saving: Open Products → Add New or edit a product. Open Product data → Inventory. Enter a value such as Usually ships in 2 business days. Click Publish or Update. Reload the product and confirm the value remains. - 5. Register a storefront product block: This is a Voxycure dynamic block for the storefront Site Editor—not an admin Product Editor v3 block. Paste it into inc/blocks.php. The woocommerce category only controls inserter grouping. Its editor_scope prevents the block from appearing in normal post, page, or product post editors. PHPCopyregister_block('product-delivery-note', [ 'label' => 'Product delivery note', 'description' => 'Displays the delivery note saved on the current WooCommerce product.', 'category' => 'woocommerce', 'icon' => 'car', 'keywords' => ['product', 'delivery', 'shipping'], 'template' => get_theme_file_path('blocks/product-delivery-note/render.php'), 'editor_scope' => ['editor_contexts' => ['core/edit-site']], 'fields' => [], 'cache_ttl' => 0, ]); }); add_action('after_setup_theme', function (): void { wp_enqueue_block_style('voxyframe/product-delivery-note', [ 'handle' => 'my-theme-product-delivery-note', 'src' => get_theme_file_uri('blocks/product-delivery-note/style.css'), 'path' => get_theme_file_path('blocks/product-delivery-note/style.css'), 'ver' => wp_get_theme()->get('Version'), ]); });Why core/edit-site?Current WordPress Site Editor settings are shared and may be created before a specific template post is selected. Targeting core/edit-site is reliable; the block render template still exits safely unless the frontend has a valid WooCommerce product context.Caching is intentionally offProduct data can change independently of template content. Keep cache_ttl at 0 unless your project also invalidates the cached block whenever this product meta changes. - 6. Render the current product value: Paste this into blocks/product-delivery-note/render.php. It exits safely outside a valid product context and escapes the saved value at output. PHPCopyget_meta('_vc_delivery_note', true); if ($deliveryNote === '') { return; } ?>
'vc-product-delivery-note']) ?>>
- 7. Add the block style: Paste this into blocks/product-delivery-note/style.css. WordPress can load it with the block in the editor and frontend. CSSCopy.vc-product-delivery-note { display: flex; gap: .6rem; align-items: baseline; padding: 1rem 1.1rem; border: 1px solid currentColor; border-radius: .5rem; } .vc-product-delivery-note strong { font-weight: 600; } - 8. Add it to the Single Product template: Open Appearance → Editor. Open Design → Templates, then choose the WooCommerce Single Product template. Menu wording can differ slightly by WordPress version. Insert Product delivery note where it should appear, such as below Product Price or Add to Cart. Save the template and visit a product that has a delivery note. The block may render empty when the editor has no preview product. On a real single-product request, it reads the current product through WooCommerce. - What to do when Product Editor v3 ships: Wait for WooCommerce to publish a stable public extension API and migration guide. At that point, keep the existing WC_Product data key and replace only the admin field UI. The storefront block can continue reading _vc_delivery_note through WooCommerce CRUD. Do not guess the APIDataForms, DataViews, and custom field types describe WooCommerce’s direction, not a production contract. Do not ship code copied from internal namespaces or proof-of-concept branches. - Official WooCommerce references: Product editor beta retirement in WooCommerce 11.0 Product Editor v3 direction and DataForms plan Adding custom product fields with WooCommerce CRUD Theming WooCommerce blocks and templates WooCommerce block reference - [WooCommerce](https://framework.voxycureinfotech.com/integrations/woocommerce): Keep commerce extensions HPOS-safe and use the supported Blocks extension surfaces. - Products and orders: Use WooCommerce CRUD objects rather than querying order posts, post meta, or custom tables. PHPCopy$product = wc_get_product($productId); $sku = $product ? $product->get_sku() : ''; $order = wc_get_order($orderId); $order->update_meta_data('dispatch_note', sanitize_text_field($note)); $order->save(); - High-Performance Order Storage: HPOS can store orders outside wp_posts. WooCommerce CRUD methods abstract the active datastore. Declare compatibility only after testing your complete extension. WooCommerce HPOS recipe book - Cart and Checkout blocks: Use the Store API, documented filters, Slot/Fills, inner blocks, or IntegrationInterface. Classic shortcode hooks do not all run in block-based Cart and Checkout. WooCommerce Blocks extensibility - Product editor: WooCommerce 11.0 removed the old block-based Product Editor beta. Product Editor v3 does not currently expose a stable public block API. Read the complete Product Editor and product blocks guide for the supported product-field workflow and a Single Product template block. ## Help - [Troubleshooting](https://framework.voxycureinfotech.com/help/troubleshooting): Common registration, editor, persistence, template, and caching problems. - Definition does not appear: Confirm the plugin is active. Register on voxycure/register, not after init. Use a unique sanitized slug or block ID. Ensure the target post type exists and show_in_rest is enabled. - Field does not save: Confirm field_key is present and stable. Check the browser REST response for schema errors. Verify the current user can edit that post or manage that option page. For option tabs, ensure the field tab matches a tab value. - Block template warning: Use an absolute path such as get_theme_file_path(). The file must exist, end in .php, and be under an approved root. Do not pass a public URL as the template path. - New URLs return 404: Deactivate and reactivate the plugin once, or visit Settings → Permalinks. Never flush rewrite rules on every request.