Docs Block Developer Guide

Building a New Block — block.json

block.json is the block’s registration file. WordPress reads it to register the block type, its attributes, and its scripts. wpTruss reads the wptPanels key to inject shared inspector panels into the block editor at runtime.


Minimum Valid block.json

{
    "name":         "wptruss/feature-card",
    "title":        "Feature Card",
    "description":  "A single feature card with icon, heading, and description.",
    "category":     "wptruss",
    "icon":         "grid-view",
    "version":      "1.0.0",
    "apiVersion":   3,
    "editorScript": "file:./index.js",
    "style":        "file:./style.css",
    "render":       "file:./render.php",

    "wptPanels": {
        "structure": true,
        "spacing":   true,
        "layout":    true
    },

    "attributes": {
        "headingLevel": { "type": "string",  "default": "h3"      },
        "semanticRole": { "type": "string",  "default": "article" },

        "blockPadding":  { "type": "string",  "default": "xl"   },
        "blockGap":      { "type": "string",  "default": "md"   },
        "spacingBottom": { "type": "string",  "default": "none" },

        "hideOnMobile":  { "type": "boolean", "default": false },
        "hideOnTablet":  { "type": "boolean", "default": false },
        "hideOnDesktop": { "type": "boolean", "default": false },
        "textAlign":     { "type": "string",  "default": "left" },

        "elementOverrides": { "type": "object", "default": {} },

        "heading":     { "type": "string", "default": "" },
        "description": { "type": "string", "default": "" }
    }
}

Key rules:

  • name must follow the namespace/slug format. Use wptruss/ as the namespace for all platform blocks.
  • apiVersion must be 3.
  • render pointing to file:./render.php is required for all wpTruss blocks. The save() function in index.js always returns null.
  • headingLevel and semanticRole are required attributes — the block validator rejects blocks missing either.
  • elementOverrides is required if you use any element registry element in the block. Omitting it means per-block overrides can never be stored.

Mandatory Attributes — Full Set

Include all of these in every block that uses the standard panel set. Do not strip any attribute from this group — the Panel Registry resolves classes against these exact keys at runtime:

"attributes": {
    "headingLevel":    { "type": "string",  "default": "h2"      },
    "semanticRole":    { "type": "string",  "default": "section" },

    "themeMode":       { "type": "string",  "default": "light"   },
    "backgroundColor": { "type": "string",  "default": "light"   },

    "blockPadding":    { "type": "string",  "default": "3xl"     },
    "blockGap":        { "type": "string",  "default": "xl"      },
    "spacingBottom":   { "type": "string",  "default": "none"    },

    "tabletColumns":   { "type": "string",  "default": "1"       },
    "hideOnMobile":    { "type": "boolean", "default": false     },
    "hideOnTablet":    { "type": "boolean", "default": false     },
    "hideOnDesktop":   { "type": "boolean", "default": false     },
    "textAlign":       { "type": "string",  "default": "left"    },

    "elementOverrides": { "type": "object", "default": {}        }
}

wptPanels

wptPanels controls which shared registry panels are injected into the block’s inspector. Set a panel to true to include it, omit or set false to exclude it.

"wptPanels": {
    "structure": true,
    "spacing":   true,
    "layout":    true
}

When a panel is enabled, the Panel Registry injects its current option set into the block at runtime. Adding a new heading level or spacing scale value to the registry propagates to every block that has that panel enabled — without editing individual block files.