如何使用页面上的AJAX过滤帖子数据?

时间:2014-11-21 作者:Radolino

我已经构建了一个带有“工作项”的自定义post\\u类型,以便输入我的个人投资组合项。“工作项”有“图形”、“网站”等分类法。

我能够在存档工作中显示它们。php模板,但我想用AJAX在页面上过滤它们。我遵循以下示例:http://www.bobz.co/ajax-filter-posts-tag/

我遇到了一个问题:

第一次显示页面时,没有从我的自定义帖子类型分类中获取任何内容。如果单击其中一个链接,则数据将成功更新。问题仅出现在第一页加载中。我想,nonce没有得到验证,因为它没有随POST一起发送,所以它失败了

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(); ?>

1 个回复
最合适的回答,由SO网友:Laxmana 整理而成

正如你所猜测的那样(至少我认为是这样)。

您应该将ajax逻辑与“第一次加载”逻辑分开。您可以创建一个函数,即my\\u get\\u posts,它将在归档工作中调用。然后在ajax\\u filter\\u get\\u posts中,可以调用my\\u get\\u posts()函数。

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;
}
此外,我认为不需要以下代码,因为wordpress会处理它。

// If taxonomy is not set, remove key from array and get all posts
          if( !$work_item ) {
            unset( $args[\'stuff\'] );
          }
代码是一个草稿,可能会更好,但你明白了。还没有测试,但应该可以

EDIT

别忘了打电话wp_reset_postdata(); 在每次自定义WP\\U查询后,恢复全局$post变量。更多信息:http://codex.wordpress.org/Function_Reference/wp_reset_postdata

结束

相关推荐

使用ANGLE$http的AJAX请求上的服务器上的空POST数据

我使用AngularJS构建一个AJAX表单,然后在运行Wordpress的服务器上进行处理。服务器端处理程序很简单:function rnr_contact_callback() { $name = $_POST[\'firstName\'] . \' \' . $_POST[\'lastName\']; wp_mail( \'[email protected]\', \'Contact form submitted