Personnaliser les permaliens avec des meta sous WordPress


Dans la série petit tuto sous WordPress, j’ai récemment eu besoin de personnaliser les permaliens de custom posts sous WordPress avec leurs meta.

Concrètement, je voulais que les urls d’un custom post de type dvd soient de la forme : nom_de_domaine/type_post/realisateur/titre_du_film

Le réalisateur étant un champ supplémentaire via les meta du post (la valeur d’un meta_key). Pour faire ceci : une fonction à mettre en place et une modification de la déclaration du custom post.

Note: réalisé sous WordPress 3.3.1

Etape 1 : Ecrire la fonction

Dans le fichier functions.php du thème, insérez le code suivant :

add_filter('post_type_link','url_dvd',1,3);
function url_dvd ( $post_link, $id = 0, $leavename = FALSE ) {

    $post = get_post($id);
    if($post->post_type != 'dvd') {
            return $post_link;
    }
  • Début de déclaration de la fonction et mise en place d’une condition pour ne réécrire que les urls du custom post « dvd »
$accent= array ("À","Á","Â","Ã","Ä","Å","à","á","â","ã","ä","å","Ò","Ó","Ô","Õ","Ö","Ø","ò","ó","ô","õ","ö","ø","È","É","Ê","Ë","é","è","ê","ë","Ç","ç","Ì","Í","Î","Ï","ì","í","î","ï","Ù","Ú","Û","Ü","ù","ú","û","ü","ÿ","Ñ","ñ","°");
$noaccent= array ("A","A","A","A","A","A","a","a","a","a","a","a","O","O","O","O","O","O","o","o","o","o","o","o","E","E","E","E","e","e","e","e","C","c","I","I","I","I","i","i","i","i","U","U","U","U","u","u","u","u","y","N","n","-");
  • Déclaration de deux array pour réécrire les accents et caractères spéciaux qui peuvent être contenus dans les valeurs du meta_key.
        $realisateur = get_post_meta($post->ID,'realisateur ',true);
	$realisateur = str_replace (' ','-',$realisateur);
	$realisateur = str_replace ('\'','-',$realisateur);
	$realisateur = str_replace ($accent, $noaccent, $realisateur);
	$realisateur = strtolower($realisateur );
  • Récupération de la valeur de la meta_key « realisateur » du post type.
  • Remplacement des espaces, apostrophes et des accents (via les deux arrays définis plus haut)
  • Mise en minuscule de la chaîne de caractères
	$str = $post_link;
        $str = str_replace('%nom_realisateur%',$realisateur, $str);

    return $str;
}
add_rewrite_tag('%nom_realisateur%','([^&]+)');
  • Récupération du lien du post
  • Injection de la variable realisateur dans la construction de l’url
  • Ajout de la fonction WordPress add_rewrite_tag et déclaration de la nouvelle variable pour construire l’url

Etape 2 : Modifier la déclaration du custom post

Il faut modifier la déclaration du custom post pour introduire la nouvelle variable dans l’url du post. Pour cela, il est plus simple d’avoir déclaré le custom post via le fichier functions.php. Si vous ne l’avez pas fait comme ceci, voici un lien qui permet de le faire simplement : http://themergency.com/generators/wordpress-custom-post-types/

Le code initial ressemble à ceci :

add_action( 'init', 'register_cpt_dvd' );
function register_cpt_dvd() {

    $labels = array(
        'name' => _x( 'DVD', 'dvd' ),
        'singular_name' => _x( 'Dvd', 'dvd' ),
        'add_new' => _x( 'Ajouter', 'dvd' ),
        'add_new_item' => _x( 'Ajouter un nouveau dvd', 'dvd' ),
        'edit_item' => _x( 'Modifier le dvd', 'dvd' ),
        'new_item' => _x( 'Nouveau dvd', 'dvd' ),
        'view_item' => _x( 'Voir le dvd', 'dvd' ),
        'search_items' => _x( 'Rechercher des dvds', 'dvd' ),
        'not_found' => _x( 'Aucun dvd trouvé', 'dvd' ),
        'not_found_in_trash' => _x( 'Aucun dvd trouvé dans la Corbeille', 'dvd' ),
        'parent_item_colon' => _x( 'dvd parent :', 'dvd' ),
        'menu_name' => _x( 'Dvds', 'dvd' ),
    );

    $args = array(
        'labels' => $labels,
        'hierarchical' => true,
        'description' => 'Le contenu pour ajouter un dvd',
        'supports' => array( 'title', 'editor', 'excerpt', 'author', 'thumbnail', 'custom-fields', 'comments', 'revisions' ),
        'taxonomies' => array( 'genre' ),
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        'menu_position' => 5,
        'show_in_nav_menus' => true,
        'publicly_queryable' => true,
        'exclude_from_search' => false,
        'has_archive' => true,
        'query_var' => true,
        'can_export' => true,
        'rewrite' => true,
        'capability_type' => 'post'
    );

    register_post_type( 'dvd', $args );
}

Il faut modifier l’entrée rewrite pour intégrer la nouvelle variable comme ceci :

add_action( 'init', 'register_cpt_dvd' );
function register_cpt_dvd() {
....

$args = array(
'labels' => $labels,
'hierarchical' => true,
'description' => 'Le contenu pour ajouter un dvd',
'supports' => array( 'title', 'editor', 'excerpt', 'author', 'thumbnail', 'custom-fields', 'comments', 'revisions' ),
'taxonomies' => array( 'serie' ),
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 5,
'show_in_nav_menus' => true,
'publicly_queryable' => true,
'exclude_from_search' => false,
'has_archive' => true,
'query_var' => true,
'can_export' => true,
'rewrite' => array('slug' => 'dvd/%nom_realisateur%'),
'capability_type' => 'post'
);
....

Ne pas oublier à la fin :

add_action( 'init', 'register_cpt_dvd' );
function register_cpt_dvd() {
....
    'rewrite' => array('slug' => 'dvd/%nom_realisateur%'),
    'capability_type' => 'post'
    );
register_post_type( 'dvd', $args );
flush_rewrite_rules();
}

Ce qui nous donne finalement :

add_action( 'init', 'register_cpt_dvd' );
function register_cpt_dvd() {

    $labels = array(
        'name' => _x( 'DVD', 'dvd' ),
        'singular_name' => _x( 'Dvd', 'dvd' ),
        'add_new' => _x( 'Ajouter', 'dvd' ),
        'add_new_item' => _x( 'Ajouter un nouveau dvd', 'dvd' ),
        'edit_item' => _x( 'Modifier le dvd', 'dvd' ),
        'new_item' => _x( 'Nouveau dvd', 'dvd' ),
        'view_item' => _x( 'Voir le dvd', 'dvd' ),
        'search_items' => _x( 'Rechercher des dvds', 'dvd' ),
        'not_found' => _x( 'Aucun dvd trouvé', 'dvd' ),
        'not_found_in_trash' => _x( 'Aucun dvd trouvé dans la Corbeille', 'dvd' ),
        'parent_item_colon' => _x( 'dvd parent :', 'dvd' ),
        'menu_name' => _x( 'Dvds', 'dvd' ),
    );

    $args = array(
        'labels' => $labels,
        'hierarchical' => true,
        'description' => 'Le contenu pour ajouter un dvd',
        'supports' => array( 'title', 'editor', 'excerpt', 'author', 'thumbnail', 'custom-fields', 'comments', 'revisions' ),
        'taxonomies' => array( 'genre' ),
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        'menu_position' => 5,
        'show_in_nav_menus' => true,
        'publicly_queryable' => true,
        'exclude_from_search' => false,
        'has_archive' => true,
        'query_var' => true,
        'can_export' => true,
        'rewrite' => array('slug' => 'dvd/%nom_realisateur%'),
        'capability_type' => 'post'
    );

    register_post_type( 'dvd', $args );
    flush_rewrite_rules();
}

Voilà vous avez la méthode pour personnaliser vos urls avec les valeurs dynamiques de vos posts !

Les valeurs peuvent être cumulées en ajoutant les déclaration de variables dans la fonction function url_dvd et dans l’array de rewrite du custom post.

Plus d’informations sur les fonctions : add_rewrite_tag et register_post_type