Блог

Опанування динамічних блоків WordPress: Поєднання PHP та JavaScript для інтерактивного контенту

Дізнайтеся, як створювати динамічні блоки WordPress, які використовують як PHP, так і JavaScript для надання інтерактивного та керованого даними контенту для ваших користувачів.

Огляд

Динамічні блоки WordPress пропонують потужний спосіб створення контенту, який виходить за рамки статичного HTML, дозволяючи інтегрувати дані в реальному часі та інтерактивні елементи. На відміну від статичних блоків, динамічні блоки генерують свій вивід на стороні сервера за допомогою PHP, що дозволяє їм отримувати та відображати актуальну інформацію. Ця стаття надає практичний посібник із розробки власних динамічних блоків, охоплюючи основні концепції реєстрації блоків, зворотних викликів рендерингу на стороні сервера та обробки атрибутів на стороні клієнта. Ми розглянемо приклад крок за кроком, демонструючи, як створити динамічний блок, який відображає останні записи, пропонуючи основу для більш складних інтерактивних компонентів.

Опанування динамічних блоків WordPress: Поєднання PHP та JavaScript для інтерактивного контенту

WordPress, по суті, є надійною системою управління контентом (CMS), побудованою на модульній архітектурі PHP та базі даних MySQL. Його розширюваність є ключовою перевагою, яка в основному досягається за допомогою тем та плагінів. Поява Gutenberg, редактора блоків, революціонізувала створення контенту, запровадивши модульний інтерфейс на основі JavaScript. Хоча статичні блоки Gutenberg чудово підходять для структурованого, незмінного контенту, багато реальних сценаріїв вимагають динамічного, інтерактивного контенту, керованого даними. Саме тут на допомогу приходять динамічні блоки, пропонуючи потужний міст між логікою PHP на стороні сервера та інтерактивністю JavaScript на стороні клієнта.

Розуміння потужності динамічних блоків

Статичні блоки, які є стандартними в Gutenberg, генерують HTML на стороні клієнта під час збереження. Цей HTML зберігається безпосередньо в контенті запису. Хоча це ефективно для статичного контенту, цей підхід має обмеження, коли йдеться про дані, які часто змінюються або вимагають обробки на стороні сервера. Динамічні блоки, з іншого боку, вирішують цю проблему, генеруючи свій вивід на стороні сервера за допомогою PHP. Коли користувач переглядає сторінку, що містить динамічний блок, WordPress виконує PHP-функцію (render_callback), щоб згенерувати HTML блоку "на льоту". Це дозволяє блоку отримувати дані в реальному часі з бази даних, взаємодіяти з іншими функціями WordPress та представляти завжди актуальну інформацію.

Цей рендеринг на стороні сервера є критично важливим з кількох причин:

  • Дані в реальному часі: Відображення останніх записів, майбутніх подій, цін на акції або будь-яких інших даних, які часто змінюються.
  • Складна логіка: Виконання обчислень, запитів до користувацьких типів записів або інтеграція із зовнішніми API перед генерацією виводу.
  • Безпека: Очищення та перевірка даних перед їх відображенням, особливо при роботі з контентом, створеним користувачами, або зовнішніми джерелами.
  • Продуктивність: Передача складних завдань рендерингу на сервер іноді може покращити продуктивність на стороні клієнта.

Анатомія динамічного блоку

Динамічний блок, як і будь-який інший блок Gutenberg, визначається його метаданими та реєстрацією JavaScript. Однак його унікальна характеристика полягає в атрибуті render_callback, зазначеному під час реєстрації. Ця функція зворотного виклику відповідає за генерацію виводу HTML блоку на сервері.

Ось розбивка ключових компонентів:

  1. Реєстрація блоку (JavaScript): Вам все ще потрібно зареєструвати свій блок за допомогою registerBlockType() у вашому файлі JavaScript. Це повідомляє Gutenberg, що ваш блок існує, і як обробляти його атрибути та інтерфейс редактора.
  2. Атрибути: Це поля даних, пов'язані з вашим блоком, які зберігаються в контенті запису. Для динамічних блоків атрибути в основному використовуються для налаштування поведінки та налаштувань блоку в редакторі. Фактичний відображуваний контент генерується render_callback.
  3. render_callback (PHP): Це серце динамічного блоку. Це PHP-функція, яка отримує атрибути блоку як аргумент і повертає рядок HTML для відображення на фронтенді.
  4. Інтерфейс редактора (JavaScript): Ви все ще будете створювати інтерфейс блоку в редакторі Gutenberg за допомогою компонентів React. Цей інтерфейс дозволяє користувачам налаштовувати атрибути блоку та бачити попередній перегляд (часто спрощене представлення) того, як виглядатиме динамічний контент.

Покроковий посібник: Створення динамічного блоку "Останні записи"

Створимо практичний приклад: динамічний блок, який відображає список останніх записів із вашого сайту WordPress.

Передумови:

  • Локальне середовище розробки WordPress.
  • Базове розуміння PHP та JavaScript.
  • Плагін або тема, куди ви додасте код блоку.

Крок 1: Налаштуйте свій плагін/тему блоку

Якщо у вас немає власного плагіна чи теми, створіть простий. Для цього прикладу ми припустимо, що ви додаєте це до плагіна.

Крок 2: Зареєструйте блок (JavaScript)

У файлі JavaScript вашого плагіна (наприклад, src/index.js) ви зареєструєте блок. Ми будемо використовувати @wordpress/blocks та @wordpress/i18n для інтернаціоналізації.

// src/index.js

import { registerBlockType } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';

// Імпортуйте компонент редагування вашого блоку
import Edit from './edit';

registerBlockType( 'my-dynamic-blocks/recent-posts', {
    title: __( 'Recent Posts', 'my-dynamic-blocks' ),
    icon: 'list-view',
    category: 'widgets',
    attributes: {
        numberOfPosts: {
            type: 'number',
            default: 5,
        },
        showExcerpt: {
            type: 'boolean',
            default: true,
        },
    },
    edit: Edit,
    // Функція save() НЕ потрібна для динамічних блоків
    // Зворотний виклик render_callback на стороні сервера оброблятиме вивід
} );

Крок 3: Створіть компонент редактора (JavaScript)

Тепер створіть файл src/edit.js. Цей компонент визначатиме, як блок виглядає та поводиться в редакторі Gutenberg.

// src/edit.js

import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, RangeControl, ToggleControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import ServerSideRender from '@wordpress/server-side-render';

export default function Edit( { attributes, setAttributes } ) {
    const blockProps = useBlockProps();
    const { numberOfPosts, showExcerpt } = attributes;

    return (
        <div { ...blockProps }>
            <InspectorControls>
                <PanelBody title={ __( 'Post Settings', 'my-dynamic-blocks' ) }>
                    <RangeControl
                        label={ __( 'Number of Posts', 'my-dynamic-blocks' ) }
                        value={ numberOfPosts }
                        onChange={ ( value ) => setAttributes( { numberOfPosts: value } ) }
                        min={ 1 }
                        max={ 10 }
                    />
                    <ToggleControl
                        label={ __( 'Show Excerpt', 'my-dynamic-blocks' ) }
                        checked={ showExcerpt }
                        onChange={ ( value ) => setAttributes( { showExcerpt: value } ) }
                    />
                </PanelBody>
            </InspectorControls>
            {
                // Використовуйте ServerSideRender для відображення попереднього перегляду динамічного блоку
                <ServerSideRender
                    block="my-dynamic-blocks/recent-posts"
                    attributes={ attributes }
                />
            }
        </div>
    );
}

Зверніть увагу, що ми не визначаємо функцію save(). Це ключова відмінність для динамічних блоків. Компонент ServerSideRender використовується для відображення попереднього перегляду виводу блоку безпосередньо в редакторі, роблячи запит до сервера.

Крок 4: Підключіть скрипти та зареєструйте рендеринг на стороні сервера (PHP)

У головному PHP-файлі вашого плагіна (наприклад, my-dynamic-blocks.php) вам потрібно підключити ваш файл JavaScript та зареєструвати тип блоку, включаючи render_callback.

<?php
/**
 * Plugin Name: My Dynamic Blocks
 * Description: A simple plugin for dynamic Gutenberg blocks.
 * Version: 1.0
 * Author: Your Name
 */

function my_dynamic_blocks_register_block() {
    // Реєстрація типу блоку
    register_block_type( 'my-dynamic-blocks/recent-posts', array(
        'editor_script' => 'my-dynamic-blocks-editor-script',
        'render_callback' => 'my_dynamic_blocks_render_recent_posts',
        'attributes' => array(
            'numberOfPosts' => array(
                'type' => 'number',
                'default' => 5,
            ),
            'showExcerpt' => array(
                'type' => 'boolean',
                'default' => true,
            ),
        ),
    ) );
}
add_action( 'init', 'my_dynamic_blocks_register_block' );

function my_dynamic_blocks_enqueue_editor_scripts() {
    wp_enqueue_script(
        'my-dynamic-blocks-editor-script',
        plugins_url( 'build/index.js', __FILE__ ), // Припускаючи, що у вас є процес збірки
        array( 'wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-i18n', 'wp-server-side-render' ),
        filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' )
    );
}
add_action( 'enqueue_block_editor_assets', 'my_dynamic_blocks_enqueue_editor_scripts' );

/**
 * Зворотний виклик рендерингу для динамічного блоку "Останні записи".
 *
 * @param array $attributes Атрибути блоку.
 * @return string HTML вивід.
 */
function my_dynamic_blocks_render_recent_posts( $attributes ) {
    $number_of_posts = isset( $attributes['numberOfPosts'] ) ? (int) $attributes['numberOfPosts'] : 5;
    $show_excerpt    = isset( $attributes['showExcerpt'] ) ? (bool) $attributes['showExcerpt'] : true;

    $args = array(
        'posts_per_page' => $number_of_posts,
        'post_status'    => 'publish',
        'orderby'        => 'date',
        'order'          => 'DESC',
        'ignore_sticky_posts' => true,
    );

    $recent_posts_query = new WP_Query( $args );

    $output = '';

    if ( $recent_posts_query->have_posts() ) {
        $output .= '<ul class="wp-block-my-dynamic-blocks-recent-posts">'; // Використовуйте клас для стилізації
        while ( $recent_posts_query->have_posts() ) {
            $recent_posts_query->the_post();
            $output .= '<li>';
            $output .= '<a href="' . esc_url( get_permalink() ) . '">' . esc_html( get_the_title() ) . '</a>';
            if ( $show_excerpt ) {
                $output .= '<p>' . get_the_excerpt() . '</p>';
            }
            $output .= '</li>';
        }
        $output .= '</ul>';
        wp_reset_postdata(); // Важливо: скинути дані запису після власного циклу
    } else {
        $output = '<p>' . __( 'No posts found.', 'my-dynamic-blocks' ) . '</p>';
    }

    return $output;
}

Пояснення PHP коду:

  • my_dynamic_blocks_register_block(): Ця функція підключається до init для реєстрації нашого типу блоку. Важливо, що вона визначає render_callback як my_dynamic_blocks_render_recent_posts і також передає атрибути блоку, що відображає те, що визначено в JavaScript.
  • my_dynamic_blocks_enqueue_editor_scripts(): Ця функція підключається до enqueue_block_editor_assets для завантаження нашого файлу JavaScript спеціально для редактора. Вона включає wp-server-side-render як залежність.
  • my_dynamic_blocks_render_recent_posts(): Це наш render_callback. Він отримує масив $attributes, очищає та перетворює їх на правильні типи, а потім використовує WP_Query для отримання останніх записів. Він створює HTML список <ul> і повертає його. wp_reset_postdata() є життєво важливим після власного циклу WP_Query для запобігання конфліктам з основним запитом WordPress.

Крок 5: Зберіть ваш JavaScript

Якщо ви використовуєте сучасний процес збірки JavaScript (наприклад, @wordpress/scripts), вам потрібно буде зібрати ваші ресурси. Виконайте npm run build (або yarn build) у каталозі вашого плагіна.

Крок 6: Активуйте та протестуйте

Активуйте ваш плагін. Тепер, коли ви додасте блок "Останні записи" до запису або сторінки, ви побачите інтерфейс редактора. Область попереднього перегляду покаже вивід, згенерований вашим PHP-зворотним викликом. Коли ви опублікуєте або оновите запис, той самий PHP-зворотний виклик буде виконано на фронтенді для відображення динамічного контенту.

Найкращі практики та застереження

  • Безпека перш за все: Завжди очищайте та перевіряйте будь-які дані, що надходять з атрибутів або зовнішніх джерел, перш ніж використовувати їх у вашому render_callback. Використовуйте функції WordPress, такі як esc_html(), esc_url(), sanitize_text_field() тощо.
  • wp_reset_postdata(): Якщо ваш render_callback використовує WP_Query або змінює глобальний об'єкт $post, завжди викликайте wp_reset_postdata() після цього, щоб відновити початковий запит та дані запису.
  • Міркування щодо продуктивності: Хоча динамічні блоки потужні, надмірний або складний рендеринг на стороні сервера може вплинути на час завантаження сторінки. Оптимізуйте ваші запити та логіку рендерингу. Розгляньте механізми кешування, якщо виникають проблеми з продуктивністю.
  • Попередній перегляд редактора: Компонент ServerSideRender надає хороший попередній перегляд, але він покладається на запит до сервера. Для дуже складних блоків це може бути не миттєво. Переконайтеся, що ваш render_callback ефективний.
  • Обробка атрибутів: Атрибути в основному призначені для налаштування блоку в редакторі. render_callback відповідає за отримання та відображення фактичного динамічного контенту. Уникайте зберігання великих обсягів динамічних даних безпосередньо в атрибутах.
  • Умовні позначення: Використовуйте унікальні префікси для назв ваших блоків (наприклад, my-plugin-slug/block-name) та назв PHP-функцій, щоб уникнути конфліктів з іншими плагінами або темами.
  • Інтернаціоналізація: Використовуйте __() та _n() для перекладних рядків як у вашому JavaScript, так і в PHP коді.

Розширення можливостей динамічних блоків: За межами останніх записів

Приклад "Останні записи" - це лише верхівка айсберга. Ви можете використовувати динамічні блоки для:

  • Відображення користувацьких типів записів: Демонстрація продуктів, елементів портфоліо або подій.
  • Контент, специфічний для користувача: Відображення контенту, релевантного для увійшовшого користувача.
  • Інтерактивні форми: Хоча складні форми можуть все ще вимагати спеціалізованих плагінів, прості динамічні форми можна створювати.
  • Візуалізація даних: Отримання даних з API та відображення діаграм або графіків (хоча це часто вимагає більш просунутих бібліотек JavaScript).
  • Інтеграція з іншими плагінами: Динамічне відображення даних, керованих іншими плагінами.

Висновок

Динамічні блоки WordPress є незамінним інструментом для розробників, які прагнуть створювати справді інтерактивні та керовані даними досвіди в редакторі Gutenberg. Розуміючи, як реєструвати блоки з функціями render_callback та ефективно керувати атрибутами, ви можете створювати потужні компоненти, які отримують та відображають інформацію в реальному часі. Хоча статичні блоки служать своїй меті для структурованого контенту, динамічні блоки відкривають новий рівень функціональності, дозволяючи вам подолати розрив між логікою на стороні сервера та представленням на фронтенді. Дотримуючись найкращих практик безпеки, продуктивності та організації коду, ви можете впевнено розробляти надійні та корисні динамічні блоки, які покращують ваші веб-сайти WordPress.

Sources (5)