web-dev-qa-db-fra.com

Recherche par mot clé limitée à un type de message spécifique filtré par plusieurs taxonomies personnalisées?

Est-il possible de limiter la recherche de mots-clés à un type de publication spécifique (par exemple, "Actualités") tout en filtrant les résultats en fonction de taxonomies personnalisées sélectionnées?

  • J'ai une section de nouvelles.
  • Cela a le type de message personnalisé appelé "nouvelles".
  • Cela a alors la taxonomie personnalisée 'news-category'.
  • Plusieurs termes de taxonomie personnalisés doivent être répertoriés avec les cases à cocher correspondantes.

Imaginons par exemple que quelqu'un veuille chercher le mot clé "Wales" et vérifie les taxonomies personnalisées "Médical" et "Financier", puis affiche les résultats selon ces requêtes de recherche.

Pour résumer, ils ne font que chercher dans le type de message de presse qui est filtré par les taxonomies personnalisées et le mot clé. Est-ce possible? Si c'est le cas, comment?


METTRE À JOUR:

J'ai un modèle appelé archive-members.php avec ce qui suit, comment puis-je envelopper tout cela avec le code nécessaire pour afficher une recherche avec mot clé + catégorie, mot clé ou catégorie simplement.

<?php
/**
 * @package WordPress
 * @subpackage Default_Theme
 */

get_header();
?>

        <!-- Main Content -->

        <div class="post" id="post-<?php the_ID(); ?>">
            <div class="entry">

                <div class="left-search">
                    <div class="page-title-search">
                        <h2>Search</h2>
                        <form id="custom-search" action="<?php bloginfo('url'); ?>/" method="get">
                        <?php //Get all (non-empty) terms for taxonomy 'news-category'
                        $args = array('orderby' => 'name','order' => 'ASC');
                        $categories = get_terms( 'members', $args );
                        ?>
                        <!-- Visible input for search term -->
                        <p style="margin-bottom:5px!IMPORTANT;"><b>Keyword</b></p>
                        <input type="text" class="keyword" name="s" value="" />
                        <div class="clear"></div>

                        <p style="margin-top:20px!IMPORTANT;margin-bottom:2px!IMPORTANT;"><b>Specialisms</b></p>
                        <?php //Display checkbox for each term
                        $counter = 1;
                        foreach ($categories as $category) {
                            echo '<input type="checkbox" id="field-'.$counter.'" class="mycheckbox" name="mw-filter-terms[]" value="'.$category->slug.'">';
                            echo '<label for="field-'.$counter.'" class="mycheckbox-label">'.esc_html($category->name).'</label>';
                        $counter++; 
                        } ?>

                        <!-- Hidden input to set post type to news-->
                        <input type="hidden" name="post_type" value="members" />

                        <div class="clear"></div>
                        <!-- Submit button -->
                        <button class="blue medium awesome awesomeforward awesomesearch" type="submit">Search</button>
                        </form>                     


                    </div>
                </div>

                <div class="news-content" style="background-color:#ececec!IMPORTANT;">
                    <div class="page-title-content">
                        <h2>Members Directory</h2>
                    </div>
                    <div class="news-content-inner">
                        <div class="inner-holder">
                            <?php the_field('content', 1886); ?>
                        </div>
                    </div>
                            <a class="blue medium awesome awesomeforward" style="margin-left:193px;margin-bottom:10px;color: white !important; " href="<?php bloginfo('url'); ?>/member-signup/">Become A Member</a>                    

                <div class="news-content" style="background-color:#ececec!IMPORTANT;">
                    <div class="page-title-content">
                        <h2>Search Results</h2>
                    </div>
                    <div class="news-content-inner">
                        <?php $portfolioloop1 = new WP_Query( array( 'paged' => get_query_var('paged'), 'order' => 'ASC', 'orderby' => 'title', 'post_status' => 'publish', 'post_type' => 'members', 'posts_per_page' => 300 ) ); ?>
                        <?php while ( $portfolioloop1->have_posts() ) : $portfolioloop1->the_post(); ?>
                        <div <?php if (get_field('logo') != "") { ?>style="height:120px;"<?php } ?> class="news-item" onclick="location.href='<?php echo the_permalink(); ?>'">
                            <?php if (get_field('logo') != "") { ?>
                                <div style="height:110px;float:left;">
                                <table>
                                    <tr>
                                    <td height="110">
                                    <img style="margin-right:15px;" src="<?php echo the_field('logo'); ?>" width="150" alt="<?php echo the_title(); ?>" />
                                    </td>
                                    </tr>
                                </table>
                                </div>
                            <?php } ?>
                            <div <?php if (get_field('logo') != "") { ?>style="float:left;width:379px;"<?php } ?>>
                                <h2><a style="color:#AA3CA7!important;" href="<?php echo the_permalink(); ?>"><?php echo the_title(); ?></a></h2>
                                <p class="news-page">
                                    <?php $description = get_field('description');
                                    echo substr($description,0,300) . "..." ?>
                                </p>
                            </div>  
                        </div>
                        <?php endwhile; // end of the loop. ?>

                    </div>
                <div class="clear"></div>                   
            </div>
        </div>    

<?php get_footer(); ?>
1
Rob

C'est assez inefficace d'utiliser query_posts et je trouve souvent que c'est plus ennuyeux que ça en vaut la peine. Au lieu de cela, pour définir le type de publication, vous pouvez simplement avoir une entrée cachée dans le formulaire avec le nom 'post_type' et la valeur (dans cet exemple) 'news'. WordPress gère le reste.

Malheureusement, les taxonomies ne sont pas si faciles (j'ai peut-être raté un tour?). Cependant, plutôt que de refaire la recherche avec query_posts, vous pouvez simplement utiliser le filtre pre_get_posts qui s'exécute avant que la base de données ne soit filtrée par terme de taxonomie.

Ce qui suit suppose que votre catégorie d'actualités porte le nom 'news-category' et que votre type de message est 'news':

(Commencez par supprimer votre élément query_posts du modèle de recherche, car il remplace simplement la requête par défaut exécutée par WordPress).

Balise HTML

C'est le formulaire qui affiche votre recherche:

<form action="" method="get">
<?php
 //Get all (non-empty) terms for taxonomy 'news-category'
 $args = array('orderby' => 'name','order' => 'ASC');
 $categories = get_terms( 'news-category', $args );

 //Display checkbox for each term
 foreach ($categories as $category) {
       echo '<input type="checkbox" name="my-filter-terms[]" value="'.$category->slug.'">'.esc_html($category->name);
  }
  ?>

    <!-- Hidden input to set post type to news-->
    <input type="hidden" name="post_type" value="news" />

    <!-- Visible input for search term -->
    <input type="text" name="s" value="" />

    <!-- Submit button -->
    <input type="submit" />
 </form>

J'ai utilisé my-filter-terms pour stocker le tableau de slugs des termes vérifiés. (Il serait probablement préférable d’enregistrer une variable personnalisée, mais je vais en rester pour le moment. J’espérais pouvoir utiliser la variable de requête taxonomie par défaut, mais cela ne semblait pas fonctionner).

Filtrer la recherche

Le type de message et le terme de recherche seront automatiquement gérés. Ce qui suit est de filtrer par terme de taxonomie. Cela va dans les functions.php de votre thème:

add_filter('pre_get_posts','my_filter_the_search',10,1);
function my_filter_the_search($query){

    //If the query is a search AND taxonomy terms are set, filter by those terms:
    if($query->is_search() && isset($_GET['my-filter-terms'])){
        //Get array of slugs of checked terms
        $terms = (array) $_GET['my-filter-terms'];

        //Tax_query array
        $tax_query = array(array(
                    'taxonomy' => 'news-category',
                    'field' => 'slug',
                    'terms' => $terms,
                    'operator' => 'IN',
                )); 

        //Tell the query to filter by tax
        $query->set('tax_query', $tax_query  );
    }
    return $query;
}

L'opérateur est défini sur IN. Cela signifie qu'il recherche tous les messages dans l'un des termes cochés. Vous pouvez le définir sur AND pour rechercher les publications qui correspondent à tous les termes cochés.

3
Stephen Harris

Vous devriez pouvoir le faire en combinant les paramètres 'tax_query' et 's' d'un WP_Query. Je suppose ici que vous utilisez des paramètres d'URL pour accomplir cela, mais vous pouvez configurer les variables initiales comme vous le souhaitez.

$search_terms = isset( $_GET['s'] ) ? urldecode( $_GET['s'] ) : '';
$news_category = isset( $_GET['news_category'] ) ? urldecode( $_GET['news_category'] ) : '';


$query_args = array( 'post_type' => 'news', 'tax_query' => array() );

if ( !empty( $search_terms ) ) {
    $query_args['s'] = $search_terms;
}

if ( !empty( $search_terms ) ) {
    $query_args['tax_query'][] = array(
        array(
            'taxonomy' => 'news',
            'field' => 'slug',
            'terms' => $news_category
        )
    );
}

$my_posts = new WP_Query( $query_args );
if ( $my_posts->have_posts() ) { // etc

Plus d'informations sur les paramètres WP_Query, dans le codex wordpress.org: https://codex.wordpress.org/Class_Reference/WP_Query

1
Boone Gorges