Compartilhando barras laterais dinâmicas em blogs multisite

8

Estou tentando encontrar uma maneira de recuperar uma barra lateral dinâmica de um blog e imprimi-la em outro blog na mesma instalação do Wordpress Multisite. eu tentei

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

Mas nada é retornado.

Também estava cansado de recuperar a barra lateral, get_blog_option($blog_id, 'sidebar_widgets')mas só consegui recuperar uma matriz para identificar quais widgets foram usados ​​pela barra lateral, mas não consegui encontrar uma distância para processar a matriz em uma barra lateral.

Timothy Wallis
fonte

Respostas:

7

Infelizmente, o switch_to_blog()método não funciona para esse fim. switch_to_blog()é realmente apenas uma opção parcial - faz algumas modificações para $wpdbajudar nas consultas ao banco de dados. Mas não é uma mudança completa da maneira que você pode imaginar.

Em particular, dynamic_sidebar()depende da chamada global $wp_registered_sidebars. Esse global é preenchido por register_sidebar(), geralmente chamado de um arquivo de tema como functions.php. Mas o functions.php e o restante do processo de configuração do tema não são executados novamente switch_to_blog(). Ou seja: se você estiver executando o Twenty Eleven no blog atual, ele registrará suas próprias barras laterais durante a inicialização; usar switch_to_blog()em um blog com o Twenty Ten não informará o Twenty Ten para configurar suas barras laterais. Você pode tentar forçá-lo (carregando manualmente o functions.php do switched-blog), mas é quase certo que isso levará a um desastre, devido a problemas com nomes de funções duplicados, ordem de carregamento, etc, etc.

Você pode tentar uma abordagem um pouco diferente: no blog com a barra lateral desejada, crie uma função que imprima o conteúdo da barra lateral no buffer de saída e, antes de imprimi-lo na tela, guarde-o em uma opção de site. Em seguida, você pode pegar a barra lateral (ou uma versão estática dela, pelo menos) em qualquer site da rede. Isso não funcionará se você precisar absolutamente de uma barra lateral totalmente dinâmica, mas para a maioria dos propósitos provavelmente não.

Outro método (que pode ser mais fácil) é renderizar a barra lateral com uma função em um arquivo mu-plugins ou algo parecido e chamar a função manualmente nos seus temas (ou conectá-la a um gancho comum da barra lateral). Pode levar algum trabalho para abstrair o conteúdo da WP_Widgetarquitetura, mas, por outro lado, seria uma solução verdadeiramente dinâmica para o problema em questão.

Boone Gorges
fonte
Graças a esses outros dois métodos, parecem ótimas idéias, eu já estava pensando em experimentar o primeiro, mas você poderia desenvolver um pouco a segunda idéia. Eu acho que estava tentando fazer algo assim usando get_blog_option('1','sidebars_widgets');para obter uma lista de widgets, mas não consegui encontrar os mesmos para processar os dados em uma barra lateral.
Timothy Wallis
Eu acho que vai ser mais problema do que vale a pena ficar com a infraestrutura real de widgets do WP. Em vez disso, abstraia a marcação do widget / PHP em uma função separada, que você chamará diretamente em um arquivo de modelo (ou vinculará a uma ação apropriada).
Boone Gorges
2

Deparou-se com o mesmo problema e meio que descobriu uma solução. O que estou fazendo é o seguinte:

1.) Sempre que algo for alterado na barra lateral do blog 1, salve uma matriz desses widgets e suas configurações como um transitório em todo o site, que desatualiza após 24 horas.

2.) Em todos os blogs filhos, coloque algum código no sidebar.php que agarra esse transiente em todo o site e exibe os widgets.

Parece bem fácil, mas foi muito difícil de entender ... e ainda está longe de ser perfeito.

Vamos cavar alguns códigos:

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

Isso pertence ao functions.php do blog 1 (ou melhor, um plugin no total) e salva os widgets no transitório sob medida a 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 );

Isso também pertence ao functions.php do blog 1 e renova o transitório toda vez que os widgets são atualizados.

E, finalmente, para os outros blogs, vá para 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 isso ajude alguém. Se alguém tiver alguma melhoria, será muito bem-vindo.

Christian Jung
fonte
1

Verifique se você tem exatamente o mesmo código de registro das barras laterais em execução nos dois sites durante o widgets_init. Isso deve preencher $ wp_registered_sidebars e resolver o problema destacado por Boone. Ainda não tentei isso.

kovshenin
fonte
0

Isso pode indicar a direção certa.

Xtreme One - Estrutura do tema - http://marketpress.com/product/xtreme/

Confira o vídeo - http://vimeo.com/52479425

O conceito básico é que, ao adicionar uma barra lateral a um site de rede, você também pode atribuí-la como uma barra lateral global.

Shawn
fonte
Interessante, eu me pergunto como ele está fazendo isso. Provavelmente modificado widget_update_callback para verificar se é global e, em seguida, executando uma consulta para adicioná-la a todos os blogs filhos do site atual.
Timothy Wallis
-1

Você está usando global $switched;?

global $switched;
switch_to_blog($blog_id);
dynamic_sidebar($sidebar_name);
restore_current_blog();
developdaly
fonte
O $switchedglobal é chamado de dentro switch_to_blog(). Você não precisa declará-lo no espaço para nome global.
amigos estão dizendo sobre boone gorges
Bom saber. Estou usando um método WPMU desatualizado. Então, são apenas barras laterais que você não pode acessar? E os menus?
developdaly
Eu precisaria testá-lo, mas acho que os menus podem funcionar em um switch_to_blog()contexto, porque não precisam ser registrados pelo tema antes de serem chamados (os dados de registro são armazenados no banco de dados).
amigos estão dizendo sobre boone gorges
Eu posso confirmar que os menus funcionam. Veja qual é o resultado do uso is_active_sidebar($sidebar_name).
developdaly