web-dev-qa-db-fra.com

Empêcher le slug de page d'interférer avec le permalien d'archive de type publication personnalisé?

Dans mon plugin, je crée un type de publication personnalisé qui a une archive et utilise le paramètre rewrite pour choisir un slug:

$args = array (
    'public' => true,
    'has_archive' => true,
    'rewrite' => array('slug' => 'lessons', 'with_front' => false)
);
register_post_type ('my_plugin_lesson', $args);

Avec ce code, je reçois une archive des articles 'my_plugin_lesson' à example.com/lessons/.

Cependant, je peux aussi créer une page avec le titre "Leçons", et WordPress lui attribuera le slug "leçons". Le lien Afficher la page sur le panneau d'administration de cette page sera example.com/lessons/, mais la page est inaccessible car WordPress affiche les archives de mon type de publication personnalisé.

Existe-t-il un moyen d'empêcher WordPress de choisir un slug pour les pages ou les publications qui interfèrent avec le slug de mes types de publication personnalisés?

1
Ben Miller

Je sais que vous avez déjà trouvé la solution, car vous avez compris que cette question avait déjà été posée et répondue ...

Cependant, une fois que cette question est une prime et ne peut pas être fermée en double, je veux donner un sens à cela, et ajouter (un peu) de valeur supplémentaire aux réponses déjà postées.

Que fait-on dans ces réponses (la l'une par @ RachelCarden et celle postée ici par @ matthew-boynes ) est ce dont vous avez besoin, mais il est codé en dur , c’est-à-dire que vous devez manuellement ajoutez le slug d'archive cpt dans la fonction de filtrage.

Ce que je veux obtenir, c’est un filtre qui fonctionne de la même manière, mais de manière dinamique , quelque chose comme:

add_filter('wp_unique_post_slug_is_bad_hierarchical_slug', 'prevent_slug_override', 99, 3);
add_filter('wp_unique_post_slug_is_bad_flat_slug', 'prevent_slug_override', 99, 3);

function prevent_slug_override( $now, $slug, $type ) {
  if ( in_array($type, array('nav_menu_item', 'revision', 'attachment') ) )
    return $now;
  $cpts = get_post_types( array('_builtin' => false), 'objects' );
  $check_bad = array();
  foreach ( $cpts as $cpt => $object ) {
    if ( $object->has_archive ) {
      if (
        ! empty($object->rewrite) && isset($object->rewrite['slug']) &&
        ! empty($object->rewrite['slug']) && ($object->rewrite['slug'] != $cpt)
      ) {
        $check_bad[] = $object->rewrite['slug'];
      } else {
        $check_bad[] = is_string($object->has_archive) ? $object->has_archive : $cpt;
      }
    }
  }
  if ( in_array($slug, $check_bad) ) return true;
  return $now;
} 
4
gmazzap

Je pense que vous pourriez utiliser les filtres de wp_unique_post_slug pour éviter ce conflit. Essayez ce qui suit

function wpse_109072_is_slug_conflict( $false, $slug, $post_type ) {
    return ( 'page' == $post_type && 'lessons' == $slug );
}
add_filter( 'wp_unique_post_slug_is_bad_hierarchical_slug', 'wpse_109072_is_slug_conflict', 10, 3 );
add_filter( 'wp_unique_post_slug_is_bad_flat_slug', 'wpse_109072_is_slug_conflict', 10, 3 );
2
Matthew Boynes