WordPress

Как мы создаем админ-панели, о которых мечтают все владельцы сайтов

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

Раньше страничка на любой CMS делалась так:

  • утверждалась статичная верстка;
  • по ней на бэкенде создавался темплейт с полями для заполнения;
  • пользователь заходил в админку и мог внести в эти поля текст или картинки.

То есть, редактирование материала на сайте было жестким и ограничивалось рамками заданного темплейта каждой страницы.

Потом появились зерокодинг-конструкторы, которые покорили индустрию тем, что любой юзер мог быстро создать полноценный сайт без каких-либо навыков программирования. По какой-то причине из всех крупных CMS только WordPress внедрил подобный инструмент, который можно использовать для коммерческой разработки.

Клиенту должно быть удобно работать с админкой

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

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

Как мы делаем свои админ-панели?

Берем у дизайнера макеты, разбиваем на блоки и начинаем верстать:

  • отдаем компоненты в работу фронтенд-разработчику;
  • собранные блоки по мере готовности отправляются в бэкенд;
  • и именно контент-менеджер собирает готовые блоки согласно дизайн-макетам.

Таким образом, разработка ведется параллельно и комплексно: фронтенд делает блок, бэкенд создает на него динамику, а контент-менеджер сразу размещает. Каждый элемент в отдельности очень легко поддерживать и кастомизировать, поэтому в итоге мы получаем прекрасно собираемый и масштабируемый сайт, четкое распределение задач и довольно высокие скорость и качество разработки.

Такой подход не только облегчает управление сайтом нашим заказчикам, но и позволяет внедрять интересные фичи и механики. При помощи блоков мы можем создавать и гибко управлять множеством вещей. Например, в одном из проектов мы интегрировали большое количество GА4-ивентов (аналитика и события по ней), которые включались и выключались в админке буквально через чекбокс. Это дало возможность маркетингу и аналитикам в бизнесе действовать независимо от нас и, следовательно, сэкономило кучу времени и денег клиенту.

Мы можем создавать блоки двумя разными способами:

Для создания полей в этих блоках используется плагин Advanced Custom Fields PRO (подробнее об этом в следующих статьях).

Такой подход позволяет полностью или частично изолировать логику блока от основного приложения. В нашей практике даже было разворачивание отдельного react или vue приложения в рамках gutenberg блока. Причем не обязательно блок должен находится в контентой части записи. WordPress позволяет использовать gutenberg и в области виджетов, с помощью этого можно конструировать модальные окна, навигационные меню и тд. А так же открываются следующие возможности:

  • объединение ряда блоков одним функционалом путем клонирования групп полей (примером этому может служить функционал выбора события генерируемого на блоке в GA или создание сложного анимированного фона у блока);
  • создание обособленого «микроприложения», например, блок с выводом записей, возможностью добавления фильтрации, пагинации, бесконечной прокрутки и т. д.;
  • создание блока-обертки для внутренних блоков (слайдеры, сложные сетки);
  • создание собственной колоночной системы по дизайн-макетам;
  • создание конструктора форм обратной связи прямо в визуальном редакторе;
  • условные блоки для отображения на определенном разрешении.

Разберем процесс создания блока с помощью функции acf_register_block_type

На хук инициализации плагина повесим функцию, в которой зарегистрируем блок. В данном случае это блок, отвечающий за вывод новостей:

add_action('acf/init', 'wwzrds_news_list_block_init');

function wwzrds_news_list_block_init() {
	if (function_exists('acf_register_block_type')) {
		acf_register_block_type([
			'name'            => 'news-list',
			'title'           => __('Блог (сетка)'),
			'icon'            => file_get_contents(THEME_DIR . '/assets/img/icons/block.svg'),
			'render_callback' => 'wwzrds_news_list_block_callback',
			'mode'            => 'preview',
			'supports'        => [
				'align'  => false,
				'mode'   => false,
				'jsx'    => false,
				'anchor' => false
			],
			'example'         => [
				'attributes'    => [
					'mode' => 'preview',
					'data' => [
						'is_preview' => true,
					],
				],
			],
		]);
	}
}

function wwzrds_news_list_block_callback($block, $content = '', $is_preview = false, $post_id = 0) {
	$args = [
		'block'      => $block,
		'content'    => $content,
		'is_preview' => $is_preview,
		'post_id'    => $post_id,
	];

	$fields = get_fields() ?: [];
	$args   = array_merge($args, $fields);

	get_template_part('template-parts/blocks/block-news-list/block-news-list', args: $args);
}

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

В самом файле шаблона нам нужно вытащить эти данные. Для начала обозначим переменную $args, чтобы наша ide’шка не ругалась:

// Fix PhpStorm inspection on undefined variable.
if ( empty( $args ) ) {
	$args = [];
}

Далее обозначим значения полей по умолчанию:

// Array of default arguments (parameters) for template part.
$defaults = [
	'custom_class'    => '',
	'is_preview'      => false,
	'has_uppercase'   => false,
	/**
	 * One of:
	 * - latest
	 * - chosen
	 */
	'mode'            => 'latest',
	'posts_ids'       => [],
	'pagination'      => true,
	'per_page'        => get_option( 'posts_per_page' ),
	'use_params'      => true,
	'enable_filter'   => true,
  'taxonomy'        => 'technology',
];

Затем объединим входящие аргументы и дефолтные значения в один массив и распакуем его. Для этого мы используем функцию-хелпер, которая учитывает типы дефолтных значений и вложенные массивы, но можно использовать и стандартную функцию WordPress wp_parse_args:

// Fill args with defaults to avoid errors.
$args = wwzrds_parse_args( $args, $defaults );

// Unpack arguments to variables.
[
  // Кастомный класс для элемента блока
	'custom_class'    => $custom_class,
	// Проверяем, находимся ли мы в режиме редактирования
	'is_preview'      => $is_preview,
	// ACF поле. По дизайну наш блок может быть или в верхенем регистре или нет
	'has_uppercase'   => $has_uppercase,
  // ACF поле. Выбор режима отображения. Тут есть возможность или выводить последние записи
  // или выбранные
	'mode'            => $mode,
	// ACF поле. ID постов, которые нужно выводить, если mode === 'chosen'
	'posts_ids'       => $ids,
  // ACF поле. Выводить ли пагинацию для блока
	'pagination'      => $show_pagination,
  // ACF поле. Кол-во выводимых записей на странице
	'per_page'        => $posts_per_page,
  // ACF поле. Сохранять ли параметры фильтрации и пагинации в url
	'use_params'      => $use_params,
	// ACF поле. Включть отображение фильтра по таксономии
	'enable_filter'   => $enable_filter,
  // ACF поле. Таксономия для фильтрации
  'taxonomy'        => $taxonomy,
] = $args;

Далее на основе этих переменных генерируем разметку. Саму разметку, стили и скрипты приводить не будем. Пропустим этот этап.
В админке создаем группу полей со следующими правилами отображения:

Ну и создадим сами поля:

В режиме редактирования страницы добавляем наш созданный блок и смотрим что получилось.

Так выглядит панель с настройками блока:

И все изменения применяются в реальном времени в области редактора:

В итоге мы получаем настраиваемый блок с изолированной логикой, который можно встроить в любое место сайта:

Что еще важно сказать про преимущества такого редактора?

WordPress практически полностью перешёл на JSX-синтаксис, и все их новые темплейты рендерятся в HTML. Скорость работы при таком подходе феноменальная, потому что, по большому счёту, мы рендерим кэшированную статику, и это дает ощутимый прирост к нашей производительности. Кстати, с таким подходом очень удобно работать с бенчмарками, PageSpeed и с другими измерителями, в частности по методологии Lighthouse.

Такие админ-панели идеально подходят под корпоративные сайты любого размера и любой отрасли. Мы считаем, что это лучшее решение на рынке на сегодняшний день.