Não é possível alternar a postagem consultada no gancho pre_get_posts

Preciso alterar dinamicamente a página que está sendo carregada com base no URL. É um sistema de tradução, e a lesão de uma página é diferente para cada idioma. Os URLs são assim:

/en/best-restaurants-in-tokyo /it/migliori-ristoranti-a-tokyo /fr/meilleurs-restaurants-à-tokyo 

Os slugs são armazenados em uma tabela separada, não em wp_posts ou wp_postmeta . A única maneira que eu encontrei para conseguir isso é modificando o object WP_Query global em pre_get_posts hook. O problema é que não funciona e não entendo o porquê. O WordPress processa index.php vez de single.php como deveria para todas as postagens. Se eu abrir a página pela lingueta original ou por ID (ou seja, ?p=4033 ), tudo funciona bem.

Abaixo está o código que demonstra o problema.

 add_action('pre_get_posts', 'mt_handle_translation_redirect', 9999); function mt_handle_translation_redirect ($query) { global $wpdb; if (!$query->is_main_query()) return; // "1178" is a valid post ID $query->set('page_id', 1178); } 

Se eu abrir qualquer página de publicação (por exemplo, ‘ http: // localhost / wordpress /? P = 1010 ‘), ele redirectá para a página 1178 como esperado. Se eu abrir uma página inicial, não redirectá.

Se adicionarmos add_rewrite_rule ao código, isso não tornará os redirecionamentos corretamente mais, mas, em vez disso, ele tentará renderizar a página inicial:

 add_action('init', 'mt_init'); function mt_init() { add_rewrite_tag('%tr_language%', '([a-z_-]+)' ); add_rewrite_tag('%tr_title%', '([\pL_-]+)' ); add_rewrite_rule('^(fr)/([^/]+)/?', 'index.php?tr_language=$matches[1]&tr_title=$matches[2]', 'top'); flush_rewrite_rules(); } 

Parece que quando eu chamo index.php sem o ID de postagem específico ou uma lesão, não é mais possível redirect para outra página, porque sempre faz uma lista de postagem, como em uma página inicial ou em uma página de categoria.

Como faço URLs personalizados para abrir outra postagem?

Solutions Collecting From Web of "Não é possível alternar a postagem consultada no gancho pre_get_posts"

Hã. Eu verifiquei duas vezes. No meu servidor local, esse bit de código muda com êxito a postagem:

 function test_redirect() { global $wp_query; $wp_query->set('page_id', 5); } add_action('pre_get_posts', 'test_redirect'); 

Você terá que fazer um pouco de debugging. Em um servidor dev, var_dump a variável $ wp_query alguns lugares chave para verificar se ele tem o que você espera.

Uma solução alternativa é ligar a ação parse_query para modificar a consulta anteriormente.

Outra opção é ligar em template_redirect mais tarde e, em seguida, criar um novo object wp_query. Isso geralmente seria preferível se você estivesse mudando a postagem para algo fundamentalmente diferente, em vez de apenas outra tradução, porque eliminará quaisquer outras variables ​​que foram definidas por parse_query anteriormente. Ele vem com a sobrecarga extra de consultar o post duas vezes. Aqui está a idéia geral:

 function redirect_translation() { global $wp_query; // Replace wp_query here... query_posts() should work too. $wp_query = new WP_Query(array('post_id' => 5)); } add_action('template_redirect','redirect_translation'); 

Fazer isso em pré_get_posts causará um loop infinito.

EDITAR: Olhando para o seu código novamente, como o mt_handle_translation_redirect está sendo chamado? Eu suspeito que você não esteja atualizando o object global $ wp_query, razão pela qual a consulta real não está sendo modificada. Verificando o conteúdo de wp_query alguns lugares (como o seu arquivo de modelo) seria um bom começo.