https://github.com/jverneaut/html-to-gutenberg
https://github.com/jverneaut/html-to-gutenberg
Last synced: about 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/jverneaut/html-to-gutenberg
- Owner: jverneaut
- Created: 2025-04-03T12:55:57.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2025-04-03T18:31:08.000Z (2 months ago)
- Last Synced: 2025-04-03T19:28:35.768Z (2 months ago)
- Language: JavaScript
- Size: 68.4 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README

# HTML To Gutenberg
A Webpack plugin and CLI that generates dynamic Gutenberg blocks built with React and either PHP or Twig, from a single HTML file.
Instead of manually coding both React and PHP/Twig components, simply write an HTML file with some special attributes, and this plugin will automatically generate all necessary files for you:
- ✅ **React-based** `edit.js` for the WordPress editor
- ✅ **Frontend rendering with** `render.php` by default
- ✅ Or use **Twig-based** `render.twig` if you prefer (recommended!)
- ✅ **block.json** with automatically defined attributes
- ✅ **index.js** to register the block typehttps://github.com/user-attachments/assets/d9ee9410-9529-4664-a7a4-82b0eb1ad306
This plugin now **defaults to PHP rendering**, making it more compatible with typical WordPress projects.
However, if you're working with **Timber, Bedrock**, or just want a more **frontend-friendly templating experience**, you can enable Twig rendering by setting:
```js
new HTMLToGutenbergPlugin({
...
engine: "twig", // Enables render.twig instead of render.php
});
```👉 Personally, **I highly recommend Twig** for rendering blocks. It feels closer to HTML, is easier to read and write, and is much nicer to maintain—especially if you're a front-end developer.
> For a full Twig-based Gutenberg-ready setup, check out my other project [gutenberg-tailwindcss-bedrock-timber-twig](https://github.com/jverneaut/gutenberg-tailwindcss-bedrock-timber-twig/)
## ✨ Features
- **Automatic Gutenberg block generation** from simple HTML
- **Use attributes** (`data-attribute="title"`, etc.) to define editable fields
- **Supports RichText and MediaUpload**:
- Non-`` elements with `data-attribute="something"` → **Editable RichText**
- `` elements with `data-attribute="something"` → **Image selection via MediaUpload**
- **Fully automates block.json attributes creation**
- **Add additional styles** via the `data-styles="primary secondary"` attribute on the root block element
- **InnerBlocks handling** with `` and `` elements
- **Automatic `style` strings to JS objects conversion** for `edit.js`
- **Supports both PHP and Twig** for frontend rendering## 📦 Installation
```sh
npm install --save-dev @jverneaut/html-to-gutenberg
npm install --save-dev @10up/block-components # Required for the edit.js component
```## ⚙️ Webpack Configuration
This plugin is designed to work with Webpack. Here's how to integrate it:
```js
// webpack.config.js
import HTMLToGutenbergPlugin from "@jverneaut/html-to-gutenberg";export default {
plugins: [
new HTMLToGutenbergPlugin({
inputDirectory: "./blocks", // Your source HTML files
outputDirectory: "./generated-blocks", // Where generated Gutenberg blocks will be placed
blocksPrefix: "custom", // Blocks namespace// Optional: switch to Twig-based rendering (recommended)
engine: "twig", // either 'php' (default) or 'twig'
}),
],
};
```📌 This setup will:
- Scan `blocks/` for `.html` files
- Generate Gutenberg blocks inside `generated-blocks/`> **Note: These blocks still need to be bundled and registered with WordPress before use.**
### Minimal full setup example using Webpack and PHP
#### Webpack configuration
```js
// webpack.config.js
import HTMLToGutenbergPlugin from "@jverneaut/html-to-gutenberg";
import GutenbergWebpackPlugin from "@jverneaut/gutenberg-webpack-plugin";export default {
mode: "development",
entry: "./index.js", // Your main entry point for non-Gutenberg scriptsplugins: [
new HTMLToGutenbergPlugin({
inputDirectory: "./blocks", // Source folder for your custom blocks HTML
outputDirectory: "./generated-blocks", // Where transformed blocks will be output
}),new GutenbergWebpackPlugin("./generated-blocks"), // Registers the generated blocks
],module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"],
},
},
},
],
},
};
```#### Registering Blocks in PHP
Add the following to your theme’s `functions.php` file or a custom plugin to automatically register the generated blocks with WordPress:
```php
add_action('init', function () {
$blocks_path = get_stylesheet_directory() . '/dist/blocks';
$blocks = array_filter(glob($blocks_path . '/**/*'), 'is_dir');foreach ($blocks as $block) {
register_block_type($block);
}
});
```This is a lightweight, automatic setup. Feel free to adapt it to your specific workflow — other approaches might suit your project better.
## CLI
```sh
Usage: npx @jverneaut/html-to-gutenberg [options]A Webpack plugin and CLI that generates dynamic Gutenberg blocks built with React and either PHP or Twig, from a single HTML file.
Options:
-V, --version output the version number
-i, --input HTML blocks input path (default: ".")
-o, --output Gutenberg blocks output path
-p, --prefix Blocks namespace (default: "custom")
-e, --engine Engine (either "php", "twig" or "all") (default: "php")
-w, --watch Watch the input directory for changes and regenerate blocks
-h, --help display help for command
```## 🚀 Quick Start (Example Project)
**An example** is available in the `example/` folder. You can test it by running:
```sh
cd example
npm install
npm run dev
```You can then edit `demo-block.html` and see the generated block inside `example/generated/demo-block`. It is setup to output both `render.php` as well as `render.twig` for demonstration purposes.
## Usage
> _Documentation writing in progress..._
>
> In the meantime, you can explore a variety of examples in the [\_\_tests\_\_/fixtures/processable](https://github.com/jverneaut/html-to-gutenberg/tree/main/__tests__/fixtures/processable) directory. These include both Twig and PHP rendering examples to help you understand how to generate blocks using HTML with this plugin.
>
> As long as the input HTML is valid, the plugin should correctly parse it and generate the corresponding translated JS/Twig/PHP files. If you come across any edge cases or manage to break the plugin in unexpected ways, feel free to open an issue.## Example
### 📝 Input HTML
```html
Hello, Gutenberg!
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Veritatis
facere deleniti nam magni. Aspernatur, obcaecati fuga.
![]()
Title 2
42
```
### 🔄 Generated files
✅ `edit.js` **(for Gutenberg editor)**
```jsx
import {
useBlockProps,
RichText,
MediaUpload,
InnerBlocks,
} from "@wordpress/block-editor";
import { Image } from "@10up/block-components";export default ({ attributes, setAttributes }) => {
return (
setAttributes({ title })}
>setAttributes({ content })}
>
setAttributes({ image: image.id })}
render={({ open }) => (
setAttributes({ image: image.id })}
/>
)}
>
Title 2", number: 42 },
],
["custom/other-child-block", { title: "Title 3", number: 42 }],
]}
templateLock
>
);
};
```✅ `render.twig` **(for frontend rendering)**
```twig
{{ attributes.title }}
{{ attributes.content }}
![]()
{{ content }}
```
✅ `render.php` **(for frontend rendering)**
```php
'container']); ?>>
![]()
```
✅ `block.json` **(auto-generated block metadata)**
```json
{
"name": "custom/demo-block",
"title": "Demo Block",
"textdomain": "demo-block",
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"version": "0.1.0",
"category": "theme",
"example": {},
"styles": [
{ "name": "primary", "label": "Primary", "isDefault": true },
{ "name": "secondary", "label": "Secondary" }
],
"attributes": {
"align": { "type": "string", "default": "full" },
"title": {
"type": "string",
"default": "Hello, Gutenberg!"
},
"content": {
"type": "string",
"default": "Lorem ipsum dolor sit amet consectetur, adipisicing elit. Veritatis facere deleniti nam magni. Aspernatur, obcaecati fuga."
},
"image": { "type": "integer" }
},
"supports": { "html": false, "align": ["full"] },
"editorScript": "file:./index.js",
"render": "file:./render.twig", // if using Twig engine
"render": "file:./render.php" // if using PHP engine
}
```✅ `index.js` **(register the block type)**
```js
import { registerBlockType } from "@wordpress/blocks";
import { InnerBlocks } from "@wordpress/block-editor";import Edit from "./edit.js";
import metadata from "./block.json";registerBlockType(metadata.name, {
edit: Edit,
save: () => ,
});
```## ❓ FAQ
### Can I add more fields beyond RichText and MediaUpload?
Right now, the plugin auto-generates fields for text and images as well as InnerBlocks. Support for additional fields may come later based on my experience building production sites with this tool.
### Should generated blocks be versioned, or should the source HTML file be?
That depends on your strategy:
- **Versioning the source HTML files only:**
You treat the `.html` files as **the single source of truth**, and let this plugin regenerate the entire block every time. This is ideal when using this plugin as a **build tool**, fully automating block creation and updates. You don’t version the generated files—just the `.html`.
- **Versioning the generated files only:**
You use the HTML input files as a **block scaffolding tool**, generate the files once, delete or ignore the `.html` files, and then **manually edit the generated React/Twig/PHP code**. This approach gives you more control over customization at the cost of automation.
👉 Choose the one that fits your workflow best—**automated generation** vs **manual control**.
### Why would I choose Twig instead of PHP for rendering blocks?
Personally, I find **Twig much friendlier** for templating. It’s closer to HTML, which makes it easier to read, write, and maintain—especially for front-end developers.
On top of that, **writing code generation for Twig is simpler** than for PHP. Since the syntax is less verbose and more structured, it’s a better fit for the kind of programmatic output this plugin produces.
### How do I use the Twig-generated blocks inside my project?
Check out [gutenberg-tailwindcss-bedrock-timber-twig](https://github.com/jverneaut/gutenberg-tailwindcss-bedrock-timber-twig/) — a companion project that enables you to use **Twig as the rendering engine for Gutenberg blocks**.
This setup uses Timber and integrates tightly with TailwindCSS and Bedrock, giving you full control over the front-end and a seamless Twig-based authoring experience.
> I plan to release this integration as a standalone package in the future to make it easier to use in other projects.