Сайт перешел на функционал групп
Читаем новость, обсуждаем, делимся впечатлениями или может есть какие пожелания? Перейти
24 декабря 2018 в 01:03
Владимир Otshelnik-Fm
на сайт, и вы сможете вступить в группу.
Вы сможете подписаться на выход новых материалов группы.
Вы сможете подписаться на новые комментарии к выбранной записи группы.

Редактор блоков WordPress. 2 часть - создаём первый блок


Какие бы стандартные блоки не давал новый WordPress редактор блоков (Gutenberg) в комплекте - но под каждый сайт требуются не стандартные блоки, а кастомные. Можно конечно под проект стилизовать имеющиеся - просто подкорректировав их стили. Но мы пойдем дорогой трудной, дорогой не прямой...

Навыки, необходимые для этого урока:
  Понимание API WordPress
  Умение написания простого плагина вордпресс
  Базовые знания php и js


     В этом уроке:
        Создадим свой первый блок:

Внешний вид первого блока
Внешний вид первого блока

Gutenberg в wordpress - как работать? Здесь и найдёте ответ!
Как я и обещал - первые блоки мы будем создавать без особых инструментов для этого, и без специально настроенного окружения. Если вы работаете в IDE - отлично. Но если юзаете блокнот в клеточку типа notepad++ или его младшего собрата sublime - на первое время хватит и их.
Также примеры будут на ES5, никакого ESNext или JSX. Что это и как это - мы разобрали в прошлом уроке. Создать простой блок можно и без них. Главное - уловить концепцию написания блока. Простые шаги, чтобы в js-файле его зашевелить под гутенберг (блочный редактор вордпресс).

Этот урок будет целостным и законченным. Этакий Hello World.

Содержание:

  1. Структура проекта
  2. PHP файл
  3. CSS файл
  4. JS файл
  5. Блок создан - его вид, внутри, в БД
  6. Что дальше?


Структура проекта:

Структура проекта
Структура проекта

Создаем новый проект. Я его назвал: OtFm First Block
Повторяем структуру и пустые файлы как на скриншоте выше.

otfm-first-block.php будет содержать регистрацию и подключение css и js файлов
index.php - пустой файл-заглушка.

Папка first-block содержит 2 файла:
block-style.css - файл стилей блока. Необходим и в редакторе блоков, и в фронтенде.
index.js - наш первый блок. Необходим только в редакторе.


PHP файл:

В файле otfm-first-block.php добавляем заголовки плагина

<?php
/*
Plugin Name:    OtFm First Block
Description:    First Block for WordPress 5 block editor
Version:        1.0.0
Author:         Otshelnik-Fm (Wladimir Druzhaev)
Author URI:     https://otshelnik-fm.ru/
*/
if (!defined('ABSPATH')) exit; // Game over

На 9-й строке запрещаем прямой просмотр php файла - если сервер это вдруг позволяет сделать.

Плагин готов - активируем.

Регистрация блока и ресурсов

Следующим шагом нам надо зарегистрировать наши стили и скрипт. И на уровне php зарегистрировать новый блок, подключив к нему js и css файл.

Делаем это в одной функции:

add_action('init', 'otfm_fb_load');
function otfm_fb_load(){
    // регистрируем стиль
    wp_register_style(
        'otfm_fb_style',
        plugins_url( 'first-block/block-style.css', __FILE__ )
    );

    // регистрируем скрипт
    wp_register_script(
        'otfm_fb_script',
        plugins_url( 'first-block/index.js', __FILE__ ),
        array( 'wp-blocks', 'wp-element' ),
        filemtime( plugin_dir_path( __FILE__ ) . 'first-block/index.js' )
    );

    // не WordPress 5.0
    if( !function_exists( 'register_block_type' ) ) return;

    // регистрируем блок
    register_block_type( 'otfm-first/first-block', array(
        'editor_script' => 'otfm_fb_script',    // подключаем скрипт в админке
        'editor_style'  => 'otfm_fb_style',     // подключаем стиль в админке
        'style'         => 'otfm_fb_style'      // подключаем стиль в фронтенде
    ) );
}

Функция висит на хуке init. Внутри функции 4-ре логические секции:
1. Регистрируем стиль
2. Регистрируем скрипт
3. Проверяем что это ВП 5.0
4. Регистрируем блок

Рассмотрим подробней:

1. Регистрация стиля (4-я строка) - ничего необычного. Знакомая нам ВП функция.

2. При регистрации скрипта (10-я строка, тоже стандартная ВП функция), но стоит обратить внимание на зависимости (13-я строка). WordPress скрипты разбиты на packages (пакеты) - зависимости, которые вызываются до загрузки нашего блока. Чтобы не тянуть весь бандл со всеми пакетами - их и разбили на мелкие части. И в вордпресс 5.0, при работе с блоками, необходимо точно определять зависимости. В противном случае вы получите в консоли ошибку undefined скрипта.

array( 'wp-blocks', 'wp-element' ), - это минимальные зависимости для создания блока. Здесь вы найдете их handle.
Ну и собственно описание всех пакетов в этом справочнике

где:
wp-blocks - это библиотека JavaScript в вордпресс, которая обрабатывает регистрацию блоков и связанные с ними функции.
wp-element – библиотека, которая обрабатывает пользовательский интерфейс блока (block UI).

3. Если кто-то в WordPress ниже 5.0 версии запустит наш плагин - не появится fatal error из-за несуществующей функции на 21-й строке. Если вы блок регистрируете через хук init - обязательно делайте такую проверку (18-я строка).

4. На 21-й строке мы регистрируем наш первый блок.
Первым аргументом функция принимает имя блока. Чтобы не было конфликтов - используется соглашение в виде пространства имён: otfm-first/first-block

Вторым аргументом функция register_block_type() принимает массив (необязательно):

array(
    'editor_script' => '',
    'editor_style'  => '',
    'script'  => '',
    'style'  => '',
    'render_callback'  => ''
)
  • editor_script – handle скрипта, который загружается только в редакторе.
  • editor_style – handle стилевого файла, который загружается только в редакторе.
  • script – handle скрипта, который загружается только в фронтенде.
  • style – handle стилевого файла, который загружается только в фронтенде.
  • render_callback - коллбек функция, для создания динамических блоков с помощью не js, а php

editor_script, editor_style и style мы и использовали выше, подключив скрипт и стиль для редактора Gutenberg блоков. И стиль для фронтенд стилизации блока.

Проверим загрузку наших ресурсов - открыв создание поста:

Наши ресурсы загружены
Наши ресурсы загружены

- при создании записи стиль и скрипт загружаются. А посмотрев в фронтенде - мы увидим, что там загрузился только стиль. В общем заготовка работает.

Еще вариант подключения ресурсов

Ещё один вариант подключения скриптов и стилей - ВП 5.0 вводит для этого еще 2 хука:

  • enqueue_block_editor_assets - хук срабатывает в редакторе блоков (по сути - в админке)
  • enqueue_block_assets - хук срабатывает везде где есть блоки (и сам редактор и в фронтенде - где выводится блок)

т.е. вы можете скрипт и/или стиль не предавать в массиве register_block_type(), а написать свою функцию с подключением скрипта и стиля (wp_enqueue_style() и wp_enqueue_script()) и вешать на эти хуки. И их область подключения будет определена только в том месте, где эти хуки срабатывают.
Тут нет единого мнения - кто-то делает так, кто-то по другому. Все варианты правильные.

С php файлом мы закончили.

CSS файл:

В наш стилевой файл block-style.css внесем следующие стилевые правила:

.otfm_fb_text {
    background-color: #a0db91;
    border: 1px solid #6da270;
    color: #3a407e;
    font-size: 16px;
    line-height: normal;
    margin: 5px 0;
    padding: 12px;
}

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

JS файл:

Окунёмся в мир js и чудный мир блоков!

Полный код блока

Вписываем этот код в index.js файл:

( function( blocks, element ) {
    var el = element.createElement;

    blocks.registerBlockType( 'otfm-first/first-block', {
        title: 'Первоблок',
        description: 'Описание блока в сайдбаре',
        icon: 'universal-access-alt',   // dashicons
        category: 'layout',             // category of the block
        keywords: [                     // search sinonime block
            'первоблок',
            'otfm'
        ],

        edit: function() {
            return el(
                'p',
                { className: 'otfm_fb_text' },
                'Текст блока в редакторе'
            );
        },

        save: function() {
            return el( 
                'p', 
                { className: 'otfm_fb_text' }, 
                'Сохраненный текст в фронтенде :-D' 
            );
        }
    }); // END registerBlockType

}(
    window.wp.blocks,
    window.wp.element
) );

- глобально наш код состоит из 2-х фрагментов:
   В первом мы определяем переменные
   Во втором мы регистрируем блок.

Смотрите на принт ниже:

Разбор js
Разбор js

Итак:
В нашу анонимную функцию мы передаем window.wp.blocks и window.wp.element - именно их мы и указали в зависимостях в php файле.

Внутри нашей функции мы определили переменную el (2-я строка js-кода) из element.createElement - она отвечает за создание тега. Теперь она создает простой тег (p - параграф в нашем случае), или использует компоненты - например RichText (это может быть RichText, BlockControls AlignmentToolbar, ColorPalette и т.д.)

Посмотрим на 15-ю строку:
в функции редактирования мы и создаем тег p через el
Это эквивалентно такой записи:

edit: function() {
        return wp.element.createElement(
            'p',
            { className: 'otfm_fb_text' },
            'Текст блока в редакторе'
        );
    },

- но чтобы код был компактный и следуя принципам DRY (Don't repeat yourself - не повторяйся) - его сократили, загнав метод создания элемента в переменную. Когда внутри js много html тегов - это упрощает создание тега. Здесь и вступает в работу библиотека React.

Функция создания блока

Давайте перейдем к функции создания блока.
Создаем блок через функцию registerBlockType()
Эта функция первым аргументом (4-я строка) получает имя блока (строка), тот namespace - пространство имен, что мы определили регистрируя блок через php.
Второй аргумент - объект конфигурации (настроек) блока. В него входят атрибуты, функция редактирования и функция сохранения.

Что же там внутри объекта:

title - заголовок блока.
description - описание блока, которое появляется справа (сайдбар "Настройки", он же "Инспектор")
icon - имя dashicon или svg иконка. В следующих уроках расскажу как добавить svg иконку.
category - категория, в которую попадет блок.
Gutenberg (редактор блоков) зарегистрировал такие:
   "common" - основные блоки
   "formatting" - форматирование
   "layout" - элементы разметки
   "widgets" - виджеты
   "embed" - вставки

Категории блоков
Категории блоков

keywords - массив ключевых слов для поиска. Блочный редактор предоставляет удобный механизм поиска блоков:
По иконке "Плюс" вы открываете меню выбора блока - там доступен и поиск блоков.
Или в пустом блоке нажимаете /ключевое-слово - более быстрый механизм поиска блоков по ключам.
В массиве keywords допускается вписать 3 значения. Но это не значит что всего 3 синонима для поиска вы задать можете. Можно все слова вписать в одну строку - например так:

keywords: [
        'otfm первоблок ещё слово'
    ],

- т.е. ограничений на слова нету. По всем этим словам редактор блоков будет искать. Причем он начинает поиск с вводом первых букв слова.

С основными настройками для нашего блока мы разобрались.

Описание всех настроек registerBlockType():

  • title (строка): имя в редакторе
  • description (не обязательно. строка): описывает назначение блока
  • icon (не обязательно. Dashicon или JS element): иконка блока
  • category (строка): категория блока
  • keywords (не обязательно. массив): до трёх ключевых слов поиска блока
  • attributes (не обязательно. объект): доп атрибуты - обрабатывает данные динамического блока
  • edit (функция): функция, которая возвращает разметку для визуализации в редакторе
  • save (функция): функция, которая возвращает разметку, которая будет отображена в фронтенде
  • supports (не обязательно. объект): определяет поддерживаемые блоком функции
  • styles (не обязательно. массив): определяет вариации стилей
  • transforms (не обязательно. массив): правила преобразования блока в другие блоки
  • parent (не обязательно. массив): блок может быть зависим от других блоков. Указывается родительский блок

Дополнительно давайте опишем вкратце supports опцию:
Свойство support принимает объект с логическими значениями, чтобы определить, поддерживает ли ваш блок определенные основные функции.
Например так:

supports:{
    multiple: false // запретить добавление блока более одного раза (например тег "Далее")
},

скажет редактору блоков что наш блок можно в контенте записи использовать только один раз. Например тег "More" в вордпресс - его глупо использовать дважды.

Ознакомьтесь с ними в руководстве по блокам

Рассмотрим styles:
- это дополнительные стили. Или BSV - block style variation (вариации стиля блока)

styles: [
    // обозначим по умолчанию.
    {
        name: 'default',
        label: 'Квадратный',
        isDefault: true
    },
    {
        name: 'round',
        label: 'Круглый'
    }
],

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

Edit & Save

Перейдем к функции edit на 14-й строке:
В документации edit и save описаны здесь
Это уровень абстракции поверх react. В этой функции мы видим в реальном времени все наши изменения в редакторе блоков.
В нашем коде мы создаем элемент параграфа. Задаём дополнительный css класс блоку - чтобы в css файле написать для него стили. И задаем неизменяемый текст для параграфа. На этом с редактированием всё.

Перейдем к функции save на 22-й строке:
Здесь нам надо повторить всю верстку как и в функции edit. В данном случае они идентичны, за исключением текста в параграфе. Именно этот блок отобразится у нас в фронтенде.

Эти две функции принимают props - опции состояния. Примерно так:
edit: function( props ) - но т.к. в этом уроке мы не использовали стилизацию или динамические данные - этого в примере нет. Это будет рассмотрено в последующих уроках.

Создание блока в общих чертах

Если рассматривать в общих чертах создание блока - то вот вид очень простого блока на jsx:

registerBlockType(
    'otfm-first/first-block',
    {
        title: 'Первоблок',
        icon: 'universal-access-alt',
        category: 'layout',
        keywords: ['первоблок','otfm'],
        edit: () => <h2>Welcome to the Gutenberg Editor!</h2>,
        save: () => <h2>How am I looking on the front end?</h2>
    }
);

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

Блок создан - его вид, внутри, в БД:

Итак: мы познакомились с примером создания блока. Вы этот код можете сохранить и он уже будет работать в вашем редакторе блоков:

Заготовка вполне рабочая
Заготовка вполне рабочая

В фронтенде наш блок отличается только текстом, как и задумано:

Вид в фронтенде
Вид в фронтенде

Посмотрим вёрстку блока - стандартные классы и наш дополнительный что мы задали:

Вёрстка блока
Вёрстка блока

WordPress 5.0 редактор блоков даёт классы по такому шаблону:
wp-block-/namespaces/ т.е. у на будет wp-block-otfm-first-first-block

В базе данных - в таблице wp_posts запишутся такие данные в публикацию:

<!-- wp:otfm-first/first-block -->
<p class="wp-block-otfm-first-first-block otfm_fb_text">Сохраненый текст в фронтенде :-D</p>
<!-- /wp:otfm-first/first-block -->

Но как мы видели скриншотом выше - html комментарии из исходного кода парсер вордпресса вычищает и они не попадают в исходный код страницы.

Что дальше?

Мы создали простой статичный блок. Рассмотрели регистрацию css/js и зависимости при их регистрации. Зарегистрировали блок и задали его первоначальную конфигурацию. Это первые шаги в программирование под новый редактор блоков.
В следующем уроке мы создадим блок, который будем развивать и дополнять, изучая новые возможности блочного редактора.

Здесь было очень много ссылок на хэндбук Gutenberg редактора (gutenberg wordpress documentation - ещё раз) - как видите официальная документация там в порядке. Наверно надо немного привыкнуть к ней - и тогда вы с лёгкостью сможете в ней искать нужные ответы. Документация улучшается. А следить за её обновлением нужно конечно через гитхаб - работа ведется регулярно.

В первой части я упомянул про инструмент create-guten-block и если вы уже созрели - предлагаю попробовать его. Т.к. создавать новый блок с ноля несколько тоскливо - надо регистрировать блок, скрипты и стили в php. Потом в js - каркас блока вставить (а для этого подойдут макросы или горячие клавиши на создание каркаса в js-файле внутри вашей ide) - несколько скрупулёзное занятие.
Если вы работаете через WP-CLI - у них есть поддержка блоков: команда для создания такого каркаса.

Ещё один источник и "подглядеть" можно в самом вордпресс. На гитхабе список реализованных в вордпрессе блоков вы найдете по этой ссылке


Ну как? Сложно создать первый блок?
Какие трудности у вас были и какие впечатления вы испытали от своего первого гутенберг блока?
- делитесь в комментариях!

1 комментарий

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

Авторизация
*
*
Регистрация
*
*
*
Настоящим подтверждаю, что я ознакомлен и согласен с условиями политики конфиденциальности
Генерация пароля
Написать
*
*
Закрыть