WordPress Multisite - kategori global

21

Menyiapkan contoh multisite WP - klien memiliki ontologi / set kategori yang ada yang ingin mereka klasifikasikan semua konten di seluruh set blog. Juga keinginan adalah bahwa setiap kategori baru akan ditambahkan di tingkat 'blog jaringan' dan disinkronkan ke blog lain.

Apa cara terbaik untuk melakukan ini?

anu
sumber
Saya kira membuat kategori yang ditugaskan ke variabel global dan kemudian mengimpor pada tema init.
kaiser
4
Saya pikir pertanyaan ini sama dengan Bagikan satu taksonomi di banyak blog di 3.0 . Namun pertanyaan itu tidak mendapatkan jawaban yang baik. Ini adalah pertanyaan yang menarik, saya akan menawarkan hadiah untuk itu.
Jan Fabry

Jawaban:

14
function __add_global_categories( $term_id )
{
    if ( get_current_blog_id() !== BLOG_ID_CURRENT_SITE || ( !$term = get_term( $term_id, 'category' ) ) )
        return $term_id; // bail

    if ( !$term->parent || ( !$parent = get_term( $term->parent, 'category' ) ) )
        $parent = null;

    global $wpdb;

    $blogs = $wpdb->get_col( "SELECT blog_id FROM {$wpdb->blogs} WHERE site_id = '{$wpdb->siteid}'" );
    foreach ( $blogs as $blog ) {
        $wpdb->set_blog_id( $blog );

        if ( $parent && ( $_parent = get_term_by( 'slug', $parent->slug, 'category' ) ) )
            $_parent_ID = $_parent->term_id;
        else
            $_parent_ID = 0;

        wp_insert_term( $term->name, 'category',  array(
            'slug' => $term->slug,
            'parent' => $_parent_ID,
            'description' => $term->description
        ));
    }

    $wpdb->set_blog_id( BLOG_ID_CURRENT_SITE );
}
add_action( 'created_category', '__add_global_categories' );

Ini akan berjalan setiap kali kategori ditambahkan di situs utama. Beberapa peringatan / poin yang layak disebut;

  • Jika Anda memiliki banyak blog, fungsi ini mungkin cukup intensif.
  • Rata-rata, kami menjalankan antara 5 hingga 8 kueri (mungkin lebih) per blog - tergantung pada kecepatan basis data Anda, fungsi ini mungkin harus dipotong.
  • Hanya kategori yang baru ditambahkan yang 'disinkronkan'. Memperbarui dan menghapus kategori tidak (kode perlu direvisi).
  • Jika kategori yang baru ditambahkan memiliki orang tua, dan orang tua tidak dapat ditemukan dalam blog multisite yang dimaksud, kategori tersebut akan dibuat tanpa orangtua (ini seharusnya hanya menjadi kasus jika kategori induk dibuat sebelum fungsi ini dipasang).
TheDeadMedic
sumber
1
Apakah ada - atau mungkinkah ada - plugin yang melakukan ini? Seiring dengan pengeditan dan penghapusan? Dan halaman pengaturan untuk memilih taksonomi mana dan situs anak mana untuk menerapkannya?
Marcus Downing
Bahkan, akankah Anda keberatan jika saya menggunakan kode Anda sebagai titik awal untuk menulis sebuah plugin?
Marcus Downing
Tidak masalah apa pun - jawaban saya berada di bawah lisensi pertukaran tumpukan, cc-wiki dengan atribusi diperlukan :)
TheDeadMedic
11

Oh, penundaan hari Minggu ...

https://github.com/maugly/Network-Terminator

  • Memungkinkan untuk menambahkan istilah secara massal di seluruh jaringan
  • Anda dapat memilih situs apa yang akan terpengaruh
  • Bekerja dengan taksonomi khusus
  • Tidak terhapus
  • Tidak disinkronkan

Ini adalah sesuatu yang telah saya lakukan dalam beberapa jam terakhir dan saya tidak punya waktu untuk pengujian lebih lanjut sekarang. Bagaimanapun - itu bekerja untuk saya! .)

Cobalah. Ada juga fitur 'uji coba' yang diterapkan sehingga Anda dapat memeriksa hasilnya sebelum benar-benar melakukan sesuatu.

Perbarui -> Screenshot:

Sebelum tindakan:

Sebelum bertindak

Setelah uji coba:

Setelah uji coba

Plugin yang ditautkan di atas menambahkan antarmuka pengguna tetapi hampir semua hal penting terjadi dalam fungsi ini:

        <?php function mau_add_network_terms($terms_to_add, $siteids, $testrun = false) {

        // check if this is multisite install
        if ( !is_multisite() )
            return 'This is not a multisite WordPress installation.';

        // very basic input check
        if ( empty($terms_to_add) || empty($siteids) || !is_array($terms_to_add) || !is_array($siteids) )
            return 'Nah, I eat only arrays!';

        if ($testrun) $log = '<p><em>No need to get excited. This is just a test run.</em></p>';
        else $log = '';

        // loop thru blogs
        foreach ($siteids as $blog_id) :

            switch_to_blog( absint($blog_id) );

            $log .= '<h4>'.get_blog_details(  $blog_id  )->blogname.':</h4>';
            $log .= '<ul id="ntlog">';

            // loop thru taxonomies
            foreach ( $terms_to_add as $taxonomy => $terms ) {

                // check if taxonomy exists
                if ( taxonomy_exists($taxonomy) ) {
                    // get taxonomy name
                    $tax_name = get_taxonomy($taxonomy);
                    $tax_name = $tax_name->labels->name;

                    //loop thru terms   
                    foreach ( $terms as $term ) {

                        // check if term exists
                        if ( term_exists($term, $taxonomy) ) {
                            $log .= "<li class='notice' ><em>$term already exists in the $tax_name taxonomy - not added!</em></li>";

                        } else {

                            // if it doesn't exist insert the $term to $taxonomy
                            $term = strip_tags($term);
                            $taxonomy = strip_tags($taxonomy);
                            if (!$testrun)
                                wp_insert_term( $term, $taxonomy );
                            $log .= "<li><b>$term</b> successfully added to the <b>$tax_name</b> taxonomy</li>"; 
                        }
                    }
                } else {
                    // tell our log that taxonomy doesn't exists
                    $log .= "<li class='notice'><em>The $tax_name taxonomy doesn't exist! Skipping...</em></li>"; 
                }
            }

            $log .= '</ul>';    

            // we're done here
            restore_current_blog();

        endforeach;
        if ($testrun) $log .= '<p><em>No need to get excited. This was just the test run.</em></p>';
        return $log;
    } ?>

Saya akan kembali dan mengedit ini dengan info lebih lanjut nanti (jika perlu).

Ini jauh dari sempurna (baca masalah yang diketahui di kepala plugin).
Setiap umpan balik dihargai!

Michal Mau
sumber
3
Saya suka ketika orang membuat plugin dalam menanggapi pertanyaan! Anda layak mendapatkan hadiah!
Jan Fabry
Terima kasih atas dukungan Anda @ Jan Fabry. Saya akan senang jika seseorang di samping saya benar-benar akan menemukan hal ini berguna.
Michal Mau
5

Jawaban TheDeadMedic terlihat bagus, tetapi saya akhirnya mengambil pendekatan yang berbeda untuk masalah ini. Alih-alih menduplikasi istilah yang sama di banyak situs, saya malah membuat situs lain menggunakan tabel situs rumah untuk istilah.

add_action('init', 'central_taxonomies');

function central_taxonomies () {
  global $wpdb;

  $wpdb->terms = "wp_terms";
  $wpdb->term_taxonomy = "wp_term_taxonomy";
}

Ini menggantikan nama tabel wp_2_termsdengan wp_terms, dll. Anda tentu saja harus memeriksa database Anda untuk memastikan nama tabel yang tepat, yang mungkin berbeda jika Anda mengubah awalan Anda.

Anda dapat menjalankan ini dari plugin atau tema (meskipun saya sarankan plugin). Saya mungkin mendapatkan putaran untuk menerbitkan plugin untuk melakukan ini di beberapa titik. Ada dua kelemahan dari pendekatan ini:

  • Ini hanya aktif di situs anak-anak yang pluginnya diaktifkan. Tidak ada cara untuk menegakkan ini dari situs induk.
  • Ini berlaku untuk semua taksonomi, bukan hanya yang terpilih.

Pendekatan ini fleksibel - dapat diadaptasi untuk menarik kategori dari blog mana pun, bukan hanya yang utama.


Pembaruan: Saya telah menjadikan ini sebagai plugin, yang dapat diaktifkan di seluruh situs jika Anda membutuhkannya: MU Central Taxonomies

Marcus Downing
sumber
Ada masalah besar dengan pendekatan ini: Hubungan antara posting dan istilah mungkin tidak benar. Tabel term_relationships berisi relasi ini berdasarkan ID pos dan ID istilah. Tetapi selalu ada kemungkinan bahwa posting dalam subsitus memiliki ID yang sama. Mengubah istilah untuk 1 posting mungkin berdampak tidak terduga pada posting lain di blog lain.
Anh Tran
Benar, term_relationshipstabel tidak harus disertakan. Saya melihat dan memperbaikinya sejak lama di plugin, tetapi tidak pernah memperbarui jawaban ini untuk mencocokkan.
Marcus Downing