Tipi di post personalizzati nidificati con permalink


9

Sto cercando di impostare una struttura di tipo di post personalizzato multilivello con permalink che sembrano authors/books/chapters, con autori, libri e capitoli tutti impostati come il proprio tipo di post personalizzato. Ad esempio, potrebbe apparire un tipico URL su questo sitoexample.com/authors/stephen-king/the-shining/chapter-3/

Ogni capitolo può appartenere a un solo libro e ogni libro può appartenere a un solo autore. Ho preso in considerazione l'utilizzo di tassonomie anziché CPT per autori e libri, ma devo associare metadati a ciascun elemento e preferisco l'interfaccia post per questo.

Sono quasi arrivato semplicemente impostando ogni post personalizzato come figlio di una voce nel CPT di un livello superiore. Ad esempio, creo "Chapter 3" e assegno "The Shining" come genitore usando una meta-box personalizzata. "The Shining" a sua volta ha "Stephen King" come genitore. Non ho avuto problemi a creare queste relazioni.

Sto usando i tag di riscrittura nelle lumache CPT e i permalink vogliono funzionare, ma non sono del tutto giusti. Usando un analizzatore di riscrittura, posso vedere che le regole di riscrittura sono effettivamente generate, ma non sembrano essere nel giusto ordine e quindi altre regole vengono elaborate per prime.

Ecco uno screenshot del mio analizzatore di riscrittura.

Ecco come ho registrato i miei CPT:

function cpt_init() {

  $labels = array(
    'name' => 'Authors'
   );

  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true,
    'rewrite' => array(
        'slug' => 'author',
        'with_front' => FALSE,
    ),
    'with_front' => false,
    'capability_type' => 'post',
    'has_archive' => false, 
    'hierarchical' => true,
    'menu_position' => null,
    'supports' => array( 'title', 'editor' )
  ); 

  register_post_type('authors',$args);

  $labels = array(
    'name' => 'Books'
  );

  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true,
    'rewrite' => array(
        'slug' => 'author/%authors%',
        'with_front' => FALSE,
    ),
    'with_front' => false,
    'capability_type' => 'post',
    'has_archive' => false, 
    'hierarchical' => true,
    'menu_position' => null,
    'supports' => array( 'title', 'editor' )
  ); 

  register_post_type('books',$args);


  $labels = array(
    'name' => 'Chapters'
   );

  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true,
    'rewrite' => array(
        'slug' => 'author/%authors%/%books%',
        'with_front' => FALSE,
    ),
    'with_front' => FALSE,
    'capability_type' => 'post',
    'has_archive' => false, 
    'hierarchical' => true,
    'menu_position' => null,
    'supports' => array( 'title', 'editor' )
  ); 

  register_post_type('chapters',$args);

}

add_action( 'init', 'cpt_init' );

Quindi c'è un modo per cambiare la priorità delle mie regole di riscrittura in modo che autori, libri e capitoli vengano tutti abbinati per primi?

So anche che dovrò aggiungere un post_type_linkfiltro, ma questo sembra secondario per ottenere i permalink in primo luogo. Se qualcuno sa dove posso trovare una panoramica completa di come funziona quel filtro, sarebbe apprezzato.


Hai considerato di usare solo Pages? Otterresti automaticamente la giusta struttura del permalink.
Michael Hampton,

L'ho sicuramente considerato. Il problema con le pagine è che potremmo avere 100 articoli di nipoti per un singolo autore, che sarà molto difficile da gestire nell'amministratore delle pagine. Inoltre, dobbiamo essere in grado di eseguire query per tipo di post.
Dalton,

Sto lavorando a una soluzione ma ho una domanda veloce: è fondamentale avere "autore" davanti a ogni permalink? Perché quello sembra essere lo stickler. Penso che sia un po 'confuso WordPress un po' troppo, soprattutto perché si tratta di una lumaca permalink utilizzata anche per le pagine degli autori di WP. Se è necessario avere "autore", penso che tutto sia ancora fattibile ... sarà solo più complicato.
Rachel Carden,

Oops, non mi rendevo conto che l'autore sarebbe entrato in conflitto con la lumaca dell'autore WP integrata. No, non è necessario, potrebbe essere qualsiasi cosa. Pensavo di aver bisogno di qualcosa lì perché è un CPT, ma poteva essere altrettanto facilmente "scrittori" o qualsiasi altra cosa.
Dalton,

Mi sono reso conto che la confusione sta in realtà con i CPT che condividono "autore" come la lumaca di base. Una volta impostato "autore" come lumaca per gli "autori" CPT, e quindi impostato "autore /% autore%" per i capitoli "libri" di CPT e "autore /% autore% /% libro%" per i capitoli di CPT ', quindi WordPress pensa che i post per "libri" e i post per "capitoli" siano letteralmente post gerarchici per "autori". Ha senso? Nei miei test potresti tenere "autore" come base per gli "autori" della CPT e funziona perfettamente. Quindi sostituisci la mia domanda precedente con: hai bisogno di 'author' o la lumaca può iniziare con% author%?
Rachel Carden,

Risposte:


11

Se si desidera mantenere "autori" come la lumaca di base nei permalink, ad esempio example.com/authors/stephen-king/ per il "CPT degli autori", example.com/authors/stephen-king/the-shining/ per il 'libri' CPT ed example.com/authors/stephen-king/the-shining/chapter-3/ per il CPT 'capitoli', WordPress penserà praticamente che tutto sia un post di 'autori' o un figlio gerarchico di un 'autori 'post e, dato che non è così, WordPress alla fine diventa molto confuso.

Detto questo, c'è una soluzione abbastanza semplice ma fintanto che la struttura del tuo permalink segue sempre lo stesso ordine, cioè la parola "autori" è sempre seguita da una lumaca dell'autore, che è sempre seguita da una lumaca del libro che è sempre seguita da un capitolo slug, allora dovresti essere bravo ad andare.

In questa soluzione, non è necessario definire la lumaca di riscrittura nella definizione del tipo di post personalizzato per 'capitoli' e 'libri', ma impostare la 'lumaca di riscrittura degli autori come semplicemente' autori ', inserire il seguente codice nelle funzioni.php file e "svuota" le regole di riscrittura.

add_action( 'init', 'my_website_add_rewrite_tag' );
function my_website_add_rewrite_tag() {
    // defines the rewrite structure for 'chapters', needs to go first because the structure is longer
    // says that if the URL matches this rule, then it should display the 'chapters' post whose post name matches the last slug set
    add_rewrite_rule( '^authors/([^/]*)/([^/]*)/([^/]*)/?','index.php?chapters=$matches[3]','top' );
    // defines the rewrite structure for 'books'
    // says that if the URL matches this rule, then it should display the 'books' post whose post name matches the last slug set
    add_rewrite_rule( '^authors/([^/]*)/([^/]*)/?','index.php?books=$matches[2]','top' );   
}

// this filter runs whenever WordPress requests a post permalink, i.e. get_permalink(), etc.
// we will return our custom permalink for 'books' and 'chapters'. 'authors' is already good to go since we defined its rewrite slug in the CPT definition.
add_filter( 'post_type_link', 'my_website_filter_post_type_link', 1, 4 );
function my_website_filter_post_type_link( $post_link, $post, $leavename, $sample ) {
    switch( $post->post_type ) {

        case 'books':

            // I spoke with Dalton and he is using the CPT-onomies plugin to relate his custom post types so for this example, we are retrieving CPT-onomy information. this code can obviously be tweaked with whatever it takes to retrieve the desired information.
            // we need to find the author the book belongs to. using array_shift() makes sure only one author is allowed
            if ( $author = array_shift( wp_get_object_terms( $post->ID, 'authors' ) ) ) {
                if ( isset( $author->slug ) ) {
                    // create the new permalink
                    $post_link = home_url( user_trailingslashit( 'authors/' . $author->slug . '/' . $post->post_name ) );
                }
            }

            break;

        case 'chapters':

            // I spoke with Dalton and he is using the CPT-onomies plugin to relate his custom post types so for this example, we are retrieving CPT-onomy information. this code can obviously be tweaked with whatever it takes to retrieve the desired information.
            // we need to find the book it belongs to. using array_shift() makes sure only one book is allowed
            if ( $book = array_shift( wp_get_object_terms( $post->ID, 'books' ) ) ) {

                // now to find the author the book belongs to. using array_shift() makes sure only one author is allowed
                $author = array_shift( wp_get_object_terms( $book->term_id, 'authors' ) );

                if ( isset( $book->slug ) && $author && isset( $author->slug ) ) {
                    // create the new permalink
                    $post_link = home_url( user_trailingslashit( 'authors/' . $author->slug . '/' . $book->slug . '/' . $post->post_name ) );
                }

            }

            break;

    }
    return $post_link;
}

Ulteriori informazioni sul plug-in CPT-onomies


Funziona perfettamente, grazie! Sento di aver imparato così tanto. Anche il plugin CPT-onomies è davvero fantastico. wordpress.org/extend/plugins/cpt-onomies
Dalton

Ho la sensazione che potresti incontrare alcuni ostacoli man mano che la tua "biblioteca" cresce ma ho già in mente un po 'di codice, quindi, se lo fai, fammelo sapere.
Rachel Carden,

@RachelCarden Cosa fai quando due libri hanno lo stesso titolo ma autori diversi? Ci sarà una collisione nell'URL riscritto! Come si risolve questo?
Segfault,

1
@Segfault Dovrai recuperare tutte le lumache dell'autore in modo da poterle codificare nelle regole di riscrittura: foreach ($ author_slugs come $ author_slug) {add_rewrite_rule ('^ autori /'. $ Author_slug. '/ ([ ^ /] *) / ([^ /] *) /? ',' index.php? autori = '. $ author_slug.' & capitoli = $ match [2] ',' top '); add_rewrite_rule ('^ autori /'. $ author_slug. '/([^/[*)/?','index.php?authors='. $ author_slug. '& books = $ match [1]', 'top') ; }
Rachel Carden,

@Segfault Puoi usare get_terms () , se stai usando un CPT-onomy, o get_posts () per recuperare i nomi / slug dei post.
Rachel Carden,

4

Non ho esperienza personale con uno scenario simile, ma Randy Hoyt ha fatto una presentazione al WordCamp San Fran lo scorso fine settimana su "Tipi di post subordinati" che suona come quello di cui stai parlando.

Ecco la sua pagina per il discorso che include le sue diapositive di presentazione e i collegamenti a un plugin che ha creato per lavorare con tipi di post subordinati: http://randyhoyt.com/wordpress/subordinate-post-types/


Grazie, questa sembra una buona risorsa. Non è chiaro se questo supporta le relazioni dei nipoti, sebbene (non sembra nei miei test) e in realtà non aiuta con i permalink. Ho già escogitato un modo per impostare le mie relazioni figlio / genitore (anche se questo è un bel modo di farlo), ma i permalink sono davvero il problema su cui mi sono bloccato ora.
Dalton,

1

Le regole verranno aggiunte a extra_rules_top di WP_Rewrite nell'ordine in cui vengono aggiunti i permastrotti extra. Quindi, cambiando l'ordine in cui registri i tipi di post cambierà l'ordine in cui le regole di riscrittura verranno generate facendo corrispondere prima la riscrittura dei capitoli. Tuttavia, poiché stai usando query_var dagli altri post_types, wp_query potrebbe finire per abbinare uno di quelli come il nome del post interrogato prima di abbinare il capitolo come desideri.

Vorrei creare nuovi tag di riscrittura per rappresentare i segnaposto per l'autore principale e il libro principale, ovvero:

add_rewrite_tag('%parent-book%', '([^/]+)', 'parent_book=');

Nel fare ciò, dovrai filtrare "query_vars" per rendere pubblico "parent_book". Quindi dovrai aggiungere un filtro a pre_get_posts che convertirà il nome impostato come parent_book query_var nel post_id e lo imposterà come 'post_parent'.


Potresti fornire esempi di codice per i filtri che hai citato? Inoltre, come sarebbe il tag di riscrittura per il CPT nipote?
Dalton,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.