Many institutions can’t migrate to the WordPress block editor all at once, and they don’t have to. Large sites often rely on legacy shortcodes that are deeply embedded across hundreds of pages, and depending on the timeline and budget of the project, a full rewrite of the site is not always an option, and often unnecessary.
This repository demonstrates a practical, low-risk approach to modernization by converting an existing shortcode into a server-rendered block. Instead of replacing working logic, the block reuses the existing PHP rendering function and layers an intuitive editing interface on top of it.
The goals of this example are to:
- Reuse existing rendering logic to avoid duplication
- Introduce block controls that enhance the editor user experience
- Use block editor filters to remove block controls based on user roles
- Provide a modern architecture for creating block plugins
Following this pattern can enable teams to progressively improve the editing experience while preserving current frontend output; allowing for an incremental, intentional, and safe adoption of the block editor.
Below is the main plugin file structure. The rest of the files in the project root folder are configuration files, and package manager files for NPM and Composer.
shortcode-to-block/
├── .bin/ # create-block script & templates
├── inc/ # PHP files loaded in main file
├── src/ # Source files
│ └── blocks/ # Block source files
├── README.md # Project README file
└── shortcode-to-block.php # Main plugin file
The create-block script will create a block within the scr/blocks folder with the following structure.
my-custom-block/
├── block.json # Defines metadata, attributes, and file locations
├── edit.js # Defines how the block behaves in the editor
├── editor.scss # Editor-only styles
├── index.js # Main block file, registers the block in JS
├── render.php # Handles server-side rendering logic
├── style.scss # Editor and front-end styles
└── view.js # Handles front-end JS functionality
This plugin includes modern development tools configured in package.json and composer.json.
- Install the plugin manually or through
git clone git@github.com:humanmade/shortcode-to-block.git. - Navigate to the plugin folder
cd shortcode-to-block. - Run
composer install. - Run
npm install.- Note: If you are using
nvmfor managing Node versions, runnvm useto switch to the recommended version, otherwise usev22to avoid any incompatibility issues.
- Note: If you are using
- Run
npm run buildto generate the static build files.
npm run dev: Run the development server.npm run build: Run a static build.npm run create-block <block-name>: Scaffold a server-rendered block.npm run format:js: Autoformat first-party JS code in the plugin.npm run format:php: Autoformat first-party PHP code in the plugin.npm run lint:js: Report on code issues in first-party JS files.npm run lint:php: Report on code issues in first-party PHP files.npm run lint: Report on code issues in first-party JS and PHP files.
- Start by creating the basic structure of a server-rendered block:
npm run create-block <block-name>. - Determine all the shortcode attributes you will be using.
- Register a block attribute in
block.jsonfor each of the shortcode attributes. - Create the editor UI by leveraging WordPress block editor components.
- In the
edit.jsfunction, use theServerSideRendercomponent for displaying the shortcode output in the editor. - In the
render.phpfile usedo_shortcode()to call the same legacy rendering function from the shortcode.