跨多站点博客共享动态侧边栏


8

我试图找到一个博客中检索动态边栏并将其打印在同一安装的Wordpress Multisite中的另一个博客上的方法。我努力了

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

但是什么也没有返回。

我也很疲倦地检索侧边栏,get_blog_option($blog_id, 'sidebar_widgets')但是我只能检索一个数组,以识别侧边栏使用了哪些小部件,但是我找不到办法将数组处理为侧边栏。

Answers:


7

不幸的是,该switch_to_blog()方法不适用于此目的。switch_to_blog()实际上只是部分切换-它对$wpdb数据库查询的帮助进行了一些修改。但这并不是您想象中的完全转换。

特别是dynamic_sidebar()取决于全局调用$wp_registered_sidebars。该全局register_sidebar()变量由填充,通常从诸如functions.php之类的主题文件中调用。但是functions.php和主题设置过程的其余部分不会由运行switch_to_blog()。就是说:如果您在当前博客上运行“二十一”,它将在启动期间注册其自己的侧边栏;使用switch_to_blog()到运行二十十一个博客将告诉二十十来设置它的侧边栏。您可以尝试强制使用它(通过手动加载switch-blog的functions.php),但是由于重复的函数名称,加载顺序等问题,几乎可以肯定会导致灾难。

您可能会尝试一些不同的方法:在具有所需侧栏的博客上,构建一个将侧栏内容打印到输出缓冲区的函数,然后在将其打印到屏幕之前,将其存储在site_option中。然后,您可以从网络上的任何站点获取侧边栏(至少是其静态版本)。如果您绝对需要一个完全动态的侧边栏,则此方法将无效,但对于大多数目的,您可能不需要。

另一种方法(可能更简单)是在mu-plugins文件或类似的文件中使用功能渲染边栏,然后在主题中手动调用该功能(或将其挂钩到常见的边栏挂钩)。从WP_Widget架构中提取内容可能需要花费一些工作,但另一方面,这将是针对当前问题的真正动态解决方案。


感谢其他两种方法听起来不错的主意,我已经在考虑尝试第一种方法,但是您可以稍微充实第二种方法吗?我想我试图通过使用get_blog_option('1','sidebars_widgets');获取小部件列表来做类似的事情,但是我还是找不到将数据处理到侧边栏中的方法。
蒂莫西·沃利斯

我认为,坚持使用WP的实际窗口小部件基础结构将带来更多的麻烦,而不是值得的。取而代之的是,将小部件标记/ PHP抽象到一个单独的函数中,然后直接在模板文件中调用该函数(或挂接到适当的操作)。
Boone Gorges'4

2

遇到相同的问题,并找到了解决方案。我在做什么如下:

1.)每当Blog 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();
}

希望这可以帮助别人。如果有任何改进,将非常欢迎。


1

确保您在widgets_init期间在两个站点上运行的侧栏注册代码完全相同。那应该填充$ wp_registered_sidebars并解决Boone突出显示的问题。我自己还没有尝试过。


0

这个“可能”为您指明了正确的方向。

Xtreme One-主题框架-http: //marketpress.com/product/xtreme/

观看视频-http://vimeo.com/52479425

基本概念是在将补充工具栏添加到网站时,您也可以将其分配为全局补充工具栏。


有趣的是,我想知道他是如何做到的。大概修改了widget_update_callback,以检查其全局状态,然后执行查询以将其添加到当前站点的所有子博客中。
蒂莫西·沃利斯

-1

您正在使用global $switched;吗?

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

$switched全球是从内部调用switch_to_blog()。您无需在全局名称空间中声明它。
Boone Gorges'4

很高兴知道。我使用的是过时的WPMU方法。那就是您无法访问的只是侧边栏吗?菜单呢?
2012年

我需要对其进行测试,但我猜测菜单可能在switch_to_blog()上下文中起作用,因为菜单在调用之前不需要通过主题进行注册(注册数据存储在数据库中)。
Boone Gorges'4

我可以确认菜单正常工作。查看使用的结果is_active_sidebar($sidebar_name)
2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.