phpwordpresscustom-wordpress-pages

Custom search form for taxonomy and title


I've created an archive page for my custom post type Researchers and I am wanting to be able to filter them by their organization and the post title. I'm able to get the organization search no without any problems, but I'm not sure where I'm going wrong with the post title search.

functions.php

/**
 * Create Custom Query Vars
 * https://codex.wordpress.org/Function_Reference/get_query_var#Custom_Query_Vars
 */
function add_query_vars_filter($vars)
{
  // add custom query vars that will be public
  // https://codex.wordpress.org/WordPress_Query_Vars
  $vars[] .= "organization";
  $vars[] .= "r_name";
  return $vars;
}
add_filter("query_vars", "add_query_vars_filter");

/**
 * Override researcher Archive Query
 * https://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts
 */
function researcher_archive($query)
{
  // only run this query if we're on the researcher archive page and not on the admin side
  if (
    $query->is_archive("researcher") &&
    $query->is_main_query() &&
    !is_admin()
  ) {
    // get query vars from url.
    // https://codex.wordpress.org/Function_Reference/get_query_var#Examples

    // example.com/researcher/?rating=4
    $category = get_query_var("organization", false);
    $name = get_query_var("r_name", false);

    // used to conditionally build the meta_query
    // the meta_query is used for searching against custom fields
    $meta_query_array = ["relation" => "AND"];

    $name
      ? array_push($meta_query_array, [
        "key" => "post_title",
        "value" => '"' . $name . '"',
        "compare" => "LIKE",
      ])
      : null;
    // final meta_query
    $query->set("meta_query", $meta_query_array);

    // used to conditionally build the tax_query
    // the tax_query is used for a custom taxonomy assigned to the post type
    // i'm using the `'relation' => 'OR'` to make the search more broad
    $tax_query_array = ["relation" => "OR"];

    // conditionally add arrays to the tax_query based on values in the URL
    // `organization` is the name of my custom taxonomy
    $category
      ? array_push($tax_query_array, [
        "taxonomy" => "organization",
        "field" => "term_id",
        "terms" => $category,
      ])
      : null;

    // final tax_query
    $query->set("tax_query", $tax_query_array);
    $query->set('posts_per_page', 12);
    $query->set('orderby', 'wpse_last_word');
    $query->set('order', 'ASC');
  }
}
add_action("pre_get_posts", "researcher_archive");

archive-researcher.php

<?php
/**
 * Template Name: Researcher Archive
 * Description: Custom template for displaying a list of researchers.
 */

get_header(); ?>

<div id="primary" class="content-area">
    <main id="main" class="site-main">
        <section>

            <div class="container">
                <h1>Researchers</h1>
                <form method="GET" action="<?php echo get_post_type_archive_link("researcher"); ?>">
                    <!-- gather data to use in form fields  -->
                    <?php
                        $categories = get_terms([
                        "taxonomy" => "organization",
                        "hide_empty" => false,
                        ]);
                    ?>
                    <div>
                        <input type="text" name="r_name" id="r_name" placeholder="Search"
                            value="<?php echo get_query_var("r_name", false); ?>">
                    </div>
                    <div>
                        <select name="organization" id="organization">
                            <option value="">Select a Organization</option>
                            <?php foreach ($categories as $category): ?>

                            <option id="<?php echo $category->name; ?>" value="<?php echo $category->slug; ?>"
                                <?php echo get_the_ID() == get_query_var("organization", false) ? "selected" : null; ?>>
                                <?php echo $category->name; ?>
                            </option>
                            <?php endforeach; ?>
                        </select>
                    </div>
                    <div>
                        <button>Search</button>
                        <a href="<?php echo get_post_type_archive_link("researcher"); ?>">Reset</a>
                    </div>
                </form>
                <div class="row">
                    <?php while (have_posts()): the_post(); ?>
                    <div class="col-12 col-lg-4 d-flex">
                        <?php get_template_part('template/card', 'researcher'); ?>
                    </div>
                    <?php endwhile; ?>
                </div>

                <?php the_posts_pagination(); ?>

            </div>
        </section>

    </main>
</div>

<?php get_footer(); ?>

Solution

  • You need to modify your researcher_archive function to include a search parameter for the post title using the "s" parameter.

    Here's the modified researcher_archive function:

    function researcher_archive($query)
    {
    if (
        $query->is_archive("researcher") &&
        $query->is_main_query() &&
        !is_admin()
      ) {
    $category = get_query_var("organization", false);
    $name = get_query_var("r_name", false);
    
    $meta_query_array = ["relation" => "AND"];
    
    // Remove the meta_query for post title search
    
    $tax_query_array = ["relation" => "OR"];
    
    $category
      ? array_push($tax_query_array, [
        "taxonomy" => "organization",
        "field" => "term_id",
        "terms" => $category,
      ])
      : null;
    
    $query->set("tax_query", $tax_query_array);
    
    // Add search parameter for post title
    if ($name) {
      $query->set("s", $name);
    }
    
    $query->set('posts_per_page', 12);
    $query->set('orderby', 'title'); // Change orderby to title
    $query->set('order', 'ASC');
     }
    }
    add_action("pre_get_posts", "researcher_archive");
    

    With these adjustments, the search should now include filtering by organization and searching by post title.