Делитесь многоразовыми блоками между сайтами сети.

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

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

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

Я нашел решение здесь: https://krautpress.de/2020/wiederverwendbare-bloecke-zwischen-sites-einer-multisite-synchronisieren/

/**
 * Синхронизация повторно используемых блоков между сайтами многосайтовой сети.
 * 
 * @param int $post_id Идентификатор поста.
 * @param WP_Post $post Объект поста.
 */
add_action( 'publish_wp_block', 'slug_sync_reusable_blocks', 10, 2  );
function slug_sync_reusable_blocks( $post_id, $post ) {
    // Проверяем, есть ли у поста уже sync_hash или создаем его.
    if ( get_post_meta( $post_id, 'sync_hash', true ) !== '' ) {
        $sync_hash = get_post_meta( $post_id, 'sync_hash', true );
    } else {
        $sync_hash = uniqid( $post->post_title );
        update_post_meta( $post_id, 'sync_hash', $sync_hash );
    }
    $current_site_id = get_current_blog_id();

    // Получаем идентификаторы сайтов.
    $sites = get_sites(
        [
            'fields' => 'ids',
        ]
    );

    remove_action( 'publish_wp_block', 'slug_sync_reusable_blocks', 10 );
    foreach ( $sites as $site_id ) {
        if ( $current_site_id !== $site_id ) {
            switch_to_blog( $site_id );
            // Проверяем, уже ли блок синхронизирован, и обновляем его, если нужно.
            $existing_block_query = new WP_Query(
                [
                    'post_type' => 'wp_block',
                    'no_found_rows' => true,
                    'update_post_meta_cache' => false,
                    'update_post_term_cache' => false,
                    'fields' => 'ids',
                    'meta_key' => 'sync_hash',
                    'meta_value' => $sync_hash,
                    'posts_per_page' => 1,
                ]
            );

            if ( $existing_block_query->have_posts() ) {
                // Обновляем пост.
                $existing_post_id = $existing_block_query->posts[0];
                wp_update_post(
                    [
                        'ID' => $existing_block_query->posts[0],
                        'post_content' => $post->post_content,
                        'post_title' => $post->post_title,
                        'post_status' => 'publish',
                    ]
                );
            } else {
                // Создаем пост, если блока еще нет.
                wp_insert_post(
                    [
                        'post_type' => 'wp_block',
                        'post_content' => $post->post_content,
                        'post_title' => $post->post_title,
                        'post_status' => 'publish',
                        'meta_input' =>
                        [
                            'sync_hash' => $sync_hash,
                        ],
                    ]
                );
            }
            restore_current_blog();
        }
    }
    add_action( 'publish_wp_block', 'slug_sync_reusable_blocks', 10, 2  ); 
}

Я добавил код на свой сайт с помощью плагина “Code Snippets”, и он отлично работает. Если у вас есть “мастер” сайт, как у меня, и все остальные сайты в многосайтовой сети должны использовать точно такой же повторно используемый блок-шаблон, код нужно активировать только на этом мастер-сайте.

Я решил опубликовать свой собственный ответ, потому что ранее забыли упомянуть о:

  1. Нет необходимости создавать уникальный $sync_hash, чтобы обновить соответствующий шаблон, когда он существует на суб-сайте, плюс хранить эту связь в метаданных поста! Почему — потому что шаблоны не являются постами, они не могут иметь дублирующиеся заголовки. Мы можем соединять шаблоны по заголовкам.
  2. Также нет упоминания о wp_pattern_sync_status, который может быть синхронизирован/несинхронизирован.

Исходя из всего вышесказанного, я получил правильный код из этой статьи: https://rudrastyh.com/wordpress-multisite/sync-patterns-and-template-parts-across-sites.html

add_action( 'publish_wp_block', 'rudr_sync_reusable_blocks', 25, 2 );
function rudr_sync_reusable_blocks( $post_id, $post ) {

    $sync_status = get_post_meta( $post_id, 'wp_pattern_sync_status', true );

    $site_ids = get_sites(
        array(
            'fields' => 'ids',
            'site__not_in' => get_current_blog_id(),
        )
    );

    remove_action( 'publish_wp_block', 'rudr_sync_reusable_blocks', 25, 2 );

    foreach( $site_ids as $site_id ) {
        switch_to_blog( $site_id );

        $crossposted_block = get_page_by_title( $post->post_title, OBJECT, 'wp_block' );
        if( $crossposted_block ) {
            $crossposted_block_id = wp_update_post(
                array(
                    'ID' => $crossposted_block->ID,
                    'post_content' => $post->post_content,
                )
            );
        } else {
            $crossposted_block_id = wp_insert_post(
                array(
                    'post_type' => 'wp_block',
                    'post_content' => $post->post_content,
                    'post_title' => $post->post_title,
                    'comment_status' => 'closed',
                    'ping_status' => 'closed',
                    'post_status' => 'publish',
                )
            );
        }
        if( ! is_wp_error( $crossposted_block_id ) ) {
            if( 'unsynced' === $sync_status ) {
                update_post_meta( $crossposted_block_id, 'wp_pattern_sync_status', 'unsynced' );
            }
        }
        restore_current_blog();
    }

    add_action( 'publish_wp_block', 'rudr_sync_reusable_blocks', 25, 2 );

}

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

.

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

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

Теория

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

Пример

Рассмотрим, как можно достичь этой цели с помощью пользовательских действий и фильтров WordPress. Рассуждая по примеру с сайта KrautPress и усовершенствованным вариантом Rudrastyh, мы видим, что код использует действие publish_wp_block для синхронизации многоразовых блоков между сайтами. Ниже приведен экстракт кода, который выполняет эту функцию:

add_action( 'publish_wp_block', 'rudr_sync_reusable_blocks', 25, 2 );
function rudr_sync_reusable_blocks( $post_id, $post ) {
    $sync_status = get_post_meta( $post_id, 'wp_pattern_sync_status', true );

    $site_ids = get_sites(
        array(
            'fields' => 'ids',
            'site__not_in' => get_current_blog_id(),
        )
    );

    remove_action( 'publish_wp_block', 'rudr_sync_reusable_blocks', 25, 2 );

    foreach( $site_ids as $site_id ) {
        switch_to_blog( $site_id );

        $crossposted_block = get_page_by_title( $post->post_title, OBJECT, 'wp_block' );
        if( $crossposted_block ) {
            $crossposted_block_id = wp_update_post(
                array(
                    'ID' => $crossposted_block->ID,
                    'post_content' => $post->post_content,
                )
            );
        } else {
            $crossposted_block_id = wp_insert_post(
                array(
                    'post_type' => 'wp_block',
                    'post_content' => $post->post_content,
                    'post_title' => $post->post_title,
                    'comment_status' => 'closed',
                    'ping_status' => 'closed',
                    'post_status' => 'publish',
                )
            );
        }
        if( !is_wp_error( $crossposted_block_id ) ) {
            if( 'unsynced' === $sync_status ) {
                update_post_meta( $crossposted_block_id, 'wp_pattern_sync_status', 'unsynced' );
            }
        }
        restore_current_blog();
    }

    add_action( 'publish_wp_block', 'rudr_sync_reusable_blocks', 25, 2 );
}

#### Применение

1. **Подготовка окружения**: Имейте четкое представление о структуре вашей сети мультисайтов. Четкое понимание того, какие именно блоки необходимо синхронизировать и на каких сайтах, является ключевым.

2. **Создание многоразовых блоков**: На мастер-сайте создайте или отредактируйте многоразовые блоки. Эти блоки должны быть тщательно спроектированы с учетом нужд всех сайтов сети, так как их синхронизация практически оконечна без дополнительной кастомизации на уровне субсайтов.

3. **Настройка функциональности синхронизации**: Реализуйте код для синхронизации внутри файла функций (`functions.php`) вашей темы или используйте плагин типа "Code Snippets", чтобы внедрить код без изменений в тему. Проверяйте работоспособность на тестовом окружении, прежде чем внедрять на живом сайте.

4. **Тестирование и проверка**: Проведите серию тестов, чтобы убедиться, что блоки синхронизируются на всех сайтах, как ожидается. Убедитесь, что все редакторы на субсайтах могут использовать новые блоки без каких-либо проблем.

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

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

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

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