Совместное использование динамических боковых панелей в многосайтовых блогах

8

Я пытаюсь найти динамическую боковую панель из одного блога и распечатать ее в другом блоге в той же установке Wordpress Multisite. я пытался

switch_to_blog($blog_id);
dynamic_sidebar($sidebar_name);
restore_current_blog();

Но ничего не возвращается.

Мне также надоело извлекать боковую панель, get_blog_option($blog_id, 'sidebar_widgets')но я мог только получить массив, идентифицирующий, какие виджеты использовались боковой панелью, но я не мог найти способ обработать массив в боковую панель.

Тимоти Уоллис
источник

Ответы:

7

К сожалению, switch_to_blog()метод не будет работать для этой цели. switch_to_blog()действительно является лишь частичным переключателем - он вносит некоторые изменения в $wpdbэту помощь с запросами к базе данных. Но это не полный переход, как вы можете себе представить.

В частности, dynamic_sidebar()зависит от глобального Android $wp_registered_sidebars. Этот глобальный register_sidebar()объект заполнен , который обычно вызывается из файла темы, например functions.php. Но functions.php и остальная часть процесса установки темы не выполняются повторно switch_to_blog(). То есть: если вы используете Twenty Eleven в текущем блоге, он будет регистрировать собственные боковые панели во время запуска; использование switch_to_blog()блога Twenty Ten не скажет Twenty Ten настроить его боковые панели. Вы можете попытаться форсировать его (загрузив файл functions.php на переключаемый блог вручную), но это почти наверняка приведет к катастрофе из-за проблем с дублирующимися именами функций, порядка загрузки и т. Д. И т. Д. И т. Д.

Вы могли бы попробовать несколько иной способ: В блоге с нужной боковой панелью создайте функцию, которая будет печатать содержимое боковой панели в выходной буфер, а затем, перед печатью на экране, сохраните его в site_option. Затем вы можете получить боковую панель (или, по крайней мере, ее статическую версию) с любого сайта в сети. Это не сработает, если вам абсолютно необходима полностью динамическая боковая панель, но в большинстве случаев это не так.

Другой метод (который может быть проще) состоит в том, чтобы визуализировать боковую панель с функцией в файле mu-plugins или чем-то в этом роде, а затем вручную вызвать функцию в ваших темах (или подключить ее к общему крюку боковой панели). Может потребоваться некоторая работа для абстрагирования контента от WP_Widgetархитектуры, но, с другой стороны, это будет действительно динамичное решение проблемы.

Boone Gorges
источник
Благодаря тому, что другие два метода звучат как отличные идеи, я уже думал о том, чтобы попробовать первый, но не могли бы вы немного рассказать о второй идее. Я думаю, что пытался сделать что-то вроде этого, используя get_blog_option('1','sidebars_widgets');для получения списка виджетов, но я не мог найти, чтобы обработать данные в боковую панель.
Тимоти Уоллис
Я думаю, что будет больше проблем, чем стоит придерживаться реальной инфраструктуры виджетов WP. Вместо этого абстрагируйте разметку виджета / PHP в отдельную функцию, которую вы затем вызовете непосредственно в файле шаблона (или подключитесь к соответствующему действию).
Ущелья Бун
2

Наткнулся на ту же проблему и вроде нашел решение. Что я делаю, это следующее:

1.) Всякий раз, когда что-то изменяется на боковой панели блога 1, сохраняйте массив этих виджетов и их настройки в виде переходного процесса, который устарел через 24 часа.

2.) На всех дочерних блогах, поместите некоторый код в sidebar.php, который захватывает этот переход по всему сайту и отображает виджеты.

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

Давайте углубимся в некоторый код:

function antwortzeit_cache_widgets() {
    if ( false === ( $widgets = get_site_transient( 'antwortzeit_widgets' ) ) ) {
        global $wp_registered_sidebars, $wp_registered_widgets;

        foreach ( (array) $wp_registered_sidebars as $key => $value ) {
            if ( sanitize_title($value['name']) == sanitize_title('Breite Spalte') ) {
                $index = $key;
                break;
            }
        }

        $sidebars_widgets = wp_get_sidebars_widgets();
        if ( empty( $sidebars_widgets ) )
            return false;

        if ( empty($wp_registered_sidebars[$index]) || !array_key_exists($index, $sidebars_widgets) || !is_array($sidebars_widgets[$index]) || empty($sidebars_widgets[$index]) )
            return false;

        $sidebar = $wp_registered_sidebars[$index];
        foreach ( (array) $sidebars_widgets[$index] as $id ) {
            if ( !isset($wp_registered_widgets[$id]) ) continue;

            $params = array_merge(
                array( array_merge( $sidebar, array('widget_id' => $id, 'widget_name' => $wp_registered_widgets[$id]['name']) ) ),
                (array) $wp_registered_widgets[$id]['params']
            );

            // Substitute HTML id and class attributes into before_widget
            $classname_ = '';
            foreach ( (array) $wp_registered_widgets[$id]['classname'] as $cn ) {
                if ( is_string($cn) )
                    $classname_ .= '_' . $cn;
                elseif ( is_object($cn) )
                    $classname_ .= '_' . get_class($cn);
            }
            $classname_ = ltrim($classname_, '_');
            $params[0]['before_widget'] = sprintf($params[0]['before_widget'], $id, $classname_);

            $params = apply_filters( 'dynamic_sidebar_params', $params );

            $widgets[] = array(
                'callback'  => $wp_registered_widgets[$id]['callback'],
                'base'      => $wp_registered_widgets[$id]['callback'][0]->id_base,
                'id'        => $wp_registered_widgets[$id]['callback'][0]->id,
                'params'    => $params,
            );
        }
        set_site_transient( 'antwortzeit_widgets', $widgets, 60 * 60 * 24 );
    }
}
add_action( 'init', 'antwortzeit_cache_widgets');

Это входит в файл functions.php блога 1 (или, лучше сказать, плагин вообще) и сохраняет виджеты в переходный процесс на заказ каждые 24 часа.

function antwortzeit_widgetbruecke( $instance, $new_instance ) {
    delete_site_transient('antwortzeit_widgets');
    antwortzeit_cache_widgets();
    return $instance;
}
add_filter( 'widget_update_callback', 'antwortzeit_widgetbruecke', 10, 2 );

Это также относится к блогу functions.php и обновляет переходный процесс при каждом обновлении виджетов.

И, наконец, для других блогов зайдите в sidebar.php:

global $blog_id;

if($blog_id !== 1) {
switch_to_blog(1);
    $widgets = get_site_transient( 'antwortzeit_widgets' );
    if($widgets) :
        foreach($widgets as $widget) :
        if ( is_callable($widget['callback']) ) {
            call_user_func_array($widget['callback'], $widget['params']);
        }
        endforeach; 
    endif;
restore_current_blog();
}

Надеюсь, это может кому-нибудь помочь. Если есть какие-то улучшения, они будут очень рады.

Кристиан Юнг
источник
1

Убедитесь, что у вас есть одинаковый код регистрации боковых панелей, работающий на обоих сайтах во время widgets_init. Это должно заполнить $ wp_registered_sidebars и решить проблему, которую выделил Бун. Сам не пробовал.

КОВШЕНИН
источник
0

Это «может» направить вас в правильном направлении.

Xtreme One - Theme Framework - http://marketpress.com/product/xtreme/

Проверьте видео - http://vimeo.com/52479425

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

Shawn
источник
Интересно, интересно, как он это делает. Вероятно, изменен widget_update_callback, чтобы проверить, является ли он глобальным, а затем выполнить запрос, чтобы добавить его во все дочерние блоги текущего сайта.
Тимоти Уоллис
-1

Вы используете global $switched;?

global $switched;
switch_to_blog($blog_id);
dynamic_sidebar($sidebar_name);
restore_current_blog();
developdaly
источник
$switchedГлобальный вызывается из switch_to_blog(). Вам не нужно объявлять это в глобальном пространстве имен.
Бун Ущелье
Хорошо знать. Я использую устаревший метод WPMU. Так что это просто боковые панели, к которым у вас нет доступа? Как насчет меню?
Developdaly
Мне нужно было бы проверить это, но я предполагаю, что меню могут работать в switch_to_blog()контексте, потому что они не должны регистрироваться темой перед вызовом (регистрационные данные хранятся в базе данных).
Boone Gorges
Я могу подтвердить, что меню работает. Посмотрите, что результат использования is_active_sidebar($sidebar_name).
Developdaly