web-dev-qa-db-fra.com

Voulez-vous rediriger si la requête de recherche correspond au titre exact d'un message?

J'utilise WordPress 3.3.1 et nouvelle pour ce système. Je souhaite rediriger la requête de recherche vers la publication si celle-ci correspond exactement au titre de la publication. Je veux aussi qu'il s'exécute avant toute fonction de recherche, les points d'ancrage ou les filtres. J'ai apporté quelques modifications à query.php dans le dossier include

$search .= "{$searchand}(($wpdb->posts.post_title LIKE '{$n}{$term}{$n}'))";

et a écrit une fonction de plugin comme ceci:

add_action('template_redirect', 'single_result');
function single_result() {
    if (is_search()) {
        global $wp_query;
        if ($wp_query->post_count == 1) {
            wp_redirect( get_permalink( $wp_query->posts['0']->ID ) );
        }
    }
}

J'ai aussi quelques fonctions qui doivent être exécutées juste après cette requête de recherche et qui ont des hooks "get_header". Jusqu'à présent, la requête de recherche et la redirection ne correspondent pas et ne sont pas renvoyées sous forme d'aspect. La plupart du temps, il disparaît et ne redirige pas parfaitement. Je veux que la recherche et la redirection soient très parfaites. Toute aide sera très appréciée et reconnaissante. Je vous remercie.

3
Mauriya

Tout d’abord, ne piratez pas les fichiers de base (sauf si vous avez l’intention de soumettre un correctif :)).

Deuxièmement, ce que vous faites ne vérifie pas vraiment si le titre correspond exactement à la chaîne de recherche. Qu'est-ce que vous faites le vérifier pour voir s'il n'y a qu'un seul résultat. Cela ne signifie pas que le titre correspond. Annuler le piratage de base, puis procédez comme suit:

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

Ce est sensible à la casse. Si vous ne voulez pas que vous utilisiez strtolower en apportant cette modification à la ligne 6:

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

En outre, cette requête s'exécute après la recherche WordPress, ce qui ne correspond pas à ce que l'OP a demandé. Cependant, il est nécessaire d’exécuteraquery, il est donc logique d’utiliser la requête par défaut.

@Rarst note ci-dessous dans les commentaires qu'il ne s'agit pas d'une solution totalement fiable. Je crois que cela est vrai, mais je ne sais pas à quel point cela importera dans la pratique. Voici, cependant, une option qui devrait être fiable, mais ajoute une requête à la page de recherche.

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

Comme ci-dessus, ceci est sensible à la casse.


2
s_ha_dum