Tipos de postagens aninhados com permalinks

8

Estou tentando configurar uma estrutura de tipo de postagem personalizada de vários níveis com permalinks parecidos com authors/books/chapters , com autores, livros e capítulos configurados como seu próprio tipo de postagem personalizado. Por exemplo, um URL típico neste site pode parecer com example.com/authors/stephen-king/the-shining/chapter-3/

Cada capítulo só pode pertencer a um livro e cada livro só pode pertencer a um autor. Considerei usar taxonomias em vez de CPTs para autores e livros, mas preciso associar metadados a cada item e prefiro a interface de postagem para isso.

Estou na maior parte do caminho simplesmente configurando cada postagem personalizada como filha de uma entrada no CPT um nível acima. Por exemplo, eu crio "Capítulo 3" e atribuo "The Shining" como um pai usando uma meta-caixa personalizada. "O Iluminado", por sua vez, tem "Stephen King" como pai. Eu não tive nenhum problema em criar essas relações.

Estou usando tags de reescrita nos slugs do CPT e os permalinks querem funcionar, mas não estão certos. Usando um analisador de reescrita, posso ver que as regras de reescrita são realmente geradas, mas elas não parecem estar na ordem correta e, portanto, outras regras são processadas primeiro.

Veja como registrei meus CPTs:

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' );

Então, há alguma maneira de mudar a prioridade das minhas regras de reescrita para que os autores, livros e capítulos sejam todos correspondidos primeiro?

Eu também sei que vou ter que adicionar um filtro post_type_link , mas isso parece secundário para conseguir os permalinks logo no começo. Se alguém souber onde eu posso encontrar uma visão abrangente de como esse filtro funciona, seria apreciado.

    
por Dalton 07.08.2012 / 15:34

3 respostas

11

Se você quiser manter 'autores' como o slug base nos permalinks, ou seja, example.com/authors/stephen-king / para o CPT dos autores, example.com / autores / stephen-king / the-shining / para o CPT de 'livros' e example.com/authors/stephen-king/the-shining/chapter-3 / para o ' CPT dos capítulos, o WordPress vai pensar que praticamente tudo é um post de 'autores' ou um filho hierárquico de um post de 'autores' e, como esse não é o caso, o WordPress acaba se tornando muito confuso.

Com isso dito, há uma solução que é bem básica, mas desde que a estrutura do link permanente sempre siga a mesma ordem, ou seja, a palavra 'autores' é sempre seguida por um slug de autor, que é sempre seguido por um slug de livro é sempre seguido por uma lesma de capítulo, então você deve ser bom para ir.

Nesta solução, não há necessidade de definir o slr de reescrita na definição de tipo de postagem personalizada para 'capítulos' e 'livros', mas defina o caractere de reescrita dos 'autores' como simplesmente 'autores', coloque o seguinte código em seu arquivo functions.php e "flush" suas regras de reescrita.

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

Saiba mais sobre o plugin CPT-onomies

    
por Rachel Carden 14.08.2012 / 06:29
4

Eu não tenho experiência pessoal com esse cenário, mas Randy Hoyt fez uma apresentação no WordCamp San Fran na semana passada sobre "Subordinate Post Types" que soa como o que você está falando.

Aqui está sua página para a palestra que inclui os slides de sua apresentação e os links para um plug-in que ele criou para trabalhar com tipos de post subordinados: enlace

    
por mannieschumpert 11.08.2012 / 17:43
1

As regras serão adicionadas ao extra_rules_top de WP_Rewrite na ordem em que as permastructs extras forem adicionadas. Assim, a mudança da ordem em que você registra os tipos de postagem alternará a ordem em que as regras de reconfiguração serão geradas, fazendo com que a reconfiguração do capítulo seja correspondida primeiro. No entanto, desde que você esteja usando o query_var dos outros post_types, o wp_query pode acabar combinando com um deles como o nome do posto consultado antes de combinar o capítulo como você deseja.

Eu criaria novas tags de reescrita para representar os espaços reservados para o autor pai e o pai-livro, por exemplo:

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

Ao fazer isso, você terá que filtrar 'query_vars' para tornar 'parent_book' público. Em seguida, você precisará adicionar um filtro a pre_get_posts que converterá o nome definido como o parent_book query_var no post_id e o definirá como 'post_parent'.

    
por prettyboymp 11.08.2012 / 00:54