Want to redirect if search query match exact title of any post

First, don’t hack core files (unless you intend to submit a patch 🙂 ).

Second, what you are doing isn’t really checking to see if the title exactly matches the search string. What you are doing it checking to see if there is only one result. That doesn’t mean the title matches. Undo the core hack, then do this:

function redir_title_match($a) {
  if (is_search()) {
    global $wp_query;
    $s_str = $wp_query->query_vars['s'];
    foreach ($wp_query->posts as $p) {
      if ($p->post_title == $s_str) {
        wp_safe_redirect(get_permalink($p->ID));
        exit();
      }
    }
  }
}
add_filter('template_redirect','redir_title_match');

That is case sensitive. If you don’t want that use strtolower by making this change to line 6:

if ($p->post_title == $s_str) {
=>
if (strtolower($p->post_title) == strtolower($s_str)) {

Also, this query runs after the WordPress search, which does not match what the OP requested. However, it is necessary to run a query so it makes sense to use the default query.

@Rarst notes below in the comments that this is not a completely reliable solution. I believe that to be true though I don’t know how much it would matter in practice. Here, however, is an option that should be reliable but adds a query to the search page.

function redir_rigid_title_match() {
  if (is_search()) {
    global $wp_query,$wpdb;
    $s_str = $wp_query->query_vars['s'];
    $m = $wpdb->get_var($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_title = %s",$s_str));
    if (!empty($m)) {
      wp_safe_redirect(get_permalink($m));
      exit();
    }
  }
}
add_filter('pre_get_posts','redir_rigid_title_match');

As above, this is case sensitive.


Leave a Comment