J'ai construit un post_type personnalisé avec des "éléments de travail" afin de saisir mes éléments de portefeuille personnels. Les "éléments de travail" ont des taxonomies comme "Graphiques", "Sites Web" etc.
Je peux tous les afficher dans un modèle archive-work.php mais je veux les filtrer sur la page avec AJAX. J'ai suivi cet exemple: http://www.bobz.co/ajax-filter-posts-tag/
Je rencontre un problème:
Quelqu'un peut-il me dire où ai-je commis une erreur?
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(); ?>
Comme vous l'aurez deviné, c'est ce qui se passe (du moins, je pense).
Vous devez séparer votre logique ajax de votre logique de "premier chargement". Vous pouvez créer une fonction, par exemple my_get_posts, qui sera appelée dans archive-work.php, puis dans ajax_filter_get_posts, vous pourrez appeler la fonction my_get_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;
}
De plus, je ne pense pas que le code suivant soit nécessaire car wordpress s'en chargera.
// If taxonomy is not set, remove key from array and get all posts
if( !$work_item ) {
unset( $args['stuff'] );
}
Le code est un brouillon et pourrait être meilleur, mais vous voyez l'idée. Je n'ai pas testé mais ça devrait marcher
EDIT
N'oubliez pas d'appeler wp_reset_postdata();
après chaque WP_Query personnalisé pour restaurer la variable globale $ post. Plus ici: http://codex.wordpress.org/Function_Reference/wp_reset_postdata