web-dev-qa-db-ja.com

マルチサイトブログ間での動的サイドバーの共有

私はWordpress Multisiteの同じインストールで、あるブログから動的なサイドバーを回収して別のブログに印刷する方法を見つけようとしています。私が試してみました

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

しかし、何も返されません。

サイドバーをget_blog_option($blog_id, 'sidebar_widgets')経由で再検索するのも面倒ですが、サイドバーで使用されているウィジェットを特定するためにアレイを再試行することしかできませんでしたが、アレイをサイドバーに処理する方法を見つけることができませんでした。

8
Timothy Wallis

残念ながら、switch_to_blog()メソッドはこの目的のためには機能しません。 switch_to_blog()は実際には部分的な切り替えにすぎません - データベースの問い合わせに役立つように$wpdbを変更しています。しかし、それはあなたが想像するかもしれない方法の完全な切り替えではありません。

特に、dynamic_sidebar()$wp_registered_sidebarsと呼ばれるグローバルに依存します。このグローバルにはregister_sidebar()が移入されています。これは一般にfunctions.phpのようなテーマファイルから呼び出されます。しかし、functions.php、およびその他のテーマ設定プロセスは、switch_to_blog()によって再実行されません。つまり、現在のブログでTwenty Elevenを実行している場合は、起動時にサイドバーが登録されます。 Twenty Tenを実行しているブログにswitch_to_blog()を使用すると、 not になります その sidebars。あなたはそれを強制することを試みることができます(手動で切り替えられたブログのfunctions.phpをロードすることによって)、これは重複する関数名、ロード順序などに関する問題のために、災害につながることはほぼ確実です.

やや異なる方法を試してみるとよいでしょう。サイドバーのあるブログで、サイドバーの内容を出力バッファに出力する関数を作成してから、それを画面に出力する前に、site_optionに隠します。その後、ネットワーク上の任意のサイトからサイドバー(または少なくともその静的バージョン)を入手できます。 絶対に 完全に動的なサイドバーが必要な場合、これは機能しませんが、ほとんどの目的のためにはおそらくそうしないでしょう。

もう1つの方法(これは簡単かもしれません)は、サイドバーをmu-pluginsファイルなどの関数でレンダリングしてから、テーマ内でその関数を手動で呼び出す(または共通のサイドバーフックにフックする)ことです。 WP_Widgetアーキテクチャーからコンテンツを抽象化するのにはいくらかの作業が必要になるかもしれませんが、その一方でそれは当面の問題に対する真に動的な解決策になるでしょう。

7
Boone Gorges

同じ問題に突き当たり、解決策を見つけました。私がやっているのは次のとおりです。

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

これはblog 1のfunctions.php(あるいはもっと良いのはすべてプラグイン)に属していて、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 );

これはblog 1の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();
}

うまくいけば、これは誰かを助けることができます。何か改善があったら、それらは大歓迎です。

2
Christian Jung

Widgets_initの実行中に、両方のサイトでまったく同じサイドバー登録コードが実行されていることを確認してください。それは$ wp_registered_sidebarsを生成し、Booneが強調した問題を解決するはずです。自分で試したことはありません。

1
kovshenin

これはあなたを正しい方向に向けるかもしれません。

Xtreme One - テーマフレームワーク - http://marketpress.com/product/xtreme/

ビデオをチェックしてください - http://vimeo.com/52479425

基本概念は、サイドバーをネットワークサイトに追加するときに、それをグローバルサイドバーとして割り当てることもできます。

0
shawn