Как включить вариации стиля блоков для блоков в постах, динамически отображаемых через API интерактивности.

Вопрос или проблема

Я создаю блок, который показывает бесконечный список постов, используя Интерфейс Интерктивности:

render.php

<?php
    $block_attributes = get_block_wrapper_attributes()
?>
<div
    <?php echo $block_attributes; ?>
    <?php
    echo wp_interactivity_data_wp_context(
        array(
            'posts'    => null,
            'number'   => $attributes['number'],
            'offset'   => 0,
            'category' => $attributes['category'],
        )
    );
    ?>
    data-wp-interactive="milp-store"
    data-wp-init="actions.getFirstPosts"
    data-wp-on-window--beforeunload="callbacks.saveState"
>
    <div data-wp-watch="callbacks.renderPosts"></div>
    <button data-wp-style--display="context.display" data-wp-on--click="actions.getPosts"><?php _e( 'Load More', 'my-infinite-latest-posts' ); ?></button>
</div>

view.js

import { store, getContext, getElement } from '@wordpress/interactivity';

store('milp-store', {
    callbacks: {
        renderPosts() {
            const context = getContext();
            const element = getElement();
            if (context.posts !== null) {
                var html="";
                for (var i = 0; i < context.posts.length; i++) {
                    var post = context.posts[i];
                    html += '<article id="post-' + post.id + '" class="wp-block-my-infinite-latest-posts__post">';
                    html += '<h2 class="wp-block-my-infinite-latest-posts__post-title">' + post.title.rendered + '</h2>';
                    html += '<div class="wp-block-my-infinite-latest-posts__post-content">' + post.content.rendered + '</div>';
                    html += '</article>';
                }
                element.ref.innerHTML += html;
            }
        },
        saveState() {
            const context = getContext();
            // Хранение смещения постов в sessionStorage при смене страниц.
            sessionStorage.setItem('posts-offset', context.offset);
        }
    },
    actions: {
        *getFirstPosts() {
            const context = getContext()
            const number = sessionStorage.getItem('posts-offset') || context.number;
            const posts = yield fetch(
                'https://' + window.location.hostname + '/wp-json/wp/v2/posts?per_page=" + encodeURIComponent(number) + "&offset=0&categories=" + encodeURIComponent(context.category) + "&_fields=id,title,content',
                {
                    method: 'GET',
                    headers: {
                        'Cache-Control': 'max-age=60, must-revalidate',
                    },
                }
            ).then(function (response) {
                // Заголовок ответа X-WP-Total содержит общее количество записей в коллекции.
                context.total = response.headers.get('X-WP-Total');
                return response.json();
            }).catch(function (error) {
                console.error(error);
            });
            context.posts = posts;
            context.offset = parseInt(number);
            context.display = (context.offset < context.total) ? 'block' : 'none';
        },
        *getPosts() {
            const context = getContext();
            const posts = yield fetch(
                'https://' + window.location.hostname + '/wp-json/wp/v2/posts?per_page=" + encodeURIComponent(context.number) + "&offset=" + encodeURIComponent(context.offset) + "&categories=" + encodeURIComponent(context.category) + "&_fields=id,title,content',
                {
                    method: 'GET',
                    headers: {
                        'Cache-Control': 'max-age=60, must-revalidate',
                    },
                }
            ).then(function (response) {
                return response.json();
            }).catch(function (error) {
                console.error(error);
            });
            context.posts = posts;
            context.offset = parseInt(context.offset) + parseInt(context.number);
            context.display = (context.offset < context.total) ? 'block' : 'none';
        },
    }
});

block.json

{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 3,
    "name": "my/infinite-latest-posts",
    "title": "My Infinite Latest Posts",
    "description": "Display latest posts.",
    "textdomain": "my-infinite-latest-posts",
    "category": "widgets",
    "attributes": {
        "category": {
            "type": "integer",
            "default": 0
        },
        "number": {
            "type": "integer",
            "default": 5
        }
    },
    "supports": {
        "spacing": {
            "margin": true,
            "padding": true
        },
        "interactivity": true
    },
    "editorScript": "file:./index.js",
    "viewScriptModule": "file:./view.js",
    "style": "file:./style-index.css",
    "render": "file:./render.php"
}

WordPress включает стили вариации блока только в том случае, если соответствующий блок присутствует на отображаемой странице. Однако, поскольку мой блок последних постов с бесконечным просмотром динамически загружает посты через Интерфейс Интерктивности, WordPress не может обнаружить присутствие блоков внутри постов во время рендеринга. Как я могу обеспечить включение необходимых стилей вариации блоков, даже если WordPress изначально не распознает блоки на странице?

Стили вариации блоков анализируются и обрабатываются через wp_render_block_style_variation_support_styles(). Эта функция помечена как приватная и не должна вызываться сторонним кодом вне ядра WordPress. Эта функция вызывается благодаря подключению к render_block_data хук.

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

Вы можете создать разметку блока в виде строки и затем использовать do_blocks() чтобы отрендерить их:

do_blocks(
  <<<HTML
  <!-- wp:paragraph {"className":"is-style-foo"} -->
  <p class="is-style-foo">Render this style for its side effects.</p>
  <!-- /wp:paragraph -->
  HTML
);

.

Ответ или решение

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

Проблема

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

Решение

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

Шаги Решения

  1. Фиктивный Рендеринг:
    Создайте необходимую разметку блока как строку и используйте функцию do_blocks() для её рендеринга. Это позволит системе сработать и вызвать все сопутствующие функции для обработки стилей вариаций блоков.

    do_blocks(
      <<<HTML
      <!-- wp:paragraph {"className":"is-style-foo"} -->
      <p class="is-style-foo">Render this style for its side effects.</p>
      <!-- /wp:paragraph -->
      HTML
    );
  2. Инициализация:
    Можно интегрировать фиктивный рендеринг в начальный этап загрузки страницы, чтобы гарантировать, что стили будут обработаны до загрузки реальных данных от API.

  3. Автоматизация Компоновки:
    Если есть предварительно известная структура блоков, которые могут появляться динамически, разверните эти блоки на стороне сервера заранее, чтобы стили были включены.

Плечевые Меры

  • Кеширование: Убедитесь, что динамические загрузки минимально зависят от задержек в сети, используя механизмы кеширования данных, такие как sessionStorage.

  • Контроль Загрузки: Обеспечьте, что элементы управления загружаются корректно, используя правильные условия включения CSS-классов и атрибутов управления отображением.

  • Оптимизация SEO: Убедитесь, что контент, загруженный на клиенте, индексирован поисковыми системами, возможно, через использование SSR (Server Side Rendering) или предзагрузки на уровне сервера.

Заключение

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

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

Оцените материал
Добавить комментарий

Капча загружается...