WordPress Multisite - kategorie globalne

21

Konfigurowanie instancji WP dla wielu witryn - klient ma istniejącą ontologię / zestaw kategorii, w których chce klasyfikować całą zawartość w zestawie blogów. Chodzi również o to, aby wszelkie nowe kategorie były dodawane na poziomie „bloga sieciowego” i synchronizowane z innymi blogami.

Jak najlepiej to zrobić?

anu
źródło
Chyba tworzenie kategorii przypisanych do zmiennej globalnej, a następnie importowanie przy inicjowaniu kompozycji.
kaiser
4
Myślę, że to pytanie jest takie samo jak Udostępnij jedną taksonomię na wielu blogach w 3.0 . To pytanie nie uzyskało jednak dobrej odpowiedzi. To interesujące pytanie, dam za to nagrodę.
Jan Fabry

Odpowiedzi:

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

Będzie działać za każdym razem, gdy kategoria zostanie dodana na stronie głównej. Kilka ostrzeżeń / punktów, o których warto wspomnieć;

  • Jeśli masz dużo blogów, ta funkcja może stać się bardzo intensywna.
  • Średnio uruchamiamy od 5 do 8 zapytań (prawdopodobnie więcej) na blogu - w zależności od szybkości bazy danych ta funkcja może wymagać podzielenia na fragmenty.
  • Tylko nowo dodane kategorie są „synchronizowane”. Aktualizowanie i usuwanie kategorii nie są (kod będzie wymagał aktualizacji).
  • Jeśli nowo dodana kategoria ma element nadrzędny, a elementu nadrzędnego nie można znaleźć w blogu o wielu witrynach, kategoria zostanie utworzona bez elementu nadrzędnego (powinno tak być tylko w przypadku, gdy kategoria nadrzędna została utworzona przed zainstalowaniem tej funkcji).
TheDeadMedic
źródło
1
Czy istnieje lub może istnieć wtyczka, która to robi? Wraz z edycjami i usunięciami? I strona ustawień, aby wybrać, które taksonomie i które strony potomne zastosować?
Marcus Downing,
Czy sprzeciwiłbyś się, gdybym użył twojego kodu jako punktu wyjścia do napisania wtyczki?
Marcus Downing,
Nie ma problemu - moje odpowiedzi są objęte licencją wymiany stosów, wymagana jest licencja cc-wiki :)
TheDeadMedic
11

Och, niedzielne zwlekanie ...

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

  • Umożliwia zbiorcze dodawanie warunków w sieci
  • Możesz wybrać strony, których to dotyczy
  • Współpracuje z niestandardowymi systematykami
  • Nie usuwa
  • Nie synchronizuje się

Zrobiłem to w ciągu ostatnich kilku godzin i nie mam teraz czasu na więcej testów. W każdym razie - działa dla mnie! .)

Spróbuj. Zaimplementowano również funkcję „uruchomienia testowego”, dzięki czemu można sprawdzić wynik przed faktycznym zrobieniem czegoś.

Aktualizacja -> Zrzuty ekranu:

Przed działaniem:

Przed działaniem

Po uruchomieniu testowym:

Po uruchomieniu testowym

Powyższa wtyczka dodaje interfejs użytkownika, ale prawie wszystko, co ważne, dzieje się w tej funkcji:

        <?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;
    } ?>

Wrócę i edytuję to z dodatkowymi informacjami później (w razie potrzeby).

Jest daleki od ideału (przeczytaj znane problemy w główce wtyczki).
Dziękujemy za wszelkie opinie!

Michał Mau
źródło
3
Podoba mi się, gdy ludzie tworzą wtyczki w odpowiedzi na pytania! Zasługujesz na nagrodę!
Jan Fabry
Dzięki za wsparcie @Jan Fabry. Będę szczęśliwy, jeśli ktoś obok mnie uzna tę rzecz za przydatną.
Michał Mau
5

Odpowiedź TheDeadMedic wygląda dobrze, ale skończyłem na innym podejściu do problemu. Zamiast powielać te same warunki w wielu witrynach, zamiast tego zmusiłem inne witryny do używania terminów w tabelach strony głównej.

add_action('init', 'central_taxonomies');

function central_taxonomies () {
  global $wpdb;

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

Zastępuje nazwę tabeli wp_2_termsz wp_termsitp Należy czeku oczywiście w swojej bazie danych, aby upewnić się co do dokładnej nazwy tabel, które mogą być różne, jeśli zmienisz prefiks.

Możesz uruchomić to z wtyczki lub motywu (chociaż polecam wtyczkę). W pewnym momencie mogę zacząć publikować wtyczkę. Istnieją dwie wady tego podejścia:

  • Jest aktywny tylko w witrynach podrzędnych, które mają aktywowaną wtyczkę. Nie można tego wymusić z witryny nadrzędnej.
  • Dotyczy to wszystkich taksonomii, nie tylko wybranych.

To podejście jest elastyczne - można je dostosować do pobierania kategorii z dowolnego bloga, nie tylko centralnego.


Aktualizacja: Zrobiłem to we wtyczce, którą można aktywować w całej witrynie, jeśli jest to konieczne: MU Central Taksonomie

Marcus Downing
źródło
Z tym podejściem wiąże się duży problem: relacje między wpisami a terminami mogą być nieprawidłowe. Tabela term_relationships zawiera tę relację na podstawie identyfikatora stanowiska i identyfikatora pojęcia. Ale zawsze jest szansa, że ​​posty w podwitrynach mają ten sam identyfikator. Zmiana warunków dla 1 postu może nieprzewidywalnie wpłynąć na inny post na innym blogu.
Anh Tran,
Prawidłowo, term_relationshipstabela nie powinna być dołączona. Zauważyłem i naprawiłem to dawno temu we wtyczce, ale nigdy nie zaktualizowałem tej odpowiedzi, aby pasowała.
Marcus Downing