I have build a custom post_type with "Work items" in order to enter my personal portfolio items. The "Work items" have taxonomies like "Graphics", "Websites" etc.
I am able to display them all in an archive-work.php template but I want to filter them on page with AJAX. I followed this example : /
I am running into a problem:
- The first time that the page is displayed, nothing gets fetched from my custom post type taxonomies. If I click on one of my links, then the data get successfully updated. The issue is only in the first page load. What I guess is that the nonce isn't verified because it isn't sent with POST so it fails.
Can anyone tell me where have I done a mistake ?
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(); ?>
I have build a custom post_type with "Work items" in order to enter my personal portfolio items. The "Work items" have taxonomies like "Graphics", "Websites" etc.
I am able to display them all in an archive-work.php template but I want to filter them on page with AJAX. I followed this example : http://www.bobz.co/ajax-filter-posts-tag/
I am running into a problem:
- The first time that the page is displayed, nothing gets fetched from my custom post type taxonomies. If I click on one of my links, then the data get successfully updated. The issue is only in the first page load. What I guess is that the nonce isn't verified because it isn't sent with POST so it fails.
Can anyone tell me where have I done a mistake ?
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(); ?>
Share
Improve this question
asked Nov 21, 2014 at 13:34
RadolinoRadolino
1571 gold badge2 silver badges9 bronze badges
1 Answer
Reset to default 5As you guess that's what happening(at least I think).
You should separate your ajax logic from your "first load" logic. You can make a function ie my_get_posts that will be called inside archive-work.php and then inside ajax_filter_get_posts you can call the my_get_posts() function.
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;
}
Also I don't think the following code is needed as wordpress will take care of it.
// If taxonomy is not set, remove key from array and get all posts
if( !$work_item ) {
unset( $args['stuff'] );
}
The code is a draft and could be better but you get the idea. Haven't test it but it should work
EDIT
Don't forget to call wp_reset_postdata();
after every custom WP_Query to restore the global $post variable. More here: http://codex.wordpress/Function_Reference/wp_reset_postdata