I’m loading single posts via Ajax into a div that I have set up on my index page. Everything is working fine in this regard. I want to use history.js to push/pop the state so if users enter example.com/my-post
into the address bar, it loads up the index page with the post already loaded in the div. That is where the problem lies.
This is a simplified version of the function I’m using (the actual also includes a slide):
function my_load_ajax_content () {
$args = array(
'p' => $_POST['post_id'],
'post_type' => 'projects'
);
$post_query = new WP_Query( $args );
while( $post_query->have_posts() ) : $post_query->the_post(); ?>
<div class="post-container">
<div id="project-content">
<?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
<?php the_content(); ?>
</div>
</div><!-- .post-container -->
<?php
endwhile;
wp_die();
}
add_action ( 'wp_ajax_nopriv_load-content', 'my_load_ajax_content' );
add_action ( 'wp_ajax_load-content', 'my_load_ajax_content' );
This is how I’m calling it:
$('.post-link').on('click', function(e) {
e.preventDefault();
var post_id = $(this).data('id'), // data-id attribute for .post-link
projectTitle = $(this).data('title'), // data-title attribute for .post-link
projectSlug = $(this).data('slug'), // data-slug attribute for .post-link
ajaxURL = site.ajaxurl; // Ajax URL localized from functions.php
$.ajax({
type: 'POST',
url: ajaxURL,
context: this,
data: {'action': 'load-content', post_id: post_id },
success: function(response) {
$('#project-container').html(response);
return false;
}
});
});
Here is the loop
<?php $home_query = new WP_Query('post_type=projects');
while($home_query->have_posts()) : $home_query->the_post(); ?>
<article class="project">
<?php the_post_thumbnail( 'home-thumb' ); ?>
<div class="overlay">
<a class="post-link expand" href="https://wordpress.stackexchange.com/questions/175865/<?php the_permalink(); ?>" data-id="<?php the_ID(); ?>" data-title="<?php the_title(); ?>" data-slug="<?php global $post; echo $post->post_name; ?>">+</a>
</div>
</article>
<?php endwhile; ?>
<?php wp_reset_postdata(); // reset the query ?>
I’m wondering if I’m going about this the wrong way. I’m confused and a part of me is thinking that I should put all the html into my single
template and call that from the Ajax function. But then I don’t exactly know how that would work either because if the user enters example.com/my-post
into their browser, it’ll only load the single post without all of the html on the index page. I hope I’m explaining this correctly. Can someone show me how it’s done?
1 Answer
Here is my view: Load it inside your single.php why use ajax at all?
Google wont be able to see this (using most crawlers).
In any case – here is the right way to return the data…
please note that you can use get_post or wp_query. up tp you.
JS Part:
jQuery(document).ready(function($) {
$.post(ajax_object.ajaxurl, {
action: 'my_load_ajax_content ',
post_id: post_id // << should grab this from input...
}, function(data) {
var $response = $(data);
var postdata = $response.filter('#postdata').html();
$('.TARGETDIV').html(postdata);
});
});
PHP Part:
function my_load_ajax_content () {
$pid = intval($_POST['post_id']);
$the_query = new WP_Query(array('p' => $pid));
if ($the_query->have_posts()) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
$data="
<div class="post-container">
<div id="project-content">
<h1 class="entry-title">".get_the_title().'</h1>
<div class="entry-content">'.get_the_content().'</div>
</div>
</div>
';
}
}
else {
echo '<div id="postdata">'.__('Didnt find anything', THEME_NAME).'</div>';
}
wp_reset_postdata();
echo '<div id="postdata">'.$data.'</div>';
}
add_action ( 'wp_ajax_nopriv_load-content', 'my_load_ajax_content' );
add_action ( 'wp_ajax_load-content', 'my_load_ajax_content' );
Hope this helps.
again, i wouldnt recommend doing that but… this should work.
REVISION FOR GET POST ON CLICK
first: the button / link – should be something like
<button class="get_project" data-postid="POSTID HERE!">PROJECT NAME</button>
second: the js code listening to a click:
jQuery(function($){
$('.get_project').click(function() {
var postid = $(this).attr('data-postid');
$.post(ajax_object.ajaxurl, {
action: 'my_load_ajax_content ',
postid: postid
}, function(data) {
var $response = $(data);
var postdata = $response.filter('#postdata').html();
$('.TARGETDIV').html(postdata);
});
})
});
The php code needs no changing – just set the data you need.