user3782713 user3782713 - 3 months ago 29
Ajax Question

Load Wordpress post without get_header() and get_footer()

I'm developing a wordpress site where the posts are loaded in a popup with ajax (with Magnific Popup). The posts are using the template

single.php
.

This works fine, except that the header and footer are also loaded in the popup (html tags, navigation, scripts, …). I can of course delete
get_header()
and
get_footer()
from the template, but then the single post pages aren't loaded correctly via permalinks.

I tried conditional tags, but when the template is loaded with Ajax, it doesn't 'see' it's loaded on the homepage.

I think working with different templates is an option, although I have seen sites that work with the same template (like the Zoo theme on themeforest). But I couldn't figure out how it works there.

So I'm stuck here. Anybody?

Answer

The clean solution would be to use the WordPress AJAX functions.

Themes are nowadays usually split in multiple parts to reuse blocks in various places. For example, the theme twentysixteen uses get_template_part( 'template-parts/content', 'single' ); in the single.php to include the template file that shows the actual content of the file. You can use this easily to get the content of your post without header, footer etc.

First, set up the PHP part, you can just add this in the functions.php of your theme or directly in your plugin, dependant on what you are developing.

<?php 
// for the admin area
add_action( 'wp_ajax_my_action', 'my_action_callback' );
// for the public area
add_action( 'wp_ajax_nopriv_my_action', 'my_action_callback' );

function my_action_callback() {

    $postid = intval( $_POST['postid'] );
    $post = get_post( $postid );
    setup_postdata( $post );
    get_template_part( 'template-parts/content', 'single' );

    wp_die(); // this is required to terminate immediately and return a proper response
}

The corresponding JavaScript part:

var data = {
    'action': 'my_action',
    'postid': 1234
};

// since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
// on the frontend you have to set it yourself
var ajaxurl = '<?=admin_url( 'admin-ajax.php' )?>';
jQuery.post(ajaxurl, data, function(response) {
    // alert('Got this from the server: ' + response);
    // response will now contain your post, without header, footer, sidebars etc.
});

my_action is the identifyer for the whole process and has to be consistent between the two parts.

Documentation for WordPress AJAX support: https://codex.wordpress.org/AJAX_in_Plugins

Comments