WordPress Multisite - categorías globales

21

Configuración de una instancia multisitio de WP: el cliente tiene una ontología / conjunto de categorías existente que desea clasificar todo el contenido en el conjunto de blogs. Además, el deseo es que cualquier categoría nueva se agregue a nivel de 'blog de red' y se sincronice con los otros blogs.

¿Cuál es la mejor manera de hacer esto?

anu
fuente
Supongo que hacer categorías asignadas a una variable global y luego importar en el tema init.
Kaiser
44
Creo que esta pregunta es la misma que Compartir una taxonomía en varios blogs en 3.0 . Sin embargo, esa pregunta no obtuvo una buena respuesta. Es una pregunta interesante, ofreceré una recompensa por ello.
Jan Fabry

Respuestas:

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

Esto se ejecutará siempre que se agregue una categoría en el sitio principal. Algunas advertencias / puntos que vale la pena mencionar;

  • Si tiene muchos blogs, esta función puede ser bastante intensa.
  • En promedio, estamos ejecutando entre 5 y 8 consultas (posiblemente más) por blog ; dependiendo de la velocidad de su base de datos, es posible que esta función deba fragmentarse.
  • Solo las categorías recién agregadas se 'sincronizan'. Las categorías de actualización y eliminación no son (el código deberá ser revisado).
  • Si una categoría recién agregada tiene un padre, y el padre no se puede encontrar en el blog multisitio en cuestión, la categoría se creará sin padre (este solo debería ser el caso si la categoría padre se creó antes de instalar esta función).
TheDeadMedic
fuente
1
¿Existe, o podría haber, un complemento que haga esto? Junto con ediciones y eliminaciones? ¿Y una página de configuración para elegir qué taxonomías y qué sitios secundarios aplicar?
Marcus Downing
De hecho, ¿se opondría si usara su código como punto de partida para escribir un complemento?
Marcus Downing
No hay problema en absoluto - mis respuestas caen bajo la licencia de cambio de pila, el cc-wiki con la atribución requiere :)
TheDeadMedic
11

Oh, la procrastinación del domingo ...

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

  • Permite agregar términos de forma masiva a través de la red
  • Puede seleccionar qué sitios se verán afectados
  • Funciona con taxonomías personalizadas.
  • No elimina
  • No se sincroniza

Esto es algo que he hecho en las últimas horas y no tengo tiempo para más pruebas ahora. De todos modos, ¡funciona para mí! .)

Darle una oportunidad. También se implementó una función de 'prueba de funcionamiento' para que pueda verificar el resultado antes de hacer algo.

Actualización -> Capturas de pantalla:

Antes de la acción:

Antes de la acción

Después de la prueba de funcionamiento:

Después de la prueba de funcionamiento

El complemento vinculado anteriormente agrega la interfaz de usuario, pero casi todo lo importante sucede en esta función:

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

Volveré y editaré esto con más información más tarde (si es necesario).

Está lejos de ser perfecto (lea los problemas conocidos en el encabezado del complemento).
Cualquier comentario apreciado!

Michal Mau
fuente
3
¡Me gusta cuando la gente crea complementos en respuesta a preguntas! Te mereces la recompensa!
Jan Fabry
Gracias por su apoyo @ Jan Fabry. Seré feliz si alguien a mi lado realmente encuentra esto útil.
Michal Mau
5

La respuesta de TheDeadMedic se ve bien, pero terminé tomando un enfoque diferente al problema. En lugar de duplicar los mismos términos en los muchos sitios, hice que los otros sitios usaran las tablas del sitio de inicio para los términos.

add_action('init', 'central_taxonomies');

function central_taxonomies () {
  global $wpdb;

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

Esto reemplaza el nombre de la tabla wp_2_termscon wp_terms, etc. Por supuesto, debe verificar en su base de datos para asegurarse del nombre exacto de las tablas, que podría ser diferente si cambia su prefijo.

Puede ejecutar esto desde un complemento o un tema (aunque recomiendo un complemento). Puedo llegar a publicar un complemento para hacer esto en algún momento. Hay dos desventajas en este enfoque:

  • Solo está activo en sitios secundarios que tienen el complemento activado. No hay forma de hacer cumplir esto desde el sitio principal.
  • Se aplica a todas las taxonomías, no solo a las seleccionadas.

Este enfoque es flexible: se puede adaptar para extraer categorías de cualquier blog, no solo el central.


Actualización: he convertido esto en un complemento, que puede activarse en todo el sitio si lo necesita: MU Central Taxonomies

Marcus Downing
fuente
Hay un gran problema con este enfoque: las relaciones entre publicaciones y términos pueden no ser correctas. La tabla term_relationships contiene esta relación basada en ID de publicación e ID de término. Pero siempre existe la posibilidad de que las publicaciones en subsitios tengan la misma ID. Cambiar los términos para 1 publicación puede afectar impredeciblemente a otra publicación en otro blog.
Anh Tran
Correcto, la term_relationshipstabla no debe incluirse. Lo descubrí y lo arreglé hace mucho tiempo en el complemento, pero nunca actualicé esta respuesta para que coincida.
Marcus Downing