Compartir barras laterales dinámicas en blogs multisitio

8

Estoy tratando de encontrar un lugar para recuperar una barra lateral dinámica de un blog e imprimirla en otro blog en la misma instalación de Wordpress Multisite. Yo he tratado

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

Pero no se devuelve nada.

También me cansé de recuperar la barra lateral, get_blog_option($blog_id, 'sidebar_widgets')pero solo pude recuperar una matriz para identificar qué widgets usaba la barra lateral, pero no pude encontrar lejos para procesar la matriz en una barra lateral.

Timothy Wallis
fuente

Respuestas:

7

Desafortunadamente, el switch_to_blog()método no va a funcionar para este propósito. switch_to_blog()en realidad es solo un cambio parcial: realiza algunas modificaciones a $wpdbesa ayuda con las consultas de la base de datos. Pero no es un cambio completo en la forma en que te puedas imaginar.

En particular, dynamic_sidebar()depende de global llamado $wp_registered_sidebars. Este global está poblado por register_sidebar(), que generalmente se llama desde un archivo de tema como functions.php. Pero functions.php, y el resto del proceso de configuración del tema, no se vuelve a ejecutar switch_to_blog(). Es decir: si está ejecutando Twenty Eleven en el blog actual, registrará sus propias barras laterales durante el inicio; usando switch_to_blog()un blog que ejecuta Twenty Ten no le dirá a Twenty Ten que configure sus barras laterales. Podría intentar forzarlo (cargando manualmente las funciones del php del blog conmutado), pero es casi seguro que provocará un desastre, debido a problemas con nombres de funciones duplicados, orden de carga, etc., etc.

Puede intentar una táctica algo diferente: en el blog con la barra lateral que desee, cree una función que imprima el contenido de la barra lateral en el búfer de salida y luego, antes de imprimirlo en la pantalla, guárdelo en una opción de sitio. Luego puede tomar la barra lateral (o una versión estática de ella, al menos) de cualquier sitio en la red. Esto no funcionará si necesita absolutamente una barra lateral totalmente dinámica, pero para la mayoría de los propósitos probablemente no.

Otro método (que puede ser más fácil) es representar la barra lateral con una función en un archivo de plugins mu o algo así, y luego llamar a la función manualmente en sus temas (o engancharla a un gancho de barra lateral común). Puede tomar algo de trabajo abstraer el contenido de la WP_Widgetarquitectura, pero por otro lado, sería una solución verdaderamente dinámica para el problema en cuestión.

Gargantas de Boone
fuente
Gracias a que esos otros dos métodos parecen buenas ideas, ya estaba pensando en probar el primero, pero ¿podrías desarrollar un poco la segunda Idea? Creo que estaba tratando de hacer algo como esto usando get_blog_option('1','sidebars_widgets');para obtener una lista de widgets, pero no pude encontrar de todos modos para procesar los datos en una barra lateral.
Timothy Wallis
Creo que será más problemático de lo que vale la pena quedarse con la infraestructura de widgets real de WP. En cambio, abstraiga el marcado de widget / PHP en una función separada, que luego llamará directamente en un archivo de plantilla (o enganche a una acción apropiada).
Gargantas de Boone
2

Me encontré con el mismo problema y descubrí una solución. Lo que estoy haciendo es lo siguiente:

1.) Siempre que se cambie algo en la barra lateral del blog 1, guarde una serie de esos widgets y su configuración como transitorios en todo el sitio, que se quedan obsoletos después de 24 horas.

2.) En todos los blogs secundarios, coloque algún código en sidebar.php que tome este transitorio de todo el sitio y muestre los widgets.

Suena bastante fácil, pero fue muy difícil de entender ... y aún está lejos de ser perfecto.

Veamos un poco de código:

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');

Esto pertenece al blog 1 functions.php (o mejor, un complemento completo) y guarda los widgets en el transitorio a medida cada 24 horas.

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 );

Esto también pertenece a las funciones.php del blog 1 y renueva el transitorio cada vez que se actualizan los widgets.

Y finalmente, para los otros blogs, ingrese en 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();
}

Espero que esto pueda ayudar a alguien. Si uno tiene alguna mejora, será muy bienvenido.

Christian Jung
fuente
1

Asegúrese de tener exactamente el mismo código de registro de barras laterales ejecutándose en ambos sitios durante widgets_init. Eso debería llenar $ wp_registered_sidebars y resolver el problema que Boone destacó. No he probado esto yo mismo.

kovshenin
fuente
0

Este 'poder' te señala en la dirección correcta.

Xtreme One - Marco temático - http://marketpress.com/product/xtreme/

Mira el video - http://vimeo.com/52479425

El concepto básico es cuando se agrega una barra lateral a un sitio de red, también se puede asignar como una barra lateral global.

Shawn
fuente
Interesante, me pregunto cómo lo está haciendo. Probablemente modificó widget_update_callback para verificar y ver si es global y luego ejecutar una consulta para agregarlo a todos los blogs secundarios del sitio actual.
Timothy Wallis
-1

Estas usando global $switched;?

global $switched;
switch_to_blog($blog_id);
dynamic_sidebar($sidebar_name);
restore_current_blog();
desarrollado
fuente
Lo $switchedglobal se llama desde adentro switch_to_blog(). No necesita declararlo en el espacio de nombres global.
Boone Gorges
Bueno saber. Estoy usando un método WPMU desactualizado. Entonces, ¿son solo las barras laterales a las que no puedes acceder? ¿Qué hay de los menús?
Desarrollado el
Tendría que probarlo, pero supongo que los menús podrían funcionar en un switch_to_blog()contexto, porque no es necesario que el tema los registre antes de llamarlos (los datos de registro se almacenan en la base de datos).
Boone Gorges el
Puedo confirmar que los menús funcionan. Vea cuál es el resultado del uso is_active_sidebar($sidebar_name).
Desarrollado el