Obtendo permalinks de tipos de postagens hierárquicas personalizadas para funcionar como páginas

13

Eu pesquisei todas as perguntas aqui nos permalinks de tipos de postagens personalizadas, mas a maioria parece ser um problema com a nova regra de taxonomia personalizada ou a falta óbvia de flush_rewrite_rules (). Mas no meu caso, eu estou usando apenas um tipo de post personalizado (sem taxonomia), definido para ser hierárquico (para que eu possa atribuir relacionamentos pai-filho), com o "suporte" apropriado para os atributos metabox, etc, etc. flushed reescrever regras de mil maneiras diferentes. Eu tentei diferentes estruturas permalink. Mas URLs filhos sempre resultam em 404!

Originalmente, eu tinha tipos de postagem customizados independentes para os elementos "pai" e "filho" (usando p2p), e provavelmente não teria problemas em usar uma taxonomia para o agrupamento "parental" - sei que seria semanticamente mais preciso. Mas, para o cliente, é mais fácil visualizar a hierarquia quando as "postagens" são exibidas no admin, assim como as páginas são: uma árvore simples onde os filhos aparecem abaixo do pai, prefixados com um "-" e, no ordem correta. Além disso, vários métodos para atribuir ordem via arrastar e soltar podem ser usados. O agrupamento por taxonomia (ou p2p) resulta em uma lista simples de "publicações" nas listagens de administração, o que simplesmente não é tão óbvio.

Então, o que eu estou procurando é exatamente o mesmo comportamento das "páginas" centrais, mas com o meu tipo de postagem personalizado. Eu registrei o tipo de postagem como esperado, e no admin ele funciona perfeitamente - eu posso atribuir um pai e um menu_order para cada boletim informativo "post", eles aparecem corretamente nas listas de edição:

Spring 2012
— First Article
— Second Article

E seus permalinks aparecem para serem construídos corretamente. Na verdade, se eu mudar alguma coisa sobre a estrutura, ou mesmo alterar a regra de reescrita ao registrar o tipo de postagem, eles serão atualizados automaticamente corretamente, então sei que algo está funcionando:

http://mysite.com/parent-page/child-page/                  /* works for pages! */
http://mysite.com/post-type/parent-post/child-post/        /* should work? */
http://mysite.com/newsletter/spring-2012/                  /* works! */
http://mysite.com/newsletter/spring-2012/first-article/    /* 404 */
http://mysite.com/newsletter/spring-2012/second-article/   /* 404 */

Eu também tenho "páginas" centrais padrão com relações hierárquicas criadas, e elas parecem as mesmas no administrador, mas elas realmente funcionam no front-end também (URLs pai e filho funcionam bem).

Minha estrutura de permalink está definida como:

http://mysite.com/%postname%/

Eu também tentei isso (só porque muitas outras respostas pareciam indicar que era necessário, embora não fizesse sentido no meu caso):

http://mysite.com/%category%/%postname%/

Meus argumentos CPT de registro incluem:

$args = array(
    'public'                => true,
    'publicly_queryable'    => true,
    'show_ui'               => true,
    'has_archive'           => 'newsletter',
    'hierarchical'          => true,
    'query_var'             => true,
    'supports'              => array( 'title', 'editor', 'thumbnail', 'page-attributes' ),
    'rewrite'               => array( 'slug' => 'newsletter', 'with_front' => false ),

A única diferença visível entre os filhos crianças do meu tipo de post personalizado e da página normal é que o meu CPT tem o slug no início da estrutura do permalink, seguido por as lesmas pai / filho (onde as páginas apenas começam com as lesmas pai / filho, sem "prefixo"). Por que isso iria estragar as coisas, eu não sei. Muitos artigos parecem indicar que é exatamente assim que esses permalinks hierárquicos de CPT devem se comportar - mas os meus, embora bem formados, não funcionam.

O que também me deixa perplexo é quando examino os query_vars para essa página 404 - eles parecem conter os valores corretos para o WP "encontrar" minhas páginas filhas, mas algo não está funcionando.

$wp_query object WP_Query {46}
public query_vars -> array (58)
'page' => integer 0
'newsletter' => string(25) "spring-2012/first-article"
'post_type' => string(10) "newsletter"
'name' => string(13) "first-article"
'error' => string(0) ""
'm' => integer 0
'p' => integer 0
'post_parent' => string(0) ""
'subpost' => string(0) ""
'subpost_id' => string(0) ""
'attachment' => string(0) ""
'attachment_id' => integer 0
'static' => string(0) ""
'pagename' => string(13) "first-article"
'page_id' => integer 0
[...]

Eu tentei isso com vários temas, incluindo vinte e doze, só para ter certeza de que não é um modelo faltante da minha parte.

Usando o Rewrite Rules Inspector, isso é o que aparece para o URL:      enlace

newsletter/(.+?)(/[0-9]+)?/?$   
       newsletter: spring-2012/first-article
           page: 
(.?.+?)(/[0-9]+)?/?$    
       pagename: newsletter/spring-2012/first-article
           page: 

como é exibido em outra página do inspetor:

RULE:
newsletter/(.+?)(/[0-9]+)?/?$
REWRITE:
index.php?newsletter=$matches[1]&page=$matches[2]
SOURCE:
newsletter

Esta saída de reescrita me levaria a acreditar que o seguinte permalink "não-bonito" funcionaria:

enlace

Não faz 404, mas mostra o item "newsletter" do CPT principal, não o filho. A solicitação é assim:

Array
(
    [page] => first-article
    [newsletter] => spring-2012
    [post_type] => newsletter
    [name] => spring-2012
)
    
por somatic 28.12.2012 / 14:52

5 respostas

1

Então, depois de confirmar que eu poderia obter o esperado comportamento de página hierárquica com uma instalação completamente limpa e apenas uma declaração CPT, eu sabia que a falha estava em algum lugar dentro do meu próprio plugin que eu usei para lidar com a criação de CPT metaboxes, taxonomias, etc). O problema era que, apesar de todos os conselhos para verificar se havia problemas de reescrita ou consulta, eu não conseguia ver nada obviamente errado. Eu verifiquei cada filtro e gancho, visualizando a consulta em cada ponto e vendo nada que causaria o 404.

Então eu fiquei com a tarefa de desabilitar / habilitar manualmente cada uma das 9 classes grandes, e então, encontrar pelo menos 2 delas causando o 404, passando por cada função uma a uma e desabilitando / habilitando-as, e em seguida, traçando linha por linha dentro dessas funções - uma força bruta tenta ver exatamente o que estava causando o erro 404, mesmo que eu não soubesse o porquê.

Foi quando descobri que há uma consequência em usar $query->get_queried_object() . Parece que usar essa função de wrapper realmente modifica $ query em si, que eu pensei que estava retornando inalterada no final da minha função. Foram envolvidos três filtros em duas classes que modificaram a consulta: parse_query , posts_orderby , posts_join - e todas as funções de retorno de chamada estavam chamando $query->get_queried_object() no $query arg passado para executar alguns testes condicionais e às vezes modifique a consulta vars (como para casos especiais de ordenação). Estranhamente, essas funções realmente funcionaram bem no que foram projetadas para fazer, apesar do meu uso da função. Eu nunca notei nada de errado com a consulta $ retornada antes!

De alguma forma, depois de mais de um ano de desenvolvimento e uso em dezenas de sites de produção ao vivo, eu nunca havia experimentado nenhum efeito adverso desse erro. Somente quando me aventurei em CPTs hierárquicos, essa pequena diferença de repente quebrou as coisas. Isso é parte do que me jogou tão duro com isso - o melhor que eu poderia dizer, meus filtros de consulta eram confiáveis!

Confesso que ainda não sei exatamente por que chamar essa função quebra apenas um pequeno aspecto das páginas-filhas do CPT - e, no entanto, nunca manifestou nenhum outro problema! Mas ficou claro que usá-lo dentro de um callback de filtro atrapalhava o $query retornado de alguma forma. Ao remover essa chamada, meus erros 404 desapareceram.

Obrigado por todas as dicas - gostaria de poder dividir a recompensa, à medida que eu obtinha informações de cada resposta, mesmo que a solução final fosse um pouco não relacionada. Esta tem sido uma lição educativa para não confiar cegamente em seu código, mesmo que ele esteja trabalhando para você de forma confiável por um longo tempo, ou não esteja produzindo nenhum erro óbvio.

Às vezes, como o gráfico do kaiser incorpora, você só precisa começar a jogar os interruptores até que as luzes voltem. No meu caso, eu tive que levar a mesma estratégia de solução de problemas até as linhas individuais em uma função antes que eu pudesse ver o problema.

    
por somatic 12.01.2013 / 04:36
14

Esta é minha primeira vez participando aqui no Stack Exchange, mas vou dar uma chance e ver se posso ajudar a apontar na direção certa.

Por padrão, os CPTs hierárquicos se comportam exatamente da maneira que você descreveu. O prefixo slug exclusivo, "newsletter" neste caso, é permitir que o mecanismo de reescrita saiba como diferenciar solicitações de diferentes tipos de postagens.

Esses argumentos de CPT parecem corretos, mas quando um CPT é solicitado, o pagename query var não deve ter um valor e o name query var deve ser o mesmo que newsletter aqui, então parece que há um conflito em algum lugar da sua configuração.

Para ajudar a depurar, instalar e ativar o plug-in Rewrite Rules Inspector , visite a tela em " Ferramentas - > Reescrever regras ."

  1. Enquanto observa a lista, todas as regras do CPT devem ser listadas antes de qualquer regra de reescrita da página. Verifique se esse é o caso ao verificar a coluna " Origem ".
  2. Se isso fizer check-out, insira o URL do seu CPT de "primeiro artigo" no campo " Corresponder URL " e clique no botão "Filtrar" para ver qual regra é correspondida. Ele deve corresponder a uma regra de boletim informativo e a uma regra de página, mas a regra do boletim informativo deve ser a primeira.

Se isso não revelar problemas, pesquise a coluna post_name em wp_posts para encontrar outras postagens com o slug "first-article" para ver se pode haver uma colisão. Faça uma busca por "newsletter" também, só para ter certeza.

Adicione o snippet a seguir para inspecionar suas consultas no início da solicitação para verificar e ver quais estão sendo definidas pela correspondência de regra de reconfiguração (visite o CPT filho no front end). Se o pagename var não aparecer aqui, então ele está sendo definido por algo mais tarde na solicitação:

add_filter( 'request', 'se77513_display_query_vars', 1 );

function se77513_display_query_vars( $query_vars ) {
    echo '<pre>' . print_r( $query_vars, true ) . '</pre>';

    return $query_vars;
}

Todos os plugins / funções que modificam a consulta vars podem estar causando um conflito, portanto, desative-os se ainda encontrar problemas. Além disso, libere suas regras de regravação após cada etapa, especialmente se a solicitação corresponder a uma regra errada na segunda etapa acima (mantenha a tela "Permalinks" aberta em uma guia separada e atualize-a).

    
por Brady Vercher 07.01.2013 / 08:15
5

O parent/Child permalink funciona fora da caixa, desde que você defina

'hierarchical'=> true,
'supports' => array('page-attributes' ....

Atualização:

Eu testei novamente e funciona como esperado, com este caso de teste:

add_action('init','test_post_type_wpa77513');
function test_post_type_wpa77513(){
    $args = array(
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => true, 
        'show_in_menu' => true, 
        'query_var' => true,
        'rewrite' => true,
        'capability_type' => 'post',
        'has_archive' => true, 
        'hierarchical' => true,
        'supports' => array( 'title', 'editor', 'thumbnail', 'page-attributes' )
    ); 

    register_post_type( 'newsletter', $args );
}

e permalink definido como /%postname%/ recebo newsletter / pai / filho funcionando bem.

    
por Bainternet 07.01.2013 / 13:45
3

Além de perguntar »Você já tentou desligá-lo e ligá-lo novamente?« , Eu também tenho que perguntar "Você tem algum plug-in ativo e o seu Tema está fazendo alguma coisa nos permalinks (por exemplo: registrando taxonomia, postando tipos, adicionando regras de reescrita, etc.)?

Se assim for: Isso ainda acontece, depois que você desativou todos os plugins e mudou para TwentyEleven?

Paradepuraraindamais,váparaoGitHubepegueo Plug-in "Rewrite" da Toschos . Em seguida, mude para o repositório oficial de plug-ins em wp.org e grave o Plugin MonkeyManRewriteAnalyzer . Eu até escrevi uma pequena extensão para colar um pouco juntos. Isso lhe dará muitos detalhes sobre sua configuração.

    
por kaiser 07.01.2013 / 19:42
-2

Você está executando a versão mais atual do WP? Eu acho que essa é a primeira pergunta (como quando você liga para o suporte técnico e eles perguntam se o seu computador está conectado!), Já que eu li que esse problema foi resolvido na atualização de versão mais atual.

Há uma postagem no digwp.com que aborda esse problema (http://digwp.com/2011/06/dont-use-postname/). Aparentemente, o WP não consegue distinguir facilmente entre posts e páginas, e se você iniciar seus urls com uma opção baseada em texto, o WP aciona um flag que cria uma regra para cada página / post que você tiver. Se você tiver muito conteúdo em seu site, isso pode resultar em um grande número de solicitações e seu servidor provavelmente expirará, o que resultará em um monte de 404s mesmo que as páginas estejam lá.

Se você usar uma estrutura baseada em números primeiro, então sua estrutura baseada em texto, eu aposto que o seu problema 404 seria resolvido. Agora, considerando os problemas de SEO, eu não usaria uma estrutura de datas, mas tomar essa decisão será lógico o suficiente para você.

    
por Melanie Sumner 07.01.2013 / 21:58