'Ajax Loaded Content - Deeplinking URLs
On my WordPress website I have a custom page template containing a post grid (showing the titles only) and on click on the title it is loading the whole content of the post into a div without reloading the page with the help of AJAX. Using history popstate the user can also navigate back.
The issue I'm facing now is:
If you go directly to the single post page using the permalink /single-post/ the single.php template is called. I need to prevent this behaviour, because I want to have everything on my one pager template only. If a user accesses the post like /single-post/ directly, the homepage should be shown (instead of the single page) with the proper loaded ajax content.
How can I achieve this?
This is the current code:
Template File:
$args = array(
'posts_per_page' => -1
);
$blog_query = new WP_Query( $args );
?>
<div class="post-wrapper">
<div class="post-container">
<?php
if( $blog_query->have_posts() ){
while( $blog_query->have_posts() ){ $blog_query->the_post(); ?>
<div class="post-content">
<a class="post-link" title="<?php the_title(); ?>" rel="<?php the_ID(); ?>" href="<?php the_permalink(); ?>"><?php the_title(); ?> </a>
</div>
<?php }
} else { ?>
<div class="post-content">
<h3>No Items found</h3>
</div>
<?php }
wp_reset_postdata(); ?>
</div>
<div id="single-post-container"></div>
</div>
AJAX Call:
// Load posts via AJAX
(function($, D) {
$.ajaxSetup({
cache: false
});
$(".post-link").click(function(e) {
e.preventDefault();
var url = jQuery(this).attr('href'),
title = jQuery(this).attr('title')
;
document.title = title;
history.pushState({url:url,title:title}, title, url );
var postID = $(this).attr('rel');
var $container = $("#single-post-container");
$container.html("content loading");
$.get(D.ajaxurl, {
action: 'load-single-post',
pID: postID
}, function(content) {
$container.html(content);
});
});
//BACK BUTTON FUNCTIONALITY
$(window).on('popstate', function (e) {
var state = e.originalEvent.state;
if (state !== null) {
document.title = state.title;
load(state.url);
} else {
document.title = 'Test Seite';
$("#single-post-container").empty();
}
});
})(jQuery, site);
functions.php:
function mysite_enqueue() {
wp_enqueue_script( 'includes', get_stylesheet_directory_uri() . '/js/includes.js', array('jquery'), '', true );
wp_localize_script( 'includes', 'site', array(
'theme_path' => get_stylesheet_directory_uri(),
'ajaxurl' => admin_url('admin-ajax.php')
)
);
}
add_action( 'wp_enqueue_scripts', 'mysite_enqueue' );
/**
* AJAX nopriv
*/
add_action('wp_ajax_load-single-post', 'prefix_ajax_single_post');
add_action('wp_ajax_nopriv_load-single-post', 'prefix_ajax_single_post');
function prefix_ajax_single_post() {
$pid = (int) filter_input(INPUT_GET, 'pID', FILTER_SANITIZE_NUMBER_INT);
if ($pid > 0) {
global $post;
$post = get_post($pid);
setup_postdata($post);
printf('<div id="single-post post-%d">', $pid);
the_title();
the_content();
echo '</div>';
}
exit();
}
Solution 1:[1]
In your AJAX callback create a document object with the returned page and then parse the piece you want to load into the container:
// Load posts via AJAX
(function($, D) {
$.ajaxSetup({
cache: false
});
$(".post-link").click(function(e) {
e.preventDefault();
var url = jQuery(this).attr('href'),
title = jQuery(this).attr('title')
;
document.title = title;
history.pushState({url:url,title:title}, title, url );
var postID = $(this).attr('rel');
var $container = $("#single-post-container");
$container.html("content loading");
$.get(D.ajaxurl, {
action: 'load-single-post',
pID: postID
}, function(content) {
let doc = document.implementation.createHTMLDocument("New Document");
doc.body.parentElement.innerHTML = content;
const elements = doc.getElementsByClassName('post-container');
const requiredElement = elements[0];
$container.html(requiredElement);
});
});
//BACK BUTTON FUNCTIONALITY
$(window).on('popstate', function (e) {
var state = e.originalEvent.state;
if (state !== null) {
document.title = state.title;
load(state.url);
} else {
document.title = 'Test Seite';
$("#single-post-container").empty();
}
});
})(jQuery, site);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Mifo |
