Chia sẻ Sidebars động trên nhiều trang blog


8

Tôi đang cố gắng tìm cách lấy lại một thanh bên động từ một blog và in nó trên một blog khác trong cùng bản cài đặt Wordpress Multisite. Tôi đã thử

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

Nhưng không có gì được trả lại.

Tôi cũng mệt mỏi khi truy xuất thanh bên qua get_blog_option($blog_id, 'sidebar_widgets')nhưng tôi chỉ có thể truy xuất một mảng xác định những vật dụng nào được sử dụng bởi thanh bên, nhưng tôi không thể tìm cách xử lý mảng thành thanh bên.

Câu trả lời:


7

Thật không may, switch_to_blog()phương pháp này sẽ không hoạt động cho mục đích này. switch_to_blog()thực sự chỉ là một công tắc một phần - nó thực hiện một số sửa đổi để $wpdbtrợ giúp với các truy vấn cơ sở dữ liệu. Nhưng nó không phải là một công tắc hoàn chỉnh theo cách bạn có thể tưởng tượng.

Đặc biệt, dynamic_sidebar()phụ thuộc vào toàn cầu được gọi là $wp_registered_sidebars. Toàn cầu này được điền bởi register_sidebar(), thường được gọi từ một tệp chủ đề như hàm.php. Nhưng hàm.php, và phần còn lại của quá trình thiết lập chủ đề, không được chạy lại bởi switch_to_blog(). Điều đó có nghĩa là: nếu bạn đang chạy Twenty Eleven trên blog hiện tại, nó sẽ đăng ký thanh bên của chính nó trong khi khởi động; sử dụng switch_to_blog()cho một blog chạy Twenty Ten sẽ không nói với Twenty Ten để thiết lập sidebars của nó . Bạn có thể thử buộc nó (bằng cách tải thủ công các tệp.php của blog) nhưng điều này gần như chắc chắn sẽ dẫn đến thảm họa, do các vấn đề với tên hàm trùng lặp, thứ tự tải, v.v.

Bạn có thể thử một chiến thuật hơi khác: Trên blog có thanh bên mà bạn muốn, hãy xây dựng một chức năng sẽ in nội dung của thanh bên vào bộ đệm đầu ra, sau đó trước khi in nó ra màn hình, hãy nhét nó vào site_option. Sau đó, bạn có thể lấy thanh bên (hoặc ít nhất là phiên bản tĩnh của nó) từ bất kỳ trang web nào trên mạng. Điều này sẽ không hoạt động nếu bạn thực sự cần một thanh bên hoàn toàn năng động, nhưng đối với hầu hết các mục đích, bạn có thể không.

Một phương pháp khác (có thể dễ dàng hơn) là kết xuất thanh bên bằng một hàm trong tệp mu-plugins hoặc một cái gì đó tương tự, sau đó gọi hàm theo cách thủ công trong các chủ đề của bạn (hoặc móc nó vào một móc bên thanh chung). Nó có thể mất một số công việc để trừu tượng nội dung ra khỏi WP_Widgetkiến trúc, nhưng mặt khác, nó sẽ là một giải pháp thực sự năng động cho vấn đề trong tay.


Cảm ơn hai phương pháp khác nghe có vẻ là những ý tưởng tuyệt vời, tôi đã suy nghĩ về việc thử phương pháp thứ nhất, nhưng bạn có thể đưa ra ý tưởng thứ hai một chút không. Tôi nghĩ rằng tôi đã cố gắng làm một cái gì đó như thế này bằng cách sử dụng get_blog_option('1','sidebars_widgets');để có được một danh sách các widget nhưng dù sao tôi cũng không thể tìm thấy để xử lý dữ liệu thành một thanh bên.
Timothy Wallis

Tôi nghĩ rằng nó sẽ gặp nhiều rắc rối hơn đáng để gắn bó với cơ sở hạ tầng widget thực tế của WP. Thay vào đó, trừu tượng đánh dấu widget / PHP thành một hàm riêng biệt, sau đó bạn sẽ gọi trực tiếp trong một tệp mẫu (hoặc móc vào một hành động thích hợp).
Hẻm núi Boone

2

Chạy vào cùng một vấn đề và tìm ra giải pháp. Những gì tôi đang làm là như sau:

1.) Bất cứ khi nào một cái gì đó được thay đổi trên thanh bên của blog 1, hãy lưu một mảng các vật dụng đó và các cài đặt của chúng dưới dạng tạm thời, sẽ hết hạn sau 24 giờ.

2.) Trên tất cả các blog con, hãy đặt một số mã vào sidebar.php để lấy trạng thái tạm thời này và hiển thị các widget.

Nghe có vẻ khá dễ, nhưng rất khó để tìm ra được và vẫn chưa hoàn hảo.

Hãy đi sâu vào một số Mã:

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

Điều này thuộc về các chức năng của blog 1 (hoặc tốt hơn là một plugin hoàn toàn) và lưu các widget vào tạm thời sau mỗi 24 giờ.

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

Điều này cũng thuộc về hàm.php của blog 1 và gia hạn tạm thời mỗi khi các widget được cập nhật.

Và cuối cùng cho các blog khác thả vào 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();
}

Hy vọng, điều này có thể giúp ai đó ra ngoài. Nếu ai có bất kỳ cải tiến nào, họ sẽ rất hoan nghênh.


1

Đảm bảo rằng bạn có mã đăng ký sidebars chính xác giống nhau đang chạy trên cả hai trang web trong widget_init. Điều đó sẽ tạo ra $ wp_registered_sidebars và giải quyết vấn đề mà Boone nêu bật. Không thử bản thân mình.


0

Điều này 'có thể' chỉ cho bạn đi đúng hướng.

Xtreme One - Khung chủ đề - http://marketpress.com/product/xtreme/

Kiểm tra video - http://vimeo.com/52479425

Khái niệm cơ bản là khi thêm một thanh bên vào một trang web mạng, bạn cũng có thể chỉ định nó như một thanh bên toàn cầu.


Thú vị, tôi tự hỏi làm thế nào anh ấy làm điều đó. Có lẽ đã sửa đổi widget_update_callback để kiểm tra và xem nếu nó toàn cầu và sau đó thực hiện một truy vấn để thêm nó vào tất cả các blog con của trang web hiện tại.
Timothy Wallis

-1

Bạn đang sử dụng global $switched;?

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

Toàn $switchedcầu được gọi từ bên trong switch_to_blog(). Bạn không cần phải khai báo nó trong không gian tên toàn cầu.
Hẻm núi Boone

Tốt để biết. Tôi đang sử dụng một phương pháp WPMU lỗi thời. Vì vậy, nó chỉ là sidebars bạn không thể truy cập? Thực đơn thì sao?
Developdaly

Tôi sẽ cần phải kiểm tra nó, nhưng tôi đoán rằng các menu có thể hoạt động trong switch_to_blog()ngữ cảnh, vì chúng không cần phải được đăng ký theo chủ đề trước khi được gọi (dữ liệu đăng ký được lưu trữ trong cơ sở dữ liệu).
Hẻm núi Boone

Tôi có thể xác nhận rằng các menu hoạt động. Xem kết quả của việc sử dụng is_active_sidebar($sidebar_name)là gì.
Developdaly
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.