it-swarm.com.de

So entfernen Sie Eltern Kategorie Permalink aus Beiträgen

Einfach gesagt, ich möchte so etwas tun.

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

ändern in

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

Ich habe einige Lösungen gefunden, aber sie sind nicht perfekt. Zum Beispiel habe ich diesen Code gefunden, der das Ding fast richtig macht.

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;
}

Wegen str_replace werden Links getrennt, wenn Kategorien ähnliche Namen haben. Mögen

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

Das Haus wird aus beiden Kategorien gelöscht. Kann jemand diesen Code reparieren, um mit irgendwelchen Namen zu arbeiten?

1
Recofa

Mit entweder str_replace oder preg_replace können Sie ohne einige Namenskonventionen auf der Benutzerseite oder starke Arbeit in den Direktiven (verknüpft) der Methode über Muster lesen hier ) werden Sie auf Probleme mit dem stoßen

House | My House | New House Szenarien; vor allem, wenn Sie mit Schnecken zu tun haben und wenn diese Schnecken Dinge wie myhouse und newhouse sind.

Dann lauten die Fragen "Was ist mit Enkelkindern?" Und "Was ist, wenn sich der Beitrag in mehreren Kinderkategorien mit verschiedenen Eltern befindet und sich das falsche Elternteil an der ersten Stelle dieses $cats-Arrays befindet?".


Mögliche Lösung: Filtern Sie den Permalink, um übergeordnete Kategorien zu entfernen

Das Folgende schien für die oben genannten Szenarien zu funktionieren, und es vermeidet, dass str_- und preg_-insgesamt ersetzt werden.

Ich gehe von deinem Linkbeispiel aus:

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

dass Ihre Permalink-Struktur /%category%/%postname%/ ist und dass das Ziel hier darin besteht, den Permalink auf das jüngste Mitglied der Kategorie family und post title zu beschränken. Also, example.com/child-cat/post-title/ oder example.com/grandchild-cat/post-title

Da wir wissen, dass nur diese beiden letzten Werte erhalten bleiben sollen, und wir den Permalink haben, analysieren wir ihn, zerlegen den Pfadabschnitt in ein Array, zählen die Arrayeinträge, behalten die letzten und vorletzten Einträge bei und reformieren die Permalink und gib es zurück.

Nachdem wir uns vergewissert haben, dass es sich um einen Beitrag handelt, der natürlich auch eine Kinderkategorie hat.

So etwas vielleicht:

    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;
    }  

Ein vorläufiger Test scheint auf meiner Seite bei einer Neuinstallation zu funktionieren, und ohne str_replace besteht er den House | MyHouse-Test. Ich bin sicher, dass es verbessert werden kann, und Sie müssen es wirklich testen und sicherstellen, dass es keine anderen Probleme/Szenarien gibt, die es zerstören. Es könnte durchaus einen besseren Ansatz geben, bei dem der Permalink nicht gefiltert wird, aber ich bin mir nicht sicher, ob es überhaupt einen gibt.

Erläuterung:

Zuerst verwenden wir get_the_category , als müssten Sie bereits ein Array von Kategorieobjekten abrufen. Wir überprüfen, ob wir welche haben und führen dann eine foreach-Schleife von array as $key => $value durch, wobei jeder Wert in ein neues Array umgewandelt wird.

Wordpress speichert den Wert von parent für eine Kategorie als die ID, und diese ID ist ein (int). Wenn es kein übergeordnetes Element gibt, erhält es einen 0. Wenn also die Summe aller Werte in unserem neuen Array größer als 0 ist, haben wir mindestens eine übergeordnete Kategorie. Das bedeutet, dass wir mindestens einen Pfadteil in unserem Permalink haben, den wir entfernen möchten, also fahren wir fort.

phps parse_url gibt uns ein Array () von 'scheme' => 'http', 'Host' => 'example.com', 'path' => '/category/child-cat/postname/'

we explode() dass, $url_array, bei jedem / was uns ein Array von jedem Abschnitt gibt. Es gibt uns auch einige leere Array-Werte, so dass wir es in array_filter einschließen und das hoffentlich für uns bereinigen und wir setzen es auf $url_path. Mit [array_values()][5] können wir fehlende numerische Schlüssel bereinigen, die durch array_filter entfernt wurden, und uns [0],[1],[2] für Schlüssel in einem Array von drei Elementen geben.

Wie bereits erwähnt, gehen wir davon aus, dass der Name des Posts am Ende ist. Bei unserem gefilterten und neu bewerteten Array verwenden wir also count(), um zu ermitteln, wie viele Schlüssel sich in diesem Array befinden, und verwenden dies, um unseren Postnamen durch Subtrahieren von " eins ", da das Array bei [0] beginnt. Dann subtrahiere man von das und wir haben unsere "jüngste Kategorie".

Dann setzen wir den Permalink wieder zusammen, indem wir unser $ url_array und die Pfadteile für den Postnamen und die Kategorie verwenden, die wir behalten möchten, und ignorieren, was sonst noch da war.

und wir geben es an den post_link-Filter zurück.


Andere mögliche Probleme, die mir bei Ihrem Beispiel aufgefallen sind:

Es gibt einige andere potenzielle Probleme mit dem von Ihnen angegebenen Beispiel: get_the_category() gibt ein Array von Kategorieobjekten zurück. Wenn diese usort() sie jedoch nach ihren IDs ordnen soll, erstellen Sie zuerst eine Kategorie, die einer vorhandenen Kategorie übergeordnet wird Die Position dieses Arrays, $cats[0], muss nicht unbedingt eine übergeordnete Kategorie sein. (es sei denn, ich verstehe die Natur von _usort_terms_by_id falsch.

Es ist auch unklar, auf was die Variable $parent in if($parent = $cats[0]->parent) eingestellt werden soll.

1
hwl