Примеры Gutenberg блоков

Главная » Примеры Gutenberg блоков

Как устроены и работают блоки Gutenberg и как создавать собственные блоки на примерах.

Скачайте примеры https://github.com/WordPress/gutenberg-examples/

Давайте разберем по порядку, от простого к сложному.

После установки плагина, мы видим девять добавленных блоков в редактор WordPress.

Откроем исходный код плагина. Каждый блок организован в своей папке.

Блоки написаны в двух версиях ES5 и ESNext. Первый это классический вариант, который работает во всех браузерах. Второй с помощью инструментов сборки нужно приводить к совместимости.

Мы будем рассматривать примеры на классическом ES5.

к содержанию ↑

Пример Basic блок

В папке 01-basic находятся всего два файла:

  • index.php — ответственен за подключение ресурсов (в данном случае, главного скрипта block.js ) и регистрацию нового блока;
  • block.js — файл, в котором описан процесс создания блока.

Важная часть кода в index.php.

function gutenberg_examples_01_register_block() {

	if ( ! function_exists( 'register_block_type' ) ) {
		// Gutenberg is not active.
		return;
	}

	wp_register_script(
		'gutenberg-examples-01',
		plugins_url( 'block.js', __FILE__ ),
		array( 'wp-blocks', 'wp-i18n', 'wp-element' ),
		filemtime( plugin_dir_path( __FILE__ ) . 'block.js' )
	);

	register_block_type( 'gutenberg-examples/example-01-basic', array(
		'editor_script' => 'gutenberg-examples-01',
	) );

}

Функция wp_register_script регистрирует файл block.js. Здесь важно отметить список зависимостей, переданных в массиве ( ‘wp-blocks‘, ‘wp-i18n‘, ‘wp-element‘ ), необходимых для работы скрипта.

  • wp-blocks — модуль для регистрации и создания блоков;
  • wp-element — абстракция поверх React;
  • wp-i18n — инструменты для перевода.

Это базовый минимальный набор библиотек.

В зависимости от переданного параметра подключения в функции register_block_type:

  • scriptstyle — скрипт или стиль будет доступен в бэкенде и фронтенде; 
  • editor_scripteditor_style — только в бэкенде.

Посмотрим функцию создания нового блока в скрипте block.js.

blocks.registerBlockType( 'gutenberg-examples/example-01-basic', {
	title: __( 'Example: Basic', 'gutenberg-examples' ),
	icon: 'universal-access-alt',
	category: 'layout',
	edit: function() {
		return el(
			'p',
			{ style: blockStyle },
			'Hello World, step 1 (from the editor).'
		);
	},
	save: function() {
		return el(
			'p',
			{ style: blockStyle },
			'Hello World, step 1 (from the frontend).'
		);
	},
} );

Блоку переданы название title, которое отображается в редакторе; иконка icon — в данном случае, из набора dashicons; категория category — из стандартных (common, formatting, layout, widgets, embed); edit и save описывают структуру блока в контексте редактора и сохраненного в базе.

к содержанию ↑

Пример Stylesheets: блок с подключением стилей

Изменения в файле index.php.

wp_register_script(
	'gutenberg-examples-02',
	plugins_url( 'block.js', __FILE__ ),
	array( 'wp-blocks', 'wp-i18n', 'wp-element' ),
	filemtime( plugin_dir_path( __FILE__ ) . 'block.js' )
);

wp_register_style(
	'gutenberg-examples-02-editor',
	plugins_url( 'editor.css', __FILE__ ),
	array( 'wp-edit-blocks' ),
	filemtime( plugin_dir_path( __FILE__ ) . 'editor.css' )
);

wp_register_style(
	'gutenberg-examples-02',
	plugins_url( 'style.css', __FILE__ ),
	array( ),
	filemtime( plugin_dir_path( __FILE__ ) . 'style.css' )
);

register_block_type( 'gutenberg-examples/example-02-stylesheets', array(
	'style' => 'gutenberg-examples-02',
	'editor_style' => 'gutenberg-examples-02-editor',
	'editor_script' => 'gutenberg-examples-02',
) );

Кроме главного скрипта блока (block.js), регистрируются два файла стилей (editor.css и style.css), один из них работает только в контексте редактора, второй — в контексте редактора и фронтенда.

Изменения в файле block.js

blocks.registerBlockType( 'gutenberg-examples/example-02-stylesheets', {
	title: __( 'Example: Stylesheets', 'gutenberg-examples' ),
	icon: 'universal-access-alt',
	category: 'layout',
	edit: function( props ) {
		return el(
			'p',
			{ className: props.className },
			'Hello World, step 2 (from the editor, in green).'
		);
	},
	save: function() {
		return el(
			'p',
			{},
			'Hello World, step 2 (from the frontend, in red).'
		);
	},
} );

Имя класса WordPress автоматически генерирует из области имен (.wp-block-gutenberg-examples-example-02-stylesheets). В код лицевой части сайта класс добавляется автоматически, а в контексте редактора мы должны его прописать.

к содержанию ↑

Редактируемый блок Editable

В функции регистрации главного скрипта появляется новая зависимость — библиотека wp-editor.

	wp_register_script(
		'gutenberg-examples-03',
		plugins_url( 'block.js', __FILE__ ),
		array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-editor' ),
		filemtime( plugin_dir_path( __FILE__ ) . 'block.js' )
	);

В файле block.js появился блок атрибутов, который определяет как связаны атрибуты редактора с сохраненными значениями в базе.

attributes: {
	content: {
		type: 'array',
		source: 'children',
		selector: 'p',
	},
},

Изменились функции edit и save, которые работают с новым элементом RichText.

edit: function( props ) {
	var content = props.attributes.content;
	function onChangeContent( newContent ) {
		props.setAttributes( { content: newContent } );
	}

	return el(
		RichText,
		{
			tagName: 'p',
			className: props.className,
			onChange: onChangeContent,
			value: content,
		}
	);
},

save: function( props ) {
	return el( RichText.Content, {
		tagName: 'p', value: props.attributes.content,
	} );
},

Дальнейшие примеры усложняются.

Для лучшего понимания нужно открывать блок в редакторе (пример recipe card).

Связанная с ним функция edit.

edit: function( props ) {
	var attributes = props.attributes;

	var onSelectImage = function( media ) {
		return props.setAttributes( {
			mediaURL: media.url,
			mediaID: media.id,
		} );
	};

	return (
		el( 'div', { className: props.className },
			el( RichText, {
				tagName: 'h2',
				inline: true,
				placeholder: i18n.__( 'Write Recipe title…', 'gutenberg-examples' ),
				value: attributes.title,
				onChange: function( value ) {
					props.setAttributes( { title: value } );
				},
			} ),
			el( 'div', { className: 'recipe-image' },
				el( MediaUpload, {
					onSelect: onSelectImage,
					allowedTypes: 'image',
					value: attributes.mediaID,
					render: function( obj ) {
						return el( components.Button, {
								className: attributes.mediaID ? 'image-button' : 'button button-large',
								onClick: obj.open
							},
							! attributes.mediaID ? i18n.__( 'Upload Image', 'gutenberg-examples' ) : el( 'img', { src: attributes.mediaURL } )
						);
					}
				} )
			),
			el( 'h3', {}, i18n.__( 'Ingredients', 'gutenberg-examples' ) ),
			el( RichText, {
				tagName: 'ul',
				multiline: 'li',
				placeholder: i18n.__( 'Write a list of ingredients…', 'gutenberg-examples' ),
				value: attributes.ingredients,
				onChange: function( value ) {
					props.setAttributes( { ingredients: value } );
				},
				className: 'ingredients',
			} ),
			el( 'h3', {}, i18n.__( 'Instructions', 'gutenberg-examples' ) ),
			el( RichText, {
				tagName: 'div',
				inline: false,
				placeholder: i18n.__( 'Write instructions…', 'gutenberg-examples' ),
				value: attributes.instructions,
				onChange: function( value ) {
					props.setAttributes( { instructions: value } );
				},
			} )
		)
	);
},

Аналогично смотрим вывод на фронтенде и функцию save, как контент записывается в базу, и заданные атрибуты.

Код может показаться сложным, в зависимости от уровня подготовки.

Сколько информации ни открывай, самый лучший способ понять любой код это погружение в него руками, головой и с помощью подсказок из интернета. Примеров в сети огромное количество.

Полезно взять наиболее популярные блоки, расширяющие Gutenberg, и изучить их.

Во-первых, растет база понимания и способы реализации самых разных типов блоков.

Во-вторых, появляется набор инструментов из готовых решений.

8
Оставить комментарий

avatar
3 Цепочка комментария
5 Ответы по цепочке
0 Последователи
 
Популярнейший комментарий
Цепочка актуального комментария
4 Авторы комментариев
АндрейИванАлексейЮрий Авторы недавних комментариев
  Подписаться  
новее старее большинство голосов
Уведомление о
Юрий
Гость

спасибо, интересно — мало пока по гуттенбергу материала, он ещё сыроват

Алексей
Гость

Спасибо за статью.

Работа с блоками Гутенберг — это как работа с произвольными полями?

Да, можно регистрировать произвольные поля вручную. Но есть замечательный ACF, который решает многие проблемы.

С блоками Гутенберг тоже самое? Может есть удобные плагин для создания блоков Гутенберг? Которые облегчают эту работу? Можете что то посоветовать?

Андрей
Гость

А что за RichText? у меня в этом примере ReferenceError: «RichText is not defined» в react-dom.min.js:117:150

Пролистать наверх