web-dev-qa-db-fra.com

Forcer des slugs de page uniques sur tous les types de publication

J'ai un site avec de nombreux types de messages personnalisés et j'ai besoin d'un slug unique pour chaque page.

Ce que je constate, c’est que wordpress vérifie uniquement les conflits de slug dans un type de publication avant d’ajouter "-2", "-3". Donc, je peux avoir "acteur/foo", "livre/foo", "livre/foo-2". Je ne veux pas ça. Je veux que chaque foo ait sa propre limace, peu importe le type de message.

Je veux éviter d'utiliser une réécriture sur le slug et je préférerais ne pas éditer de source WP en dehors de plugins/thèmes.

Est-ce possible?

2
JLeonard

Un slug unique pour les posts est créé par wp_unique_post_slug() . En regardant la source, le slug renvoyé est filtré par wp_unique_post_slug. Nous pouvons donc remplacer cette limace générée par la nôtre.

Vous remarquerez dans la source que les pièces jointes doivent comporter des slug uniques pour tous les types. Nous allons donc utiliser le code à partir de cela.

Les exemples que vous avez donnés semblaient être non hiérarchiques - et il n'est pas clair si vous souhaitez que les slugs soient uniques pour les types de publication hiérarchiques (qui par défaut doivent uniquement être uniques dans leur arborescence). Dans l'exemple ci-dessous, j'ignore la publication hiérarchique. les types.

add_filter('wp_unique_post_slug', 'wpse72553_cross_type_unique_slugs',10,5);
function wpse72553_cross_type_unique_slugs( $slug, $post_ID, $post_status, $post_type, $post_parent ){

      global $wpdb, $wp_rewrite;

     //Don't touch hierarchical post types
     $hierarchical_post_types = get_post_types( array('hierarchical' => true) );
     if( in_array( $post_type, $hierarchical_post_types ) )
          return $slug;

     if( 'attachment' == $post_type ){
         //These will be unique anyway
         return $slug;
     }


    $feeds = $wp_rewrite->feeds;
    if ( ! is_array( $feeds ) )
         $feeds = array();


     //Lets make sure the slug is really unique:
     $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND ID != %d LIMIT 1";
     $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_ID ) );

     if ( $post_name_check || in_array( $slug, $feeds) ) {
          $suffix = 2;

          do {
              $alt_post_name = substr ($slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
              $post_name_check = $wpdb->get_var( $wpdb->prepare($check_sql, $alt_post_name, $post_ID ) );
              $suffix++;
          } while ( $post_name_check );

          $slug = $alt_post_name;
      }

    return $slug;
}
5
Stephen Harris