Как сначала отфильтровать посты WordPress по категориям, а затем по тегам, которые принадлежат постам из выбранной категории? - PullRequest
1 голос
/ 20 января 2020

Это мой первый пост здесь, так же как и я новичок, поэтому, пожалуйста, потерпите меня.

Что бы я хотел сделать sh, это создать функцию AJAX, которая будет перечислять все доступные категории в виде флажков, которые пользователь может выбрать. После выбора и нажатия кнопки «Применить» я хотел бы показать список всех тегов (также в форме флажков) из сообщений, которые назначены для выбранной категории / категорий. Затем пользователь может выбрать один из доступных тегов, и после нажатия последней кнопки «Применить» будут показаны соответствующие сообщения.

Как и на TED.com «Что вас интересует?» но в AJAX. Таким образом, первым шагом будут Категории, вторым шагом будут Теги. Затем будут отображаться сообщения, которые относятся к выбранной категории и которым назначены выбранные теги.

Пока что я решил, как составить список всех доступных категорий, но при фильтрации по тегам он выдает список всех тегов, а не тегов. только для выбранной категории. Затем фактические результаты (сообщения) также дублируются. Как фильтровать по тэгам и удалять дубликаты, к сожалению, мне не хватает. Я поместил свою функцию в шорткод, так как использую конструктор блоков, чтобы я мог вставить шорткод в модуль кода и поместить его в любое место на странице.

Моя функция:

Редактировать: (теперь обновлено с ответом Витавса + добавлен код для удаления дублированных результатов)

function filter_articles_shortcode() {

  $siteurl = site_url();
  $form = '<form id="filter2" action=" '. $siteurl .'/wp-admin/admin-ajax.php" method="POST">';
    if( $cats = get_terms(
      array(
        'taxonomy' => 'category',
        'orderby' => 'name'
        )
      )
    ) :
      $form .= '<div>';
      foreach ( $cats as $cat ) :
        $form .= '<input name="cFilter[]" type="checkbox" id="'. $cat->slug .'"  value="'. $cat->term_id .'">';
        $form .= '<label for="'. $cat->slug .'">'. $cat->name .'</label>';
        $form .= '<span>&#40;' . $cat->count . '&#41;</span>';
        $form .= '<br />';
      endforeach;
      $form .= '</div>';
    endif;
  $form .= '<button id="cat-btn">Apply</button>';
  $form .= '<input type="hidden" name="action" value="catFilter">';
  $form .= '</form>';
  $form .= '<div id="results"></div>';
  return $form;

}
add_shortcode('filter-articles', 'filter_articles_shortcode');

add_action('wp_ajax_catFilter', 'show_filter_results');
add_action('wp_ajax_nopriv_catFilter', 'show_filter_results');

//
////
//

function show_filter_results() {

  if( isset( $_POST['cFilter'] ) ) {
    $args['tax_query'] = array(
      array(
        'taxonomy' => 'category',
        'field' => 'id',
        'terms' => $_POST['cFilter']
      )
    );
  }

  $query = new WP_Query( $args );

  if( $query->have_posts() ) :
    while( $query->have_posts() ): $query->the_post();

    $w = the_title('<h3>', '</h3>', true);
    $w .= the_category(', ');
    $w .= the_tags('<div>',', ','</div>');
    $w .= '<hr />';
    echo $w;

  endwhile;
  wp_reset_postdata();
  else :
    echo 'nothing';
  endif;

  $siteurl = site_url();

  $o .= '<form id="filter-tags" action=" '. $siteurl .'/wp-admin/admin-ajax.php" method="POST">';

  $utags = array();

  if( $query->have_posts() ) :
    while( $query->have_posts() ): $query->the_post();

    $tags = get_the_tags();

    if ( !empty($tags) ) {
      foreach( $tags as $tag ) {

        $utag = $tag;

        if(! in_array($utag, $utags)) {

          $utags[] = $utag;

          $o .= '<input name="tFilter[]" type="checkbox" id="tag&#8722;'. $utag->slug .'" value="'. $utag->term_id .'" />';
          $o .= '<label for="tag&#8722;'. $utag->slug .'">'. $utag->name .'</label>';
          $o .= '<span>&#40;' . $utag->count . '&#41;</span>';
          $o .= '<br />';

        }
      }
    }

    endwhile;

  $o .= '<button id="tags-btn">Tags</button>';
  $o .= '<input type="hidden" name="action" value="tagFilter">';

  foreach ($_POST['cFilter'] as $cfilter) {
    $o .= '<input type="hidden" name="cFilter[]" value="' .  esc_attr($cfilter) . '">';
  }
  wp_reset_postdata();
  else :
    echo 'nothing';
  endif;

  $o .= '</form>';
  $o .= '<div id="tag-results"></div>';
  echo $o;

  echo "<script>
    jQuery(function($){
      $('#filter-tags').submit(function() {
        var tags = $('#filter-tags');
        $.ajax({
          url:tags.attr('action'),
          data:tags.serialize(),
          type:tags.attr('method'),
          beforeSend:function(xhr){
            tags.find('#tags-btn').text('Searching...');
          },
          success:function(data){
            tags.find('#tags-btn').text('Tag');
            $('#tag-results').html(data);
          }
        });
        return false;
      });

    });
    </script>";

  die();

}

add_action('wp_ajax_tagFilter', 'show_tags_results'); 
add_action('wp_ajax_nopriv_tagFilter', 'show_tags_results');

//
////
//

function show_tags_results() {

  if( isset( $_POST['tFilter'] ) ) {
    $args2['tax_query'] = array(
      'relation' => 'AND',
      array(
          'taxonomy' => 'category',
          'field' => 'id',
          'terms' => $_POST['cFilter'],
          'include_children' => false
      ),
      array(
          'taxonomy' => 'post_tag',
          'field' => 'id',
          'terms' => $_POST['tFilter'],
      )
    );
  }

  $query = new WP_Query( $args2 );

  if( $query->have_posts() ) :
    while( $query->have_posts() ): $query->the_post();

    $e = the_title('<h3>', '</h3>', true);
    $e .= the_category(', ');
    $e .= the_tags('<div>',', ','</div>');
    $e .= '<hr />';
    echo $e;

  endwhile;
  wp_reset_postdata();
  else :
    echo 'nothing';
  endif;

  die();

}

AJAX:

jQuery(document).ready(function($){
    $('#filter2').submit(function(){
        var filter2 = $('#filter2');
        $.ajax({
            url:filter2.attr('action'),
            data:filter2.serialize(), // form data
            type:filter2.attr('method'), // POST
            beforeSend:function(xhr){
                filter2.find('#cat-btn').text('Searching...');
            },
            success:function(data){
                filter2.find('#cat-btn').text('Apply'); // changing the button label back
                $('#results').html(data); // insert data
            }
        });
        return false;
    });

});

На заметку - в идеале я Я хотел бы удалить кнопки «Применить» и вместо этого автоматически показывать данные через AJAX. Другими словами: выберите категорию (и) и сразу же покажите все теги, затем выберите тег (ы) и сразу же покажите все сообщения.

Любая помощь будет оценена и спасибо за ваше время.

1 Ответ

0 голосов
/ 20 января 2020

Вам нужны некоторые изменения в вашем коде. Во-первых, форма списка тегов должна повторно передать значение cFilter, поэтому в show_filter_results() добавьте этот код до / после поля скрытого действия.

foreach ($_POST['cFilter'] as $cfilter) {
    $o .= '<input type="hidden" name="cFilter[]" value="' .  esc_attr($cfilter) . '">';
}

Затем в show_tags_results() измените tax_query на это

$args2['tax_query'] = array(
    'relation' => 'AND',
    array(
        'taxonomy' => 'category',
        'field' => 'id',
        'terms' => $_POST['cFilter'],
        'include_children' => false
    ),
    array(
        'taxonomy' => 'post_tag',
        'field' => 'id',
        'terms' => $_POST['tFilter'],
    )
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...