web-dev-qa-db-fra.com

Comment faire pour supprimer la catégorie des parents Permalink à partir de messages

En parlant simplement, je veux faire quelque chose comme ça.

http://example.com/parent-category/child-category/post-name

changer en

http://example.com/child-category/post-name

J'ai trouvé des solutions, mais elles ne sont pas parfaites. Par exemple, j'ai trouvé ce code qui fait la chose presque correctement.

add_filter( 'post_link', 'remove_parent_category', 10, 3 );
function remove_parent_category( $permalink, $post, $leavename )
{
$cats = get_the_category( $post->ID );
if ( $cats ) {
    usort( $cats, '_usort_terms_by_ID' );
    $category = $cats[0]->slug;
    if ( $parent = $cats[0]->parent ) {
        // Find parent categories and replace them in the link
        $parentcats = get_category_parents( $parent, false, '/', true );
        $permalink = str_replace( $parentcats, '', $permalink );
    }
}
return $permalink;
}

À cause de str_replace, il casse les liens si les catégories ont des noms similaires. Comme

http://example.com/myhouse/house/post-title

Il supprimera la maison des deux catégories. Quelqu'un peut-il réparer ce code pour travailler avec des noms?

1
Recofa

Avec str_replace ou preg_replace, sans conventions de nommage du côté utilisateur ni travail important dans les directives de la méthode (lié, vous pouvez en savoir plus sur les modèles ici, ), vous allez rencontrer des problèmes avec le

House | My House | New House scénarios; en particulier une fois que vous avez affaire à des limaces, et si ces limaces sont des choses comme myhouse et newhouse.

Ensuite, les questions deviennent "Qu'en est-il des petits-enfants?" Et "Et si la publication est dans plusieurs catégories d'enfants avec des parents différents et si le mauvais parent est en première position de ce tableau $cats?"


Solution possible: filtrer le lien permanent pour supprimer les catégories parentes

Ce qui suit semble fonctionner de mon côté pour les scénarios que j'ai mentionnés ci-dessus, et il évite de remplacer str_- et preg_-tout à fait.

Je suppose par votre exemple de lien:

http://example.com/myhouse/house/post-title

que votre structure de liens permanents est /%category%/%postname%/ Et que l'objectif ici est de limiter le lien permanent au plus jeune membre de la famille de catégorie et de publier le titre. Donc, example.com/child-cat/post-title/ ou example.com/grandchild-cat/post-title

Puisque nous savons que nous voulons seulement que ces deux dernières valeurs restent, et que nous avons le permalien, analysons-le, éclatons la portion du chemin dans un tableau, comptons les entrées du tableau, conservons les entrées dernière et dernière et reformons permalink et le retourner.

Une fois que nous nous sommes assurés que nous avons affaire à un poste qui a même une catégorie enfant, bien sûr.

Quelque chose comme ça peut être:

    add_filter( 'post_link', 'remove_parent_category', 10, 3 );
    function remove_parent_category( $permalink, $post, $leavename ) {

         $cats = get_the_category( $post->ID );

         if ( $cats ) {

             foreach ($cats as $cat => $parent) {

               $cat_parent_values[] = $parent->parent; 
             }

             if( array_sum( $cat_parent_values ) > 0 )  {

                 $url_array      = parse_url( $permalink );
                 $url_path       = array_filter( explode( '/', $url_array['path'] ) );
                 $url_path      = array_values($url_path);
                 $url_path_count = count( $url_path );

                 $name_slot      = $url_path_count - 1;  
                 $child_cat_slot = $name_slot - 1;

                 $new_url_path[] = '/'. $url_path[ $child_cat_slot ];
                 $new_url_path[] = '/'. $url_path[ $name_slot ] .'/';

                 $new_permalink  = $url_array['scheme'] .'://'. $url_array['Host'] . $new_url_path[0] . $new_url_path[1];

             }//end if sum > 0
         }//end if $cats

        return $new_permalink;
    }  

Un test préliminaire de celui-ci semble fonctionner correctement sur une nouvelle installation, et il passe sans problème, il passe le test House | MyHouse. Je suis sûr que cela peut être amélioré, et vous devrez vraiment le tester et vous assurer qu'il n'y a pas d'autres problèmes/scénarios qui le résout. Il pourrait très bien exister une meilleure approche qui ne consiste pas à filtrer le permalien, mais je ne suis pas sûre d’un coup de main.

Explication:

Nous utilisons d’abord get_the_category comme si vous deviez déjà obtenir un tableau d’objets catégorie. Nous vérifions que nous en avons, puis nous faisons une boucle foreach de array as $key => $value, en convertissant chaque valeur dans un nouveau tableau.

Wordpress stocke la valeur de parent pour une catégorie en tant qu'id, et cet identifiant est un (int). S'il n'y a pas de parent, il obtient un 0. Donc, si la somme de toutes les valeurs de notre nouveau tableau est supérieure à 0, nous avons au moins une catégorie parente. Et cela signifie que nous avons au moins une partie du chemin dans notre lien permanent que nous voulons supprimer, alors nous continuons.

php's parse_url nous donnera un tableau () de 'scheme' => 'http', 'Host' => 'example.com', 'path' => '/category/child-cat/postname/'

nous explode() that, $url_array, à chaque /, ce qui nous donne un tableau de chaque section. Il nous donne également des valeurs de tableau vides, nous l'enveloppons donc dans array_filter et le nettoie pour nous, espérons-le, et nous le configurons à $url_path. Nous pouvons utiliser [array_values()][5] pour nettoyer les clés numériques manquantes supprimées par array_filter et nous donner [0],[1],[2] pour les clés d'un tableau de trois éléments.

Comme mentionné précédemment, nous supposons que le nom de l'article est à la fin. Ainsi, avec notre tableau filtré et re-évalué, nous utilisons count() pour savoir combien de clés se trouvent dans ce tableau, et nous nous en servons pour trouver notre nom en soustrayant " un "puisque le tableau commence à [0]. Puis soustrayez un de que et nous avons notre "catégorie la plus jeune".

Ensuite, nous avons reconstitué le permalien en utilisant notre $ url_array et les parties de chemin pour le nom du message et la catégorie que nous voulons conserver, en ignorant tout ce qui se trouvait là.

et nous le renvoyons au filtre post_link.


Autres problèmes possibles que j'ai remarqués avec votre exemple:

L'exemple que vous avez fourni présente d'autres problèmes potentiels: get_the_category() renverra un tableau d'objets de catégorie, mais si cet objet usort() est conçu pour les classer par leur ID, si vous créez une catégorie qui devient le parent d'une catégorie existante, commencez par le faire. La position de ce tableau, $cats[0], ne sera pas nécessairement une catégorie parente. (sauf si je comprends mal la nature de _usort_terms_by_id.

Il est également difficile de savoir à quoi la variable $parent dans if($parent = $cats[0]->parent) doit être définie.

1
hwl