web-dev-qa-db-fra.com

Réécriture d'URL en fonction d'une valeur de champion personnalisé

Je travaille sur une migration d'un autre CMS vers WordPress. L'ancien site contenait de terribles URL non-SEO au format http://example.com?lid=1234.

Nous avons importé toutes les publications de l'ancien site dans WordPress et stockons la lid en tant que champ personnalisé.

Nous aimerions que les anciennes URL fonctionnent encore si possible, mais il est hors de question d'utiliser environ 3 000 publications .htaccess.

Ma question est donc la suivante: comment créer une règle de réécriture qui extrait la valeur lid de l'URL et redirige vers la publication qui la contient dans le champ personnalisé? (la valeur lid est unique, vous ne craignez donc pas plus d'une publication avec la même valeur de champ personnalisé)

Merci beaucoup Simon

4
Simon Blackbourn

voici une idée, ajoutez d'abord lid à query_vars:

add_filter('query_vars', 'lid_query_vars');
function lid_query_vars($vars) {
    // add lid to the valid list of variables
    $new_vars = array('lid');
    $vars = $new_vars + $vars;
    return $vars;
}

puis utilisez parse_request hook pour créer votre redirection

add_action('parse_request', 'lid_parse_request');
function lid_parse_request($wp) {
    // only process requests with "lid"
    if (array_key_exists('lid', $wp->query_vars) && $wp->query_vars['lid'] != '') {
        $args = array('meta_key' => 'lid', 'meta_value' => $wp->query_vars['lid']);
        $redirect_to_post = get_posts($args);
        foreach($redirect_to_post as $p){
            $link = get_permalink($p->ID);
            wp_redirect( $link , 301 ); 
            exit;
        }
    }
}
7
Bainternet

Bonjour-Simon Blackbourn:

Pendant que j'écrivais ma réponse, mais avant de pouvoir la publier, @Bainternet a également proposé une excellente réponse. Il a adopté une approche légèrement différente, mais ses œuvres tout autant que les miennes. Pourtant, comme j’avais déjà écrit le mien quand j’ai vu le sien, je vous soumettrai le mien comme solution de rechange.

Utilise Direct SQL: $post_id = $wpdb->get_var($sql)

Ma solution utilise le SQL direct, ce qui n'est souvent pas la meilleure approche, mais j'estime qu'elle est juste ici en raison de la simplicité de ce SQL (et qu'il est donc peu probable qu'elle se casse à l'avenir) et parce que vos besoins ne vous apportent aucun avantage. d'utiliser la get_posts() relativement lourde avec tous ses besoins en matière de traitement des points d'ancrage, car vos besoins sont uniques pour votre site spécifique.

Utilise les paramètres d'URL directs: $_GET['lid']

De plus, j'ai choisi d'utiliser l'accès direct à $_GET['lid'] au lieu de créer d'abord un query_var car les vars de requête font partie de l'architecture de requête WordPress standard utilisée par le système de réécriture d'URL sous-jacent, et pour votre cas d'utilisation, vous n'utilisez pas explicitement la requête WordPress. architecture. Au lieu de cela, vous devez capturer un paramètre de requête réel transmis sur l’URL. Je pense donc que la surcharge liée à l’ajout d’une requête var n'est pas vraiment nécessaire (bien que la vérité soit dite à l'aide d'une requête var ne fait pas mal, et fonctionne bien aussi.)

Utilise le crochet 'parse_request'

Enfin, j'ai bien aimé utiliser @Bainternet avec 'parse_request' hook; il fonctionne avant la requête MySQL par défaut de WordPress, de sorte que vous n'avez pas à lancer une requête MySQL que vous allez simplement jeter mais il s'exécute après le hook 'init' qui signifie (la plupart) les hooks qui permettent aux plugins de modifier les permaliens auront été ajoutés, donnant ainsi vous les bonnes URL pour vos redirections.

Placez dans functions.php

Vous pouvez placer le code suivant dans le fichier functions.php de votre thème:

add_action('parse_request','oldsite_redirect',0);  // 0=before (most) 'parse_request' calls
function oldsite_redirect() {
  if (isset($_GET['lid'])) {
    global $wpdb;
    $sql = "SELECT post_id FROM {$wpdb->postmeta} " . 
           "WHERE meta_key='lid' AND meta_value='%s'";
    $sql = $wpdb->prepare($sql,$_GET['lid']);
    $post_id = $wpdb->get_var($sql);
    if ($post_id) {
      $permalink = get_permalink($post_id);
      if ($permalink) {
        wp_safe_redirect($permalink,301);
        exit;
      }
    }
  }
}

Encore une fois, l'une ou l'autre solution fonctionnera; @ Bainternet's ou le mien; votre choix lequel utiliser.

3
MikeSchinkel