WordPress Multisite - глобальні категорії


21

Налаштування багатопрофільного примірника WP - клієнт має існуючу онтологію / набір категорій, за якими він хоче класифікувати весь вміст у наборі блогів. Також хочеться, щоб будь-які нові категорії були додані на рівні "мережевого блогу" та синхронізовані з іншими блогами.

Який найкращий спосіб зробити це?


Я здогадуюсь зробити категорії, присвоєні глобальній змінній, а потім імпортувати на тему init.
кайзер

4
Я думаю, це питання те саме, що поділитися однією систематикою в кількох блогах в 3.0 . Однак на це запитання не було хорошої відповіді. Це цікаве питання, я запропоную за це щедроту.
Ян Фабрі

Відповіді:


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

Це запускається щоразу, коли категорія додається на основному веб-сайті. Кілька застережень / пунктів, які варто згадати;

  • Якщо у вас багато блогів, ця функція може стати досить інтенсивною.
  • В середньому ми працюємо десь від 5 до 8 запитів (можливо, більше) на кожен блог - залежно від швидкості роботи вашої бази даних, цю функцію, можливо, потрібно буде налаштувати.
  • Тільки щойно додані категорії "синхронізовані". Оновлення та видалення категорій не є (код потрібно буде переглянути).
  • Якщо щойно додана категорія має батьківське, і батьків не можна знайти в блозі, про який йдеться, багато користувачів, категорія буде створена без батьківського (це має бути лише в тому випадку, якщо батьківська категорія була створена до встановлення цієї функції).

1
Чи є - або міг бути - плагін, який робить це? Поряд із правками та видаленнями? І сторінка налаштувань, щоб вибрати, до яких таксономій та до яких дочірніх сайтів застосувати його?
Маркус Даунінг

Насправді, чи заперечуєте ви, якби я використовував ваш код як вихідний пункт для написання плагіна?
Маркус Даунінг

Нічого б не було - мої відповіді підпадають під ліцензію обміну
стеками,

11

О, недільна зволікання ...

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

  • Дозволяє масово додавати терміни в мережі
  • Ви можете вибрати, які сайти будуть впливати
  • Працює з користувацькими таксономіями
  • Не видаляється
  • Не синхронізується

Це те, що я робив за останні кілька годин, і зараз у мене немає часу на тестування. У всякому разі - це працює для мене! .)

Спробувати. Також реалізована функція "пробного запуску", щоб ви могли перевірити результат, перш ніж дійсно щось робити.

Оновлення -> Скріншоти:

Перед дією:

Перед дією

Після пробного запуску:

Після запуску тесту

Плагін, пов'язаний вище, додає користувальницький інтерфейс, але майже все важливе відбувається в цій функції:

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

Я повернусь і відредагую це з додатковою інформацією пізніше (якщо потрібно).

Це далеко не ідеально (читайте відомі проблеми у головці плагіна).
Будь-який відгук вдячний!


3
Мені подобається, коли люди створюють плагіни у відповідь на запитання! Ви заслуговуєте на винагороду!
Ян Фабрі

Дякуємо за вашу підтримку @Jan Fabry Я буду радий, якщо хтось поруч зі мною дійсно знайде цю річ корисною.
Міхал Мау


5

Відповідь TheDeadMedic виглядає добре, але я врешті-решт застосував інший підхід до проблеми. Замість того, щоб дублювати одні і ті ж терміни на багатьох сайтах, я натомість змусив інші сайти використовувати таблиці домашнього сайту для термінів.

add_action('init', 'central_taxonomies');

function central_taxonomies () {
  global $wpdb;

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

Це замінює ім'я таблиці wp_2_termsна wp_termsі т. Д. Ви, звичайно, повинні перевірити у своїй базі даних, щоб переконатися в точній назві таблиць, яка може відрізнятися, якщо ви зміните свій префікс.

Ви можете запустити це або з плагіна, або з теми (хоча я рекомендую плагін). Я можу обійтись публікацією плагіна, щоб це зробити в якийсь момент. У цього підходу є два мінуси:

  • Активна лише на дочірніх сайтах, у яких активований плагін. Неможливо застосувати це з батьківського сайту.
  • Це стосується всіх таксономій, а не лише вибраних.

Цей підхід є гнучким - його можна адаптувати для витягування категорій з будь-якого блогу, а не лише з центрального.


Оновлення: я зробив це у плагін, який можна активувати на всьому сайті, якщо вам це потрібно: MU Central Taxonomies


У цьому підході є велика проблема: відносини між посадами та термінами можуть бути невірними. Таблиця term_relationships містить це відношення на основі ідентифікатора повідомлення та ідентифікатора терміна. Але завжди є ймовірність, що повідомлення в підсайтах мають однаковий ідентифікатор. Зміна умов для 1 публікації може непередбачувано вплинути на іншу публікацію в іншому блозі.
Ань Тран

Правильно, term_relationshipsтаблиця не повинна бути включена. Я давно помітив і виправив у плагіні, але ніколи не оновлював цю відповідь на відповідність.
Маркус Даунінг

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.