it-swarm.com.de

So filtern Sie Post-Daten mit AJAX Auf Seite?

Ich habe einen benutzerdefinierten post_type mit "Arbeitselementen" erstellt, um meine persönlichen Portfolioelemente einzugeben. Die "Workitems" haben Taxonomien wie "Grafiken", "Websites" usw.

Ich kann sie alle in einer archive-work.php-Vorlage anzeigen, aber ich möchte sie auf einer Seite mit AJAX filtern. Ich folgte diesem Beispiel: http://www.bobz.co/ajax-filter-posts-tag/

Ich habe ein Problem:

  • Wenn die Seite zum ersten Mal angezeigt wird, wird nichts von meinen benutzerdefinierten Post-Typ-Taxonomien abgerufen. Wenn ich auf einen meiner Links klicke, werden die Daten erfolgreich aktualisiert. Das Problem tritt nur beim Laden der ersten Seite auf. Was ich denke, ist, dass die Nonce nicht verifiziert wird, weil sie nicht mit POST gesendet wird, so dass es fehlschlägt.

Kann mir jemand sagen, wo ich einen Fehler gemacht habe?

functions.php

function ajax_filter_posts_scripts() {
  // Enqueue script
  wp_register_script('afp_script', get_template_directory_uri() . 
      '/ajax-work-items.js', false, null, false);
  wp_enqueue_script('afp_script');

  wp_localize_script( 'afp_script', 'afp_vars', array(
        'afp_nonce' => wp_create_nonce( 'afp_nonce' ), // Create nonce which we later will use to verify AJAX request
        'afp_ajax_url' => admin_url( 'admin-ajax.php' ),
      )
  );
}
add_action('wp_enqueue_scripts', 'ajax_filter_posts_scripts', 100);

$result = array();

// Script for getting posts
function ajax_filter_get_posts( $work_item ) {

  // Verify nonce
  if( !isset( $_POST['afp_nonce'] ) || 
      !wp_verify_nonce( $_POST['afp_nonce'], 'afp_nonce' ))
    die('Permission denied');

  $work_item = $_POST['stuff'];

  // WP Query
  $args = array(
    'stuff' => $work_item,
    'post_type' => 'work',
    'posts_per_page' => -1,
  );

  // If taxonomy is not set, remove key from array and get all posts
  if( !$work_item ) {
    unset( $args['stuff'] );
  }

  $query = new WP_Query( $args );

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

       $res = '<div class="col-lg-4">'.
                  '<a href="'.get_permalink().'">'.
                      '<article class="panel panel-default" id="post-'.get_the_id().'">'.
                          '<div class="panel-body">'.
                              get_the_post_thumbnail().
                              '<div class="panel-cover">'.
                                  '<h3>'.get_the_title().'</h3>'.
                                      get_the_content().
                              '</div>'.
                          '</div>'.      
                      '</article>'.
                  '</a>' .     
              '</div>';


       $result['response'][] = $res;
       $result['status'] = 'success';

   endwhile;
   else:
       $result['response'] = '<h2>No posts found</h2>';
       $result['status']   = '404';
   endif;

   $result = json_encode($result);
   echo $result;

  die();
}

add_action('wp_ajax_filter_posts', 'ajax_filter_get_posts');
add_action('wp_ajax_nopriv_filter_posts', 'ajax_filter_get_posts');

//Get Work Filters
function get_work_filters()
{
    $work_items = get_terms('stuff');
    $filters_html = false;
    $count = count( $work_items );

    if( $count > 0 ):
        foreach( $work_items as $work_item )
        {
            $work_item_id = $work_item->term_id;
            $work_item_name = $work_item->name;

            $filters_html .= '<a href="' . 
                get_term_link( $work_item ) . 
                '" class="btn work-filter" title="' . 
                $work_item->slug . '">' . $work_item->name . '</a> ';
        }
        echo $filters_html;
    endif;
}

ajax-work-items.js

$(document).ready(function(){

    // work filters

    $('.work-filter').click( function(event) {

        // Prevent default action - opening tag page
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }

        // Get tag slug from title attirbute
        var stuff = $(this).attr('title');        

        data = {
            action: 'filter_posts', // function to execute
            afp_nonce: afp_vars.afp_nonce, // wp_nonce
            post_type: "work", // selected tag
            stuff: stuff,
            };

        $.ajax({ 
            type: "post",
            dataType: "json",
            url: afp_vars.afp_ajax_url, 
            data: data, 
            success: function(data, textStatus, XMLHttpRequest) {
                console.log(data);
                // Restore div visibility
                $('.work-results').fadeOut()
                    .queue(function(n) {
                            $(this).html(data.response);
                            n();
                }).fadeIn();
            },
            error: function( XMLHttpRequest, textStatus, errorThrown ) {
                /*console.log( MLHttpRequest );
                console.log( textStatus );
                console.log( errorThrown );*/
                $('.work-results').fadeOut()
                    .queue(function(n) {
                            $(this).html("No items found. ");
                            n();
                }).fadeIn();
            }
        });
    });

});

archive-work.php

<?php get_header(); ?>

<div id="workwrapper">  
    <div class="row-bg-page">
        <div class="container">
            <div class="jumbotron">
                <h1>Our work</h1>
                <p class="lead">Providing professional ...
                </p>
            </div>
        </div>
    </div>
    <div class="row-bg-white">
        <div class="container">

            <div id="work-filter" class="text-center">
                <?php get_work_filters(); ?>
            </div>
            <br />

            <div class="work-results">
                <?php ajax_filter_get_posts(""); ?>
            </div>

        </div>
    </div>

</div>

<?php get_footer(); ?>
3
Radolino

Wie Sie sich denken, passiert genau das (zumindest denke ich).

Sie sollten Ihre Ajax-Logik von Ihrer "First Load" -Logik trennen. Sie können eine Funktion erstellen, z. B. my_get_posts, die in archive-work.php aufgerufen wird, und dann in ajax_filter_get_posts die Funktion my_get_posts () aufrufen.

archive-work.php

    <div class="work-results">
                    <?php $res = my_get_posts();
                 echo $res['response'];
?>
                </div>

functions.php

    function ajax_filter_get_posts( $work_item ) {

      // Verify nonce
      if( !isset( $_POST['afp_nonce'] ) || 
          !wp_verify_nonce( $_POST['afp_nonce'], 'afp_nonce' ))
        die('Permission denied');

         $work_item = $_POST['stuff'];
         $result = json_encode(my_get_posts($work_item, true));
         echo $result;

         die();

    }

function my_get_posts($work_item = '', $ajax = false){

    // WP Query
      $args = array(
        'stuff' => $work_item,
        'post_type' => 'work',
        'posts_per_page' => -1,
      );

      // If taxonomy is not set, remove key from array and get all posts
      if( !$work_item ) {
        unset( $args['stuff'] );
      }

      $query = new WP_Query( $args );
      $html = '';
      $items = array();

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

           $res = '<div class="col-lg-4">'.
                      '<a href="'.get_permalink().'">'.
                          '<article class="panel panel-default" id="post-'.get_the_id().'">'.
                              '<div class="panel-body">'.
                                  get_the_post_thumbnail().
                                  '<div class="panel-cover">'.
                                      '<h3>'.get_the_title().'</h3>'.
                                          get_the_content().
                                  '</div>'.
                              '</div>'.      
                          '</article>'.
                      '</a>' .     
                  '</div>';


           $ajax ? $items[] = $res : $html .= $res;


       endwhile;

       $result['response'] = $ajax ? $items : $html;
       $result['status'] = 'success';

       else:
           $result['response'] = '<h2>No posts found</h2>';
           $result['status']   = '404';
       endif;
wp_reset_postdata();
return $result;
}

Ich glaube auch nicht, dass der folgende Code benötigt wird, da WordPress sich darum kümmert.

// If taxonomy is not set, remove key from array and get all posts
          if( !$work_item ) {
            unset( $args['stuff'] );
          }

Der Code ist ein Entwurf und könnte besser sein, aber Sie bekommen die Idee. Habe es nicht getestet, aber es sollte funktionieren

EDIT

Vergessen Sie nicht, wp_reset_postdata(); nach jeder benutzerdefinierten WP_Query aufzurufen, um die globale Variable $ post wiederherzustellen. Mehr hier: http://codex.wordpress.org/Function_Reference/wp_reset_postdata

5
Laxmana