WP Manifestindependent plugin directory
manifest / editor / craft-blocks

Craft Blocks

A small collection of custom Gutenberg blocks built with React, showing both static and dynamic (server-rendered) block patterns.

★ 0stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/busayor2020/craft-blocks/archive/refs/heads/master.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

A small, production-shaped WordPress plugin that adds two custom Gutenberg blocks built with React. It exists to show, in one compact codebase, how the two halves of block development fit together: the React editor experience and the PHP that renders on the front end.

Both blocks are registered from block.json, compiled with @wordpress/scripts, and written to the current block API (version 3).

What this demonstrates

Concept Where it lives
Dynamic, server-rendered block Post Grid (render.php + WP_Query)
Static block with saved markup Callout (save.js)
Editor data layer with useSelect and the core-data store Post Grid editor preview
Nested content via InnerBlocks (useInnerBlocksProps) Callout
block.json metadata API (apiVersion 3) Both blocks
Declarative block supports (color, spacing, typography, alignment) Both blocks
Inspector controls from @wordpress/components Both blocks
Block styles and content variants Callout (solid and outline styles, four color variants)
Escaped, injection-safe server output Post Grid render.php
Shared module reused across edit and save Callout (shared.js icon)
Modern build tooling and linting Whole repo (@wordpress/scripts)
Translation-ready strings Both blocks (__() plus a text domain)

The blocks

Post Grid (dynamic)

A responsive grid of recent posts. In the editor it pulls live posts straight from the block editor data layer with useSelect and the core store, so the preview reflects real content without a server round-trip. On the front end it is rendered by render.php using WP_Query, so the output always reflects the current set of published posts.

Controls: number of posts, columns, order and order-by, and toggles for the featured image, excerpt, and date. It also opts into the color, spacing, and alignment supports, so the block inherits theme styling and works with wide and full widths.

Callout (static)

A flexible callout box for notes, tips, and warnings. It uses InnerBlocks, so any content can go inside (paragraphs, lists, buttons, and more). The saved markup is produced by save.js and stored in post content.

It ships with four color variants (info, success, warning, tip), two registered block styles (solid and outline), an optional icon, and typography and spacing supports. The icon component is shared between the editor and the saved output, which keeps block validation clean.

Tech stack

  • React (via the @wordpress/element and block editor packages)
  • WordPress Block API v3 with block.json
  • PHP for dynamic server rendering
  • SCSS, compiled by @wordpress/scripts
  • @wordpress/scripts for build, lint (ESLint and Stylelint), and packaging

Requirements

  • WordPress 6.5 or newer
  • PHP 7.4 or newer
  • Node.js 20 or newer (only needed to build the assets)

Getting started

git clone https://github.com/Busayor2020/craft-blocks.git
cd craft-blocks
npm install
npm run build

Then place the folder in wp-content/plugins/ (or symlink it) and activate Craft Blocks from the Plugins screen. The two blocks appear in the editor inserter under the Widgets and Text categories.

Local development

npm start

This runs the build in watch mode and recompiles on save.

To spin up a throwaway WordPress site with the plugin already active (requires Docker):

npx wp-env start

The site runs at http://localhost:8888 (admin at /wp-admin, user admin, password password).

Other useful scripts:

npm run lint:js      # lint JavaScript
npm run lint:css     # lint styles
npm run format       # format the source
npm run plugin-zip   # build a distributable zip

Project structure

craft-blocks/
├── craft-blocks.php          Plugin bootstrap, registers both blocks
├── src/
│   ├── post-grid/            Dynamic block
│   │   ├── block.json        Metadata, attributes, supports
│   │   ├── index.js          Registration
│   │   ├── edit.js           Editor UI and live data preview
│   │   ├── render.php        Server-side front-end render
│   │   ├── style.scss        Front-end and shared styles
│   │   └── editor.scss       Editor-only styles
│   └── callout/              Static block
│       ├── block.json
│       ├── index.js
│       ├── edit.js           Editor UI with InnerBlocks
│       ├── save.js           Saved markup
│       ├── shared.js         Icon and variants shared by edit and save
│       ├── style.scss
│       └── editor.scss
├── eslint.config.cjs         Extends the wp-scripts default config
├── .wp-env.json              Local environment definition
└── build/                    Compiled output (generated, not committed)

A note on static versus dynamic

The two blocks are a deliberate pairing.

A static block saves its HTML into post content when you press save. It is fast to serve and self-contained, which suits presentational content like a callout whose markup does not change after it is written.

A dynamic block saves only its attributes and renders its HTML in PHP on each request. That is the right choice when the output depends on data that changes over time, like a list of recent posts. Post Grid uses this approach so the grid stays current as posts are published or updated, with no need to re-save the page that contains it.

Author

Victor Busayo GitHub: https://github.com/Busayor2020 LinkedIn: https://www.linkedin.com/in/victor-busayo/

License

GPL-2.0-or-later. See LICENSE.