1. Установка окружения
Чтобы делать кастомные блоки, лучше использовать @wordpress/scripts — это готовый билд-инструмент с webpack + Babel.
npm init @wordpress/block my-block
cd my-block
npm start
Это создаст структуру с уже готовым базовым блоком.
2. Основная структура блока
Обычно блок состоит из двух частей:
- edit – то, что видит редактор (React-компонент)
- save – то, что сохраняется в HTML
Пример простого блока:
import { registerBlockType } from "@wordpress/blocks";
import { RichText } from "@wordpress/block-editor";
registerBlockType("myplugin/custom-block", {
title: "Мой блок",
icon: "smiley",
category: "widgets",
attributes: {
content: { type: "string" },
},
edit: ({ attributes, setAttributes }) => {
return (
<RichText
tagName="p"
value={attributes.content}
onChange={(newContent) => setAttributes({ content: newContent })}
placeholder="Введите текст..."
/>
);
},
save: ({ attributes }) => {
return <RichText.Content tagName="p" value={attributes.content} />;
},
});
3. Использование React-компонентов
Ты можешь подключать свои кастомные React-компоненты внутрь блока:
const CustomButton = ({ label, onClick }) => {
return <button onClick={onClick}>{label}</button>;
};
registerBlockType("myplugin/button-block", {
title: "Кнопка",
icon: "button",
category: "widgets",
edit: ({ attributes, setAttributes }) => {
return (
<CustomButton
label="Нажми меня"
onClick={() => alert("Hello Gutenberg!")}
/>
);
},
save: () => {
return <button>Нажми меня</button>;
},
});
4. Хуки и UI из @wordpress/components
WordPress предоставляет готовые UI-компоненты: Button
, PanelBody
, ColorPalette
, TextControl
, и т.д.
Они стилизованы в духе WP-админки и очень экономят время.
Пример:
import { InspectorControls } from '@wordpress/block-editor';
import { PanelBody, ColorPalette } from '@wordpress/components';
edit: ({ attributes, setAttributes }) => {
return (
<>
<InspectorControls>
<PanelBody title="Настройки блока">
<ColorPalette
value={attributes.color}
onChange={(color) => setAttributes({ color })}
/>
</PanelBody>
</InspectorControls>
<p style={{ color: attributes.color }}>Текст с цветом</p>
</>
);
},
5. Где жить коду?
- Если блоков мало — можно писать прямо в плагине.
- Если делаешь что-то большое и модульное — выноси каждый блок в отдельную папку.
6. Рекомендации
- React хуки работают (
useState
,useEffect
и т.д.) – Gutenberg использует React под капотом. - Можно писать блоки TS/JSX —
@wordpress/scripts
всё подтянет. - Если блоки нужно шарить — упаковывай в npm-пакеты.
Отлично, давай разберёмся глубже 🚀
🔧 Как билдить Gutenberg-блоки
WordPress сам по себе не даёт hot reload как в чистом CRA/Next.js, но есть инструменты, которые делают процесс максимально похожим на React-разработку.
1. Используем @wordpress/scripts
Это официальный пакет от WP, который уже включает в себя:
- Webpack (с live reload)
- Babel (JSX/ESNext)
- PostCSS (стили)
- ESLint/Prettier-конфиги
Установка:
npm init @wordpress/block my-block
cd my-block
npm start
👉 npm start
— это аналог npm run dev
в React: он билдит в build/
и отслеживает изменения файлов.
Когда ты сохраняешь файл — билд обновляется, и при перезагрузке страницы в WordPress изменения видны.
2. Запуск локального WordPress для разработки
Тебе нужен рабочий WordPress-сайт (локально или через Docker).
Есть два варианта:
-
LocalWP (GUI-программа) — просто, быстро, всё на кнопках.
-
wp-env (от WordPress) — CLI-окружение на Docker, ставится через npm:
npm install -g @wordpress/env wp-env start
После этого у тебя локально крутится WP по адресу
http://localhost:8888
.
3. Подключение блока к WordPress
В plugin.php
(в папке плагина) подключаем билд:
<?php
/**
* Plugin Name: My Custom Block
*/
function my_custom_block_register() {
register_block_type( __DIR__ . '/build' );
}
add_action( 'init', 'my_custom_block_register' );
👉 build
— это папка, куда складывает Webpack (@wordpress/scripts
).
4. Live reload (как в React)
Прямо “горячей замены модулей” (HMR) как в CRA нет.
Но:
npm start
пересобирает всё за секунду- при обновлении страницы в WP редакторе ты сразу видишь изменения
⚡ Есть костыли для HMR через webpack-dev-server
, но большинство разрабов WP используют именно стандартный @wordpress/scripts
.
📦 Пример продвинутого блока с React-компонентами
Вот блок, где мы используем useState
, InspectorControls
и кастомный UI:
import { registerBlockType } from "@wordpress/blocks";
import { InspectorControls, RichText } from "@wordpress/block-editor";
import { PanelBody, TextControl, Button } from "@wordpress/components";
import { useState } from "@wordpress/element";
registerBlockType("myplugin/advanced-block", {
title: "Продвинутый блок",
icon: "admin-site",
category: "widgets",
attributes: {
title: { type: "string", default: "Заголовок" },
buttonText: { type: "string", default: "Кнопка" },
},
edit: ({ attributes, setAttributes }) => {
const [count, setCount] = useState(0);
return (
<>
<InspectorControls>
<PanelBody title="Настройки блока">
<TextControl
label="Текст кнопки"
value={attributes.buttonText}
onChange={(val) => setAttributes({ buttonText: val })}
/>
</PanelBody>
</InspectorControls>
<div className="my-block">
<RichText
tagName="h3"
value={attributes.title}
onChange={(val) => setAttributes({ title: val })}
placeholder="Введите заголовок..."
/>
<Button variant="primary" onClick={() => setCount(count + 1)}>
{attributes.buttonText} ({count})
</Button>
</div>
</>
);
},
save: ({ attributes }) => {
return (
<div className="my-block">
<RichText.Content tagName="h3" value={attributes.title} />
<button>{attributes.buttonText}</button>
</div>
);
},
});
👉 Тут:
- InspectorControls = боковая панель с настройками блока
- useState = локальное состояние (счётчик)
- RichText = редактируемый текст
🔥 О, вот это правильный вопрос! На нём часто ломаются джуны, которые впервые сталкиваются с Gutenberg.
📦 Где должен жить твой блок?
1. Как плагин (самый правильный способ)
- Ты создаёшь папку
my-block-plugin/
- Внутри —
plugin.php
,src/
,build/
- Подключаешь блок через
register_block_type()
✅ Плюсы:
- Можно использовать блок в любой теме
- Код легко переносится, версионируется, заливается в npm
- Это best practice (WP рекомендует именно плагины)
2. Внутри темы
- Ты можешь положить свой код в
theme-name/blocks/
- Подключать так же через
functions.php
✅ Плюсы:
- Удобно для кастомных проектов (например, сайт клиента на одной теме)
- Всё в одном месте
❌ Минусы:
- Если сменишь тему → блоки пропадут
- Повторное использование блоков на других проектах усложняется
👉 Поэтому:
- Если ты делаешь кастомный сайт клиенту → блоки можно положить прямо в тему.
- Если хочешь переиспользуемые компоненты (библиотека блоков, набор UI) → лучше всегда плагин.
⚡ Про webpack-dev-server
и HMR (чтобы реально было как CRA/Next.js)
По умолчанию @wordpress/scripts
даёт только watch
+ пересборку. Но мы можем включить полноценный dev-server:
1. Ставим зависимости:
npm install --save-dev webpack-dev-server
2. В package.json
добавляем скрипт:
"scripts": {
"start": "wp-scripts start",
"dev": "webpack serve --config webpack.config.js"
}
3. Настраиваем webpack.config.js
:
const defaultConfig = require("@wordpress/scripts/config/webpack.config");
module.exports = {
...defaultConfig,
devServer: {
hot: true,
port: 3000,
proxy: {
"/": "http://localhost:8888", // твой локальный WP
},
},
};
4. Запуск:
npm run dev
Теперь:
webpack-dev-server
поднимается наhttp://localhost:3000
- Все запросы проксируются в WP (
http://localhost:8888
) - React-компоненты реально обновляются без перезагрузки страницы 🎉
Окей 🚀 Давай сделаем чек-лист, как написать свой первый Gutenberg-блок на React. Я дам тебе пошаговый путь, без тонны документации, чтобы можно было реально взять и попробовать.
🔹 Шаг 1. Подготовка окружения
- Перейди в папку с WordPress (обычно
wp-content/plugins/
). - Создай папку для плагина, например
my-custom-block
. - Внутри — файл
my-custom-block.php
с минимальным кодом:
<?php
/**
* Plugin Name: My Custom Block
*/
function my_custom_block_register() {
wp_register_script(
'my-custom-block-editor',
plugins_url( 'build/index.js', __FILE__ ),
array( 'wp-blocks', 'wp-element', 'wp-editor' ),
true
);
register_block_type( 'my/custom-block', array(
'editor_script' => 'my-custom-block-editor',
) );
}
add_action( 'init', 'my_custom_block_register' );
👉 Это зарегистрирует твой блок и подключит скрипт, собранный на React.
🔹 Шаг 2. Инициализация проекта с @wordpress/scripts
- В папке плагина делай:
npm init -y
npm install @wordpress/scripts --save-dev
- В
package.json
добавь скрипты:
"scripts": {
"start": "wp-scripts start",
"build": "wp-scripts build"
}
🔹 Шаг 3. Создай React-файл для блока
- В папке сделай
src/index.js
- Простейший блок:
import { registerBlockType } from "@wordpress/blocks";
import { useBlockProps } from "@wordpress/block-editor";
registerBlockType("my/custom-block", {
title: "My Custom Block",
icon: "smiley",
category: "widgets",
edit() {
const blockProps = useBlockProps();
return <div {...blockProps}>Привет, я React-блок!</div>;
},
save() {
const blockProps = useBlockProps.save();
return <div {...blockProps}>Привет с фронта!</div>;
},
});
🔹 Шаг 4. Сборка
- Запусти:
npm run build
(или npm start
для разработки)
2. Появится папка build/
с index.js
, который подключается в твоём PHP
.
🔹 Шаг 5. Проверка
- Активируй плагин в админке.
- В редакторе Gutenberg появится блок My Custom Block.
- Добавь его в пост или страницу — он отрендерится через React.
🔥 Дальше ты можешь усложнять:
- Использовать
InspectorControls
(панель справа). - Подключать
RichText
,MediaUpload
и т.п. - Делать динамические блоки (PHP + React).
О, тема — это уже более фундаментально, чем блок 🚀
Если блоки — это “кирпичики” для редактора, то тема в WordPress задаёт весь внешний вид сайта (шаблоны страниц, стили, блоки, навигацию).
🔹 Что нужно знать перед стартом
-
Современные темы в WordPress = Gutenberg-блоки + React.
- Старый подход: PHP-шаблоны (
page.php
,single.php
и т.п.). - Новый подход: Block Themes — вся тема собирается из блоков (React + JSON-конфиг).
- Старый подход: PHP-шаблоны (
-
У тебя два пути:
- 🟢 Classic Theme — верстка через PHP-шаблоны (гибко, но устаревающе).
- 🔵 Block Theme (Full Site Editing) — всё строится из блоков, можно писать React-компоненты.
Если хочешь «играть в будущее» → бери Block Theme.
🔹 Минимальный скелет темы
- Создай папку в
wp-content/themes/my-theme
. - Внутри —
style.css
:
/*
Theme Name: My Theme
Author: Ты
Version: 1.0
*/
- Файл
index.php
(если классическая тема):
<?php get_header(); ?>
<h1>Привет из моей темы</h1>
<?php get_footer(); ?>
👉 Уже можно активировать тему в админке.
🔹 Если делать Block Theme
- Вместо
index.php
создаёшьtheme.json
:
{
"version": 2,
"settings": {
"color": {
"palette": [{ "slug": "primary", "color": "#0073aa", "name": "Primary" }]
},
"typography": {
"fontSizes": [
{ "slug": "small", "size": "12px", "name": "Small" },
{ "slug": "large", "size": "36px", "name": "Large" }
]
}
}
}
- Дальше создаёшь шаблоны (например,
templates/index.html
):
<!-- wp:paragraph -->
<p>Привет, я блок-тема!</p>
<!-- /wp:paragraph -->
- Всё это работает на Gutenberg-блоках → можно писать React-блоки и вставлять их как часть темы.
🔹 Где тут React?
- В кастомных блоках → твой React-код идёт туда.
- В админке → интерфейсы, панели, виджеты.
- Можно даже сделать SPA внутри темы (например, страницу портфолио или каталог товаров на React).
🔹 Для практики
- Если хочешь быстро «подружить» React и WP → начни с Classic Theme (PHP + твой React-компонент, встроенный через
wp_enqueue_script
). - Если хочешь современно и по фану → делай Block Theme с
theme.json
и своими блоками.
Отлично, это самый продуктивный вариант ⚡
Берёшь свой макет → переносишь его в WordPress-тему → получаешь и практику, и готовую работу в портфолио.
🔹 Алгоритм: как переделать верстку в WordPress-тему
1. Подготовь базовую тему
- Создай папку в
wp-content/themes/my-landing
. - Добавь
style.css
с метаданными:
/*
Theme Name: My Landing
Author: Adam Lean
Version: 1.0
*/
- Сделай
index.php
с минимальным кодом:
<?php get_header(); ?>
<h1>Привет, это мой первый WP-лендинг</h1>
<?php get_footer(); ?>
👉 Теперь тема уже появится в админке.
2. Подключи свои CSS и JS
- Создай
functions.php
:
<?php
function my_landing_enqueue() {
wp_enqueue_style( 'my-landing-style', get_stylesheet_uri() );
wp_enqueue_script( 'my-landing-js', get_template_directory_uri() . '/assets/js/main.js', array(), null, true );
}
add_action( 'wp_enqueue_scripts', 'my_landing_enqueue' );
- Положи свои стили и скрипты в
/assets/
.
3. Разбей верстку на части
header.php
→ шапка (логотип, меню).footer.php
→ подвал.index.php
→ твоя основная страница (из макета).- Если будут отдельные страницы →
page.php
илиsingle.php
.
👉 WP сам будет подключать header.php
и footer.php
через get_header()
и get_footer()
.
4. Динамика через WordPress
- Тексты, заголовки, изображения → выводи через админку.
- Простейший пример:
<?php the_title(); ?>
<?php the_content(); ?>
👉 Теперь клиент сможет менять текст прямо в редакторе, а не в коде.
5. Добавь «гибкости»
- Используй Custom Fields (через ACF или Gutenberg).
- Например: в блоке «Отзывы» сделай повторяющиеся поля → и клиент добавляет отзывы прямо из админки.