wake-up-neo.com

Mehrere Beitragstypen - denselben ReWrite-Slug teilen?

Ich bin auf eine weitere wundervolle 404-Ausgabe gestoßen. Ich versuche, 2 verschiedene Post-Typen zu haben, die den gleichen Neuschreibungs-Slug haben. Ich habe meine Umschreiberegeln gelöscht und wenn ich nur eine CPT-Funktion teste, wird die andere mit 404 bewertet. Meine Umschreibung, die ich für beide verwenden möchte, lautet:

'rewrite' => array('slug' => 'team/%teamtype%'),

Weiß jemand, wie man damit umgeht?

add_action( 'init', 'create_rider_type' );

function create_rider_type() {

register_post_type('riders', 
array(  
    'description' => 'rider custom post type',
    'show_ui' => true,
    'menu_position' => 5,
    'menu_icon' => get_stylesheet_directory_uri() . '/images/riders.png',
    'exclude_from_search' => false,
    'labels' => array(
        'name' => 'Team Riders',
        'singular_name' => 'Rider',
        'add_new' => 'Add New rider',
        'add_new_item' => 'Add New rider',
        'edit' => 'Edit riders',
        'edit_item' => 'Edit rider',
        'new_item' => 'New rider',
        'view' => 'View rider',
        'view_item' => 'View rider',
        'search_items' => 'Search riders',
        'not_found' => 'No riders found',
        'not_found_in_trash' => 'No riders found in Trash',
        'parent' => 'Parent rider',
    ),
    'hierarchical' => false,
    'supports' => array('title','editor','excerpt', 'trackbacks','custom-fields', 'comments','revisions','thumbnail','author','page-attributes'),
    'public' => true,
    'rewrite' => array('slug' => 'team/%teamtype%'),
    'taxonomies' => array('teamtype')
    ) 
);


}





add_action( 'init', 'create_sponsor_type' );

function create_sponsor_type() {

register_post_type('sponsors', 
array(  
    'description' => 'sponsor custom post type',
    'show_ui' => true,
    'menu_position' => 5,
    'menu_icon' => get_stylesheet_directory_uri() . '/images/sponsors.png',
    'exclude_from_search' => false,
    'labels' => array(
        'name' => 'Team sponsors',
        'singular_name' => 'sponsor',
        'add_new' => 'Add New sponsor',
        'add_new_item' => 'Add New sponsor',
        'edit' => 'Edit sponsors',
        'edit_item' => 'Edit sponsor',
        'new_item' => 'New sponsor',
        'view' => 'View sponsor',
        'view_item' => 'View sponsor',
        'search_items' => 'Search sponsors',
        'not_found' => 'No sponsors found',
        'not_found_in_trash' => 'No sponsors found in Trash',
        'parent' => 'Parent sponsor',
    ),
    'hierarchical' => false,
    'supports' => array('title','editor','excerpt', 'trackbacks','custom-fields', 'comments','revisions','thumbnail','author','page-attributes'),
    'public' => true,
    'rewrite' => array('slug' => 'team/%teamtype%'),
    'taxonomies' => array('teamtype')
    ) 
);

}

** * ** * ** * **** Update * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * *

Der ursprüngliche CPT-Umschreibecode, den ich gepostet habe, wurde vereinfacht, damit ich direkter auf den Punkt kommen kann. Vielleicht ist es jedoch sinnvoller, wenn Sie sehen, wie ich diese Permalinks mit meiner benutzerdefinierten Taxonomie behandle. Ich habe den Code zum Anzeigen aktualisiert.

Ich möchte sie wirklich als separate Post-Typen behalten - sowohl für die Organisation als auch als separate Metaboxen für jede. Bitte überprüfen Sie die aktualisierten Umschreibungen für die CPTs sowie mein Taxonomie-Setup unten:

add_action( 'init', 'create_team_taxonomies' );

function create_team_taxonomies() {
register_taxonomy( 
'teamtype', 
array('riders','sponsors'),
array( 
    'labels' => array(
        'name' => 'Team Types',
        'singular_name' => 'Team Type',
        'search_items' =>  'Search Team Types',
        'popular_items' => 'Popular Team Types',
        'all_items' => 'All Team Types',
        'parent_item' => 'Parent Team Type',
        'parent_item_colon' => 'Parent Team Type:',
        'edit_item' => 'Edit Team Type', 
        'update_item' => 'Update Team Type',
        'add_new_item' => 'Add New Team Type',
        'new_item_name' => 'New Team Type Name'
    ), 
'hierarchical' => true, 
'public' => true,
'show_ui' => true,
'query_var' => 'teamtype',
'show_tagcloud' => true,
'rewrite' => array( 'slug' => 'team', 'with_front' => false) 
) 
);

}

Und so richte ich das Umschreiben ein, wenn ich die Taxonomie auswähle und den Beitrag veröffentliche:

add_filter('post_link', 'teamtypepermalink', 10, 3);
add_filter('post_type_link', 'teamtypepermalink', 10, 3);

function teamtypepermalink($permalink, $post_id, $leavename) {
if (strpos($permalink, '%teamtype%') === FALSE) return $permalink;

    // Get post
    $post = get_post($post_id);
    if (!$post) return $permalink;

    // Get taxonomy terms
    $terms = wp_get_object_terms($post->ID, 'teamtype');    
    if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) $taxonomy_slug = $terms[0]->slug;
    else $taxonomy_slug = 'not-specified';

return str_replace('%teamtype%', $taxonomy_slug, $permalink);
}
4
Joe

Ich habe gerade ein Projekt durchgeführt, in dem zwei benutzerdefinierte Post-Typen denselben Slug verwenden mussten. Der Trick besteht darin, die Abfragevariablen über den Filter request zu überschreiben . Nennen wir die Post-Typen "foo" und "bar", und sie teilen sich Slug "foo".

Der folgende Code ist grob und nur als Beispiel aus dem Speicher. Nach Geschmack salzen, nicht kopieren und einfügen:

add_filter('request', 'overwriteQueryVars', 10, 1);

function overwriteQueryVars($query)
{
    if ( empty($query['post_type']) || $query['post_type']!='foo' ) {
        return $query;
    }

    // Run an SQL query that looks like this, against both post types
    $sql = "SELECT ID FROM wp_posts WHERE post_type='foo' and post_name='%s'";
    $post_name = urlencode($query['name']);

    // If you've found that the row exists for post_type 'bar' but not 'foo',
    // then simply return the $query array unaltered
    if ( in_foo_but_not_bar ) {
        return $query;
    }

    // If you've found that the row exists for post_type 'bar' but not 'foo',
    // then rewrite the $query array:

    // Original:
    $query = array (
        'page' => '',
        'foo' => 'some-Nice-post',
        'post_type' => 'foo',
        'name' => 'some-Nice-post',
    );

    // Make it look like this:
    $query = array (
        'page' => '',
        'bar' => 'some-Nice-post',
        'post_type' => 'bar',
        'name' => 'some-Nice-post',
    );

}
1
dotancohen

Soweit ich weiß, können Sie das nicht tun. Jeder Slug wird in ein query_vars-Element konvertiert, das einen bestimmten Objekttyp (Taxonomie oder Beitragstyp) abfragt. Wenn Sie Ihre WP_Query analysieren, werden Sie feststellen, dass der erste Beitragstyp abgefragt wird.

Vielleicht kann uns ein WP Ninja hier aufklären, aber ich bin mir fast sicher, dass Sie das nicht können. Zumindest solltest du das nicht.

1
MZAweb

Da CPTs (und Posts/Seiten) erstellt werden, ist dies nicht möglich. Der Slug ist für den spezifischen Typ reserviert, mit der Annahme, dass 2 CPTs = 2 verschiedene Arten von Inhalten sind.

basierend auf Ihrem Code scheint es fast so, als ob jedes der Elemente, die Sie in der CPT haben, besser als benutzerdefinierte Taxonomie bereitgestellt werden würde, da beide an eine einzelne CPT gebunden sind (ich vermute, eine Art Ereignis?)

1
Norcross

Ich weiß, dass diese Frage sehr alt ist, aber als ich nach einer Lösung für ein ähnliches Problem suchte, kam diese Frage dem, was ich erreichen wollte, am nächsten, und da sie bei meiner Suche auftauchte, dachte ich, dass es vielleicht noch keine gibt bessere Lösungen zur Verfügung. Deshalb füge ich die Lösung, die ich mir ausgedacht habe, unten hinzu, falls sie später jemandem mit einem ähnlichen Problem helfen könnte.

Ich hatte ein ähnliches Problem. Ich wollte einen neuen benutzerdefinierten Beitragstyp haben, der den Slug mit einem anderen Beitragstyp teilt. In meinem Fall hatte ich einen Beitragstyp namens country-info und wollte die gleiche Permalink-Struktur verwenden wie der Standard-Beitragstyp page.

Mit anderen Worten, ich wollte, dass es mit example.com/page-name/ anstelle von example.com/country-info/page-name zugänglich ist.

So habe ich es gelöst:

// I found it easiest to grab the request in the parse_request hook. There you can see
// the requested slug, as well as if the requested page existed or not.

add_action('parse_request', 'overwriteRequest', 10, 1);
function overwriteRequest($query) {

    // If the request matched an existing page, the query_vars array will contain the
    // post_type, but otherwise it will only contain an error.
    // So we only execute our code if the post_type is empty
    // On the top page, the query_vars is an empty array, so we check for that too!
    if ( count($query->query_vars) > 0 && empty($query->query_vars['post_type'])) {

        // The request contains the string that was requested.
        $pageName = $query->request;
        $postType = 'country-info';

        // Check if post with the requested slug exists in your custom post type
        $result = get_posts(array(
            'post_type' => $postType,
            'name' => $pageName
        ));

        // If it doesn't, just return the query
        if (count($result) < 1) {

            return $query;

        // If it does, create a new query_vars array to replace the old one.
        } else {
            $new_query = array(
                'page' => '',
                'country-info' => $pageName,
                'post_type' => $postType,
                'name' => $pageName
            );
            $query->query_vars = $new_query;
            return $query;
        }

    } else {
        return $query;
    }
}

Bitte beachten Sie:

In meinem Fall haben die Anfragen, nach denen ich gesucht habe, alle auf Stammebene der Domain wie example.com/page-name lauten, aber wenn sich Ihr benutzerdefinierter Beitragstyp in einem Verzeichnis wie example.com/some-directory/post-name/ befindet, müssen Sie eine Sache im Code ändern:

$pageName = $query->request;

muss sein

$pageName = preg_replace('/my-directory-name\//', '', $query->request)

Andernfalls versucht get_posts, einen Beitrag zu finden, in dem der Slug Ihr Verzeichnis enthält, wodurch Sie immer null Ergebnisse erhalten. Dieser preg_replace entfernt einfach Ihren Verzeichnisnamen aus der Zeichenkette.

Denken Sie daran, my-directory-name durch den tatsächlichen Verzeichnisnamen zu ersetzen!

Diese Lösung ist getestet und funktioniert mit WordPress 4.9.7

0
Azer

Ihre Umschreiberegeln überschreiben sich gegenseitig und WordPress fragt nur nach einem der Beitragstypen. Ich denke, es ist die letzte registrierte, die "gewinnt", also fragt /testslug/bmw/ immer nach einem Beitrag mit Slug bmw und Beitragstyp sponsors. Wenn Sie zu /testslug/some-name/ gehen und some-name ein Fahrer ist, wird weiterhin nach dem Post-Typ sponsors und dem Post-Slug some-name gefragt. Es findet keinen Beitrag und gibt Ihnen daher eine 404. Dies geschieht in der "Standard" -Abfrage, die WordPress für Sie ausführt, bevor die Vorlagenseite geladen wird, sodass Sie dies beispielsweise in Ihrer single-sponsors.php-Vorlagendatei nicht lösen können ( Sie könnten in 404.php, aber dann wird es hässlich).

Die sauberste Lösung besteht darin, einen Teil der Logik, die diese URL-Analyse durchführt, zu ersetzen und eine "mehrdeutige" URL zu akzeptieren. Testen Sie, ob es sich um einen Fahrer oder einen Sponsor handelt, und ändern Sie die Parameter, damit WordPress entweder mit einem Fahrer oder einem Sponsor fortfährt. Mike hat einmal eine Möglichkeit bereitgestellt mit Seiten und Taxonomien, sollte es möglich sein, dies zu erweitern, um nur mit Posts zu arbeiten.

0
Jan Fabry