Partage des barres latérales dynamiques sur les blogs multisites

8

J'essaie de trouver pour récupérer une barre latérale dynamique d'un blog et l'imprimer sur un autre blog dans la même installation de Wordpress Multisite. j'ai essayé

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

Mais rien n'est retourné.

J'étais également fatigué de faire revenir la barre latérale à travers, get_blog_option($blog_id, 'sidebar_widgets')mais je n'ai pu récupérer qu'une matrice pour identifier les widgets utilisés par la barre latérale, mais je n'ai pas pu trouver le chemin pour transformer la matrice en barre latérale.

Timothy Wallis
la source

Réponses:

7

Malheureusement, la switch_to_blog()méthode ne fonctionnera pas à cette fin. switch_to_blog()n'est vraiment qu'un commutateur partiel - il apporte quelques modifications à $wpdbcette aide avec les requêtes de base de données. Mais ce n'est pas un changement complet comme vous pouvez l'imaginer.

En particulier, dynamic_sidebar()dépend de l'appel global $wp_registered_sidebars. Ce global est rempli par register_sidebar(), qui est généralement appelé à partir d'un fichier de thème comme functions.php. Mais functions.php et le reste du processus de configuration du thème ne sont pas réexécutés par switch_to_blog(). C'est-à-dire: si vous exécutez Twenty Eleven sur le blog actuel, il enregistrera ses propres barres latérales lors du démarrage; l'utilisation switch_to_blog()d'un blog exécutant Twenty Ten ne dira pas à Twenty Ten de configurer ses barres latérales. Vous pouvez essayer de le forcer (en chargeant manuellement le fichier functions.php du blog commuté) mais cela est presque certain de conduire à un désastre, en raison de problèmes avec les noms de fonction en double, l'ordre de chargement, etc., etc., etc.

Vous pouvez essayer une approche quelque peu différente: sur le blog avec la barre latérale que vous souhaitez, créez une fonction qui imprimera le contenu de la barre latérale dans le tampon de sortie, puis avant de l'imprimer à l'écran, stockez-la dans une option site_option. Ensuite, vous pouvez récupérer la barre latérale (ou une version statique de celle-ci, au moins) à partir de n'importe quel site du réseau. Cela ne fonctionnera pas si vous avez absolument besoin d' une barre latérale totalement dynamique, mais dans la plupart des cas, vous n'en avez probablement pas.

Une autre méthode (qui peut être plus facile) consiste à rendre la barre latérale avec une fonction dans un fichier mu-plugins ou quelque chose comme ça, puis appeler la fonction manuellement dans vos thèmes (ou la raccorder à un crochet commun de la barre latérale). Il pourrait prendre un certain travail pour extraire le contenu de l' WP_Widgetarchitecture, mais d'un autre côté, ce serait une solution vraiment dynamique au problème en question.

Gorges de Boone
la source
Merci ces deux autres méthodes sonnent comme de grandes idées, je pensais déjà à essayer la première, mais pourriez-vous étoffer un peu la deuxième idée. Je pense que j'essayais de faire quelque chose comme ça en utilisant get_blog_option('1','sidebars_widgets');pour obtenir une liste de widgets mais je n'ai pas trouvé de toute façon de traiter les données dans une barre latérale.
Timothy Wallis
Je pense que ça va être plus difficile que de s'en tenir à l'infrastructure de widget réelle de WP. Au lieu de cela, résumez le balisage du widget / PHP dans une fonction distincte, que vous appellerez ensuite directement dans un fichier de modèle (ou accrocherez à une action appropriée).
gorges de Boone du
2

Ran dans le même problème et sorte de trouver une solution. Ce que je fais est le suivant:

1.) Chaque fois que quelque chose est modifié dans la barre latérale du blog 1, enregistrez un tableau de ces widgets et de leurs paramètres en tant que transitoire sur tout le site, qui est dépassé après 24 heures.

2.) Sur tous les blogs enfants, mettez du code dans sidebar.php qui saisit ce transitoire à l'échelle du site et affiche les widgets.

Cela semble assez facile, mais était très difficile à comprendre… et est encore loin d'être parfait.

Examinons un peu de code:

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

Cela fait partie de functions.php du blog 1 (ou mieux, un plugin tous ensemble) et enregistre les widgets dans le transitoire sur mesure toutes les 24 heures.

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

Cela fait également partie du fichier functions.php du blog 1 et renouvelle le transitoire à chaque mise à jour des widgets.

Et enfin pour les autres blogs, allez dans 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();
}

J'espère que cela peut aider quelqu'un. Si l'on a des améliorations, elles seront les bienvenues.

Christian Jung
la source
1

Assurez-vous que le même code d'enregistrement des barres latérales est en cours d'exécution sur les deux sites pendant widgets_init. Cela devrait remplir $ wp_registered_sidebars et résoudre le problème mis en évidence par Boone. Je n'ai pas essayé ça moi-même.

kovshenin
la source
0

Cela pourrait vous orienter dans la bonne direction.

Xtreme One - Thème Framework - http://marketpress.com/product/xtreme/

Regardez la vidéo - http://vimeo.com/52479425

Le concept de base consiste à ajouter une barre latérale à un site réseau, vous pouvez également l'assigner en tant que barre latérale globale.

Shawn
la source
Intéressant, je me demande comment il le fait. Widget_update_callback probablement modifié pour vérifier et voir s'il est global, puis exécuter une requête pour l'ajouter à tous les blogs enfants du site actuel.
Timothy Wallis
-1

Utilisez-vous global $switched;?

global $switched;
switch_to_blog($blog_id);
dynamic_sidebar($sidebar_name);
restore_current_blog();
developdaly
la source
Le $switchedglobal est appelé de l'intérieur switch_to_blog(). Vous n'avez pas besoin de le déclarer dans l'espace de noms global.
Boone Gorges
Bon à savoir. J'utilise une méthode WPMU obsolète. Alors, n'est-ce que des barres latérales auxquelles vous n'êtes pas en mesure d'accéder? Et les menus?
developdaly
J'aurais besoin de le tester, mais je suppose que les menus pourraient fonctionner dans un switch_to_blog()contexte, car ils n'ont pas besoin d'être enregistrés par le thème avant d'être appelés (les données d'enregistrement sont stockées dans la base de données).
Boone Gorges
Je peux confirmer que les menus fonctionnent. Voyez quel est le résultat de l'utilisation is_active_sidebar($sidebar_name).
developdaly