I posted a similar question about this before but I changed a bit of the code so I figured I'd start a new topic. Below is the setup I currently have to load single posts on the front page.

This is what I'm trying to do. Notice that when you click a post, it loads in a hidden container.

Can someone help me figure this out?


<div id="primary" class="content-area">
    <main id="main" class="site-main" role="main">

        <div id="project-container">
            <img id="loading-animation" src="http://i.imgur.com/5RMfW8P.gif" style="display:none">

        <!-- Start the loop -->
        <?php $home_query = new WP_Query('post_type=projects');

        while($home_query->have_posts()) : $home_query->the_post(); ?>

            <a class="post-link" href="#" rel="<?php the_ID(); ?>">
                <article id="post-<?php the_ID(); ?>">
                    <div class="post-info">
                        <h1 class="entry-title"><?php the_title(); ?></h1>
                    <?php the_post_thumbnail( "home-thumb", array( 'class' => 'grayscale grayscale-fade') ); ?>
                </article><!-- #post-## -->

        <?php endwhile; ?>
        <?php wp_reset_postdata(); // reset the query ?>

    </main><!-- #main -->
</div><!-- #primary -->


 * Enqueue scripts and styles.
function starter_scripts() {
    wp_deregister_script( 'jquery' );
    wp_register_script( 'jquery', includes_url( '/js/jquery/jquery.js' ), false, NULL, true );
    wp_enqueue_script( 'jquery' );
    wp_enqueue_script( 'jquery-effects-core');

    wp_enqueue_style( 'starter-style', get_stylesheet_uri() );
    wp_enqueue_script( 'gray', get_template_directory_uri() . '/js/min/jquery.gray.min.js', array('jquery'), '', true );
    wp_enqueue_script( 'includes', get_template_directory_uri() . '/js/min/includes.min.js', array('jquery'), '', true );
    wp_localize_script( 'includes', 'site', array(
                'theme_path' => get_template_directory_uri(),
                'ajaxurl'    => admin_url('admin-ajax.php')
add_action( 'wp_enqueue_scripts', 'starter_scripts' );

 * Return the post content to the AJAX call
function my_load_ajax_content () {
    $args = array( 'p' => $_POST['post_id'] );
    $post_query = new WP_Query( $args );
    while( $post_query->have_posts() ) : $post_query->the_post(); ?>

    <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
        <h2><a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr( 'Permalink to %s' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h2>
        <div class="entry-content">
            <?php the_content(); ?>
        </div> <!-- end .entry-content -->

add_action ( 'wp_ajax_nopriv_load-content', 'my_load_ajax_content' );
add_action ( 'wp_ajax_load-content', 'my_load_ajax_content' );


// Load posts via AJAX
$(".post-link").click(function(e) {


    var post_id = $(this).attr('rel');
    var ajaxURL = site.ajaxurl;

        type: 'POST',
        url: ajaxURL,
        data: {"action": "load-content", post_id: post_id },
        success: function(response) {
        return false;


<?php while ( have_posts() ) : the_post(); ?>

<div class="post-container">

    <?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>

    <?php the_content(); ?>

</div><!-- #post-## -->

    <?php starter_post_nav(); ?>

<?php endwhile; // end of the loop. ?>

The difference between the code you linked and your version, is that your post link has the permalink as the href value, where the original has just a hash. When you add a click handler to an anchor tag, it doesn't prevent what normally occurs when you click that link, it just executes the javascript and normal link behavior continues as it otherwise would. If you want to prevent links from being followed on a click event, you have to explicitly prevent that in your javascript:

$(".post-link").click(function(event) {
    // the rest of your code... 
|improve this answer|||||
  • Thank you. I replaced the href with a # (because adding in event.preventDefault(); wasn't working) and now the posts look like they are loading on the same page. However, the content that loads in #project-container is not what is defined in my single.php template. The loaded content only shows the content and not the title. I edited my original post to include my single template and also updated the front-page.php template to include the hashtag. What could be causing this? – Desi Jan 8 '15 at 21:44
  • event.preventDefault() probably wasn't working because you didn't pass event to the function (notice event appears twice in the code I posted). your ajax function doesn't load the single.php template, so that's not unexpected, it just gets the post and returns the content. see this answer for an example of querying a post via ajax and loading a template file to output it. your single.php file will need the loop as well. – Milo Jan 8 '15 at 21:59
  • I went ahead and tried to query the post via Ajax. It looks to be correct in my eyes, but I'm not sure why it's still not working. What happens now is when I click on the .post-link, the loading animation shows briefly, disappears, and then no content shows up. Do you think you can take a look and see if you notice anything that looks off? I updated all of the files in the original post. – Desi Jan 9 '15 at 16:19
  • your ajax function tries to use id, but your javascript passes post_id – Milo Jan 9 '15 at 17:04
  • I tried replacing $_POST['id'] in the Ajax function with $post_id but the content still isn't showing up. I'm still a beginner with coding so excuse me if I'm missing something obvious or doing something completely wrong. – Desi Jan 9 '15 at 17:11

To load your single.php template, first you need to move your functions.php code

<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
   <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
   <div class="entry-content">
     <?php the_content(); ?>

Place the above code into single.php. Make sure you replace everything, because single.php has a while loop, but we already doing a loop in the functions.php.

And in place of the above code add get_template_part('single'); to your functions.php between the while loop.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.