Multisite WordPress - categorias globais


21

Configurando uma instância multisite do WP - o cliente possui uma ontologia / conjunto de categorias existente que deseja classificar todo o conteúdo no conjunto de blogs. Também o desejo é que quaisquer novas categorias sejam adicionadas no nível do 'blog da rede' e sincronizadas com os outros blogs.

Qual é a melhor maneira de fazer isso?


Eu acho que fazer categorias atribuídas a uma variável global e depois importar no tema init.
kaiser

4
Penso que esta pergunta é a mesma que Compartilhar uma taxonomia em vários blogs no 3.0 . Essa pergunta não obteve uma boa resposta no entanto. É uma pergunta interessante, vou oferecer uma recompensa por isso.
Jan Fabry 27/05

Respostas:


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

Isso será executado sempre que uma categoria for adicionada no site principal. Algumas advertências / pontos que vale a pena mencionar;

  • Se você possui muitos blogs, essa função pode ficar bastante intensa.
  • Em média, estamos executando de 5 a 8 consultas (possivelmente mais) por blog - dependendo da velocidade do seu banco de dados, talvez seja necessário dividir esta função.
  • Somente categorias recém-adicionadas são 'sincronizadas'. As categorias de atualização e exclusão não são (o código precisará ser revisado).
  • Se uma categoria recém-adicionada tiver um pai, e o pai não puder ser encontrado no blog de vários sites em questão, a categoria será criada sem pai (esse deve ser o caso apenas se a categoria pai tiver sido criada antes da instalação dessa função).

1
Existe - ou poderia haver - um plugin que faz isso? Juntamente com edições e exclusões? E uma página de configurações para escolher em quais taxonomias e em quais sites filhos aplicar?
Marcus Downing

Na verdade, você se oporia se eu usasse seu código como ponto de partida para escrever um plugin?
Marcus Downing

Nenhum problema - minhas respostas caem sob licença da troca de pilha, o cc-wiki com a atribuição necessário :)
TheDeadMedic

11

Ah, procrastinação de domingo ...

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

  • Permite adicionar termos em massa na rede
  • Você pode selecionar quais sites serão afetados
  • Funciona com taxonomias personalizadas
  • Não exclui
  • Não sincroniza

Isso é algo que eu fiz nas últimas horas e não tenho tempo para mais testes agora. Enfim - funciona para mim! .)

De uma chance. Há também um recurso de 'execução de teste' implementado para que você possa verificar o resultado antes de fazer alguma coisa.

Atualização -> Capturas de tela:

Antes da ação:

Antes da ação

Após a execução do teste:

Após a execução do teste

O plug-in vinculado acima adiciona interface do usuário, mas praticamente tudo o que acontece de importante nesta função:

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

Voltarei e editarei isso com mais informações mais tarde (se necessário).

Está longe de ser perfeito (leia os problemas conhecidos no cabeçalho do plug-in).
Qualquer feedback apreciado!


3
Gosto quando as pessoas criam plugins em resposta a perguntas! Você merece a recompensa!
Jan Fabry

Obrigado pelo seu apoio, @Jan Fabry. Ficarei feliz se alguém ao meu lado achar essa coisa útil.
Michal Mau


5

A resposta do TheDeadMedic parece boa, mas acabei adotando uma abordagem diferente para o problema. Em vez de duplicar os mesmos termos nos vários sites, fiz com que os outros sites usassem as tabelas do site inicial para termos.

add_action('init', 'central_taxonomies');

function central_taxonomies () {
  global $wpdb;

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

Isso substitui o nome da tabela wp_2_termspor wp_termsetc. Você deve verificar seu banco de dados para garantir o nome exato das tabelas, que pode ser diferente se você alterar seu prefixo.

Você pode executar isso a partir de um plug-in ou de um tema (embora eu recomende um plug-in). Eu posso começar a publicar um plugin para fazer isso em algum momento. Existem duas desvantagens nessa abordagem:

  • Só está ativo em sites filhos que têm o plug-in ativado. Não há como aplicar isso no site pai.
  • Aplica-se a todas as taxonomias, não apenas às selecionadas.

Essa abordagem é flexível - pode ser adaptada para extrair categorias de qualquer blog, não apenas o central.


Atualização: transformei isso em um plug-in, que pode ser ativado em todo o site, se você precisar: Taxonomias centrais da MU


Há um grande problema com essa abordagem: as relações entre postagens e termos podem não estar corretas. A tabela term_relationships contém essa relação com base no ID da postagem e no ID do termo. Mas sempre há chances de que as postagens nos subsites tenham o mesmo ID. Alterar os termos de uma postagem pode afetar imprevisivelmente em outra postagem em outro blog.
Anh Tran

Correto, a term_relationshipstabela não deve ser incluída. Vi e corrigi isso há muito tempo no plug-in, mas nunca atualizei esta resposta para corresponder.
Marcus Downing

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.