Skip to content
Corex

Create a block (CLI)

Every Corex block is dynamic — its markup is produced server-side by a PHP renderer, and the editor previews that render with <ServerSideRender>. One command scaffolds the whole thing.

Terminal window
wp corex make:block TeamMember --path=wp

This writes, under your app’s Blocks/ directory:

Blocks/
team-member/
block.json # apiVersion 3, category "corex", editorScript + style wired,
# corex.renderer → App\Blocks\TeamMemberRenderer
index.js # registerBlockType + <ServerSideRender>; imports style.scss
style.scss # token-only, RTL-correct
TeamMemberRenderer.php # implements Corex\Blocks\BlockRenderer

The slug (team-member), title, block name (<prefix>/team-member), CSS class, and renderer FQCN are all derived from the name.

Terminal window
npm run build # compile index.js + style.scss → build/blocks/
# or: npm run start (watch mode)

After building, the block registers with an editor script and renders server-side. The PHP renderer is where you produce escaped markup:

final class TeamMemberRenderer implements BlockRenderer
{
public function render(array $attributes, string $content, object $block): string
{
return sprintf('<div class="%s">%s</div>',
esc_attr('corex-team-member'),
esc_html__('Team Member', 'corex'));
}
}

A dynamic block still needs editor-side registerBlockType() or WordPress shows “Your site doesn’t include support for this block.” The index.js provides it; the build compiles it (and an auto-generated RTL stylesheet). See Troubleshooting if the editor still complains.

The corex-ui add-on ships a set of ready-made dynamic blocks under the Corex inserter category — all server-rendered, token-only, and RTL-correct:

BlockRenders
corex/postsRecent posts as accessible linked cards (bounded count)
corex/breadcrumbsAn accessible breadcrumb trail
corex/copyrightThe current year + site name
corex/statA single statistic — value, label, optional description
corex/testimonialA quote with attribution (<figure>/<blockquote>/<figcaption>)
corex/pricingA pricing card — plan, price, features, optional CTA
corex/accordionAccessible disclosures from a list — native <details>, no JavaScript
corex/heroA page hero — eyebrow, heading, subheadline, button, optional background image
corex/ctaA call-to-action banner — heading, supporting line, button
corex/teamA responsive grid of team members — photo, name, role, bio
corex/galleryA responsive image gallery from the media library, with captions
corex/tabsTabbed content with no front-end JavaScript (a CSS-only accessible tabs pattern)

Together these are enough to build a full landing page — hero → stats → team → gallery → cta — entirely from Corex blocks, with no theme code. (A “stats grid” is just several corex/stat blocks inside a columns/grid container.)

The component blocks (stat/testimonial/pricing/accordion/hero/cta/team/gallery/ tabs) are edited inline on the canvas — you type the heading, quote, price, or panel text directly into the block like a modern page builder (not only in the right sidebar). They stay dynamic: the text lives in block attributes, save returns null, and the PHP renderer produces the markup from those attributes (so the editor and the front end share one source of truth). Rich text (bold, italic, links) is preserved safely with wp_kses_post. Repeatable lists — pricing features, accordion panels, team members, gallery images, tabs — are added/removed as inline rows. Image blocks (hero/team/gallery) pick from the media library (no pasted URLs), storing {id, url, alt} and rendering real <img> with alt text + lazy loading. tabs renders an accessible tabbed widget with zero view JavaScript (a CSS-only radio/label pattern), so it works even with scripts disabled.

The form block lets you pick a form from a dropdown of the registered forms (no more typing a slug); the list comes from the cap-gated corex/v1/forms route.

Each block is a pure BlockRenderer — see its generated page in the Reference.