Filtrar next_post_link () e previous_post_link () por meta_key?

8

Eu tenho uma página com duas seções, cada uma usa uma diferente WP_Query()para puxar events, que são um tipo de postagem personalizada. Cada WP_Query()uma consulta meta_keya data do evento para que a Seção 1 exiba apenas os próximos eventse a Seção 2 exiba events.

Os próximos itens eventsda Seção 1 exibem todas as informações relevantes na minha página, portanto, não é possível clicar nelas.

O passado eventsna Seção 2 exibe apenas o eventtítulo e é clicável. Quando os usuários clicam em um passado, eventeles vinculam a um single-event.phpmodelo personalizado do passado event.

Quero exibir a navegação Anterior / Próxima no single-event.phpmodelo, mas a navegação deve apontar apenas para o passado events.

Eu tentei usar next_post_link()e previous_post_link()mas estes vão ligar para as próximas eventstambém, o que eu não quero. Provavelmente, posso configurar um novo WP_Query()no meu single-event.phpe fazer um loop para obter os IDs Anterior / Próximo, mas repetir a consulta parece uma etapa drástica.

Eu realmente aprecio algumas dicas sobre como filtrar os próximos eventslinks dos meus posts anteriores / próximos. Eu já vi essa pergunta, mas prefiro não usar um plugin.

cfx
fonte
1
a resposta para isso é sugerida na outra resposta para a pergunta que você vinculou - você precisará filtrar as cláusulas join / where / sort na get_adjacent_postfunção.
Milo
Sim, isso é sugerido. Eu realmente adoraria ver um exemplo de trabalho, se possível.
cfx 27/03
1
Não tenho tempo para codificar algo no momento, mas um bom ponto de partida seria realizar uma consulta por meio de WP_Query, em seguida $your_query_object->request, inspecionar , o que revelará uma boa parte do SQL necessário para executá-lo.
Milo
Obrigado pela dica @Milo, acho que descobri! Ver abaixo!
cfx 27/03

Respostas:

6

Consegui fazer isso funcionar usando apenas filtros do WordPress, graças à dica de @ Milo.

Observe que estes são bastante específicos para o meu caso, mas você não deve ter problemas para modificá-los para seu próprio uso. Estou usando campos personalizados avançados com um campo Seletor de datas chamado datee os links Anterior / Próximo apontam apenas para eventos com datecampos definidos para qualquer dia antes de hoje.

Eu criei 5 filtros:

  • 1 para modificar JOIN(para adicionar wp_postmeta)
  • 1 para modificar WHEREpara o link anterior
  • 1 para modificar WHEREpara o link Avançar
  • 1 para modificar SORTpara o link anterior
  • 1 para modificar SORTpara o link Avançar

Aqui está o que eu criei, parece estar funcionando, mas se alguém detectar algum problema, eu adoraria comentários:

function get_adjacent_past_events_join($join) {
  if(is_singular('event')) {
    global $wpdb;
    $new_join = $join."INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id ";
    return $new_join;
  }
  return $join;
}
add_filter('get_previous_post_join', 'get_adjacent_past_events_join');
add_filter('get_next_post_join', 'get_adjacent_past_events_join');

function get_prev_past_events_where($where) {
  if(is_singular('event')) {
    global $wpdb, $post;
    $id = $post->ID;
    $current_event_date = get_field('date', $id);
    $today = date('Ymd');
    $new_where = "WHERE p.post_type = 'event' AND p.post_status = 'publish' AND (m.meta_key = 'date' AND (m.meta_key = 'date' AND CAST(m.meta_value AS CHAR) < '$today')) AND (m.meta_key = 'date' AND (m.meta_key = 'date' AND CAST(m.meta_value AS CHAR) < '$current_event_date'))";
    return $new_where;
  }
  return $where;
}
add_filter('get_previous_post_where', 'get_prev_past_events_where');

function get_next_past_events_where($where) {
  if(is_singular('event')) {
    global $wpdb, $post;
    $id = $post->ID;
    $current_event_date = get_field('date', $id);
    $today = date('Ymd');
    $new_where = "WHERE p.post_type = 'event' AND p.post_status = 'publish' AND (m.meta_key = 'date' AND (m.meta_key = 'date' AND CAST(m.meta_value AS CHAR) < '$today')) AND (m.meta_key = 'date' AND (m.meta_key = 'date' AND CAST(m.meta_value AS CHAR) > '$current_event_date'))";
    return $new_where;
  }
  return $where;
}
add_filter('get_next_post_where', 'get_next_past_events_where');

function get_prev_past_events_sort($sort) {
  if(is_singular('event')) {
    global $wpdb;
    $new_sort = " GROUP BY p.ID ORDER BY m.meta_value+0 DESC";
    return $new_sort;
  }
  return $sort;
}
add_filter('get_previous_post_sort', 'get_prev_past_events_sort');

function get_next_past_events_sort($sort) {
  if(is_singular('event')) {
    global $wpdb;
    $new_sort = " GROUP BY p.ID ORDER BY m.meta_value+0 ASC";
    return $new_sort;
  }
  return $sort;
}
add_filter('get_next_post_sort', 'get_next_past_events_sort');
cfx
fonte
3

Eu tive um problema bastante semelhante, necessário para classificar e excluir várias postagens da navegação anterior / seguinte. O problema com a solução do @ cfx era: não é capaz de ajax: a is_singular()função retorna false, se você carregar o conteúdo via wp-ajax. portanto, funcionou no carregamento da página, mas não quando o conteúdo foi alterado pelo ajax. global $post;estava me ajudando aqui.

aqui está a minha solução:

/**
  * WP: join postmeta to our sql query, so we can filter for custom fields
  *
  * @param $join
  * @return string
  */
function jnz_adjacent_work_join( $join ) {
  global $post;
  if ( get_post_type( $post ) == 'work' ) {
    global $wpdb;
    return $join . "INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id ";
  }
  return $join;
}
add_filter('get_previous_post_join', 'jnz_adjacent_work_join');
add_filter('get_next_post_join', 'jnz_adjacent_work_join');



/**
 * WP: Change order of post for prev / next navigation
  * exclude posts with custom field "not_clickable" set to true
  *
  * @param $where
  * @param $operator
  * @return string|void
  */
 function jnz_adjacent_work_where( $where, $operator ) {
   global $post;
   if ( get_post_type( $post ) == 'work' ) :
     global $wpdb;
     $where = $wpdb->prepare("WHERE p.post_title {$operator} '%s' AND p.post_type = 'work' AND p.post_status = 'publish' AND (m.meta_key = 'not_clickable' AND (m.meta_key = 'not_clickable' AND m.meta_value != 1))", $post->post_title );
   endif;

   return $where;
 }

 $gt = '<';
 $lt = '>';
 add_filter( 'get_next_post_where', function( $where ) use ( $lt ) {
   return jnz_adjacent_work_where( $where, $lt );
 });
 add_filter( 'get_previous_post_where', function( $where ) use ( $gt ) {
   return jnz_adjacent_work_where( $where, $gt );
 });

nesse caso, a consulta do campo de costum é: excluir todas as postagens que tenham cf not_clickabledefinido como true.

outro problema que encontrei: criei algum conteúdo e depois implementei esse campo personalizado. Portanto, a consulta também excluiu as postagens que nem tinham esse campo anexado à postagem, independentemente de verdadeiro ou falso. basta ter isso em mente ao usar esse tipo de filtragem. verifique se todas as postagens têm um valor ou considere isso na sua sintaxe sql.

honk31
fonte