Skip to content

Instantly share code, notes, and snippets.

@alisspers
Created September 5, 2013 19:03
Show Gist options
  • Save alisspers/6454600 to your computer and use it in GitHub Desktop.
Save alisspers/6454600 to your computer and use it in GitHub Desktop.
Using the Heartbeat API that shipped with WordPress 3.6, this sample plugin shows you how you can have your post list update for your visitors in real time when a new post is published. This code should be seen as inspiration, as it needs to be modified to work with the theme you're currently using.
<?php
/**
* Sample theme index.php to be used with WG Posts Autoreload
*/
get_header();
if ( have_posts() )
{
echo '<div id="posts">';
while ( have_posts() )
{
if ( ! isset( $last_date ) )
$last_date = get_the_time( 'Y-m-d H:i:s' );
the_post();
?>
<article>
<h1><?php the_title(); ?></h1>
<?php the_content(); ?>
</article>
<?php
}
echo '</div>';
}
?>
<script type="text/javascript">
var wg_latest_post_date = '<?php echo $last_date ?>';
</script>
<?php get_footer(); ?>
!function ($, doc)
{
$(doc).ready(function ()
{
// Set the interval to 5 secs, for debugging
wp.heartbeat.interval('fast');
// Tell the server when our latest post was published
$(doc).on('heartbeat-send', function(e, data)
{
data['wg-posts-autoreload'] = wg_latest_post_date;
});
$(doc).on('heartbeat-tick.wg-posts-autoreload', function(event, data)
{
if (!data.hasOwnProperty('wg-posts-autoreload'))
return;
// OK, we got posts back. Let's add them to the list.
$.each(data['wg-posts-autoreload'], function (index, post)
{
// This code is quite dumb.
// This is where you create a new post DOM element
// and inject it into your post list
$('<article />')
.append($('<h1 />').html(post['title']))
.append(post['content'])
.hide()
.prependTo($('#posts'))
.slideDown();
// Update the variable that we send to the server
wg_latest_post_date = post['date'];
});
});
});
}(jQuery, document);
<?php
/*
Plugin Name: WG Posts Autoreload
Description: An example plugin showing how you can utilize the Heartbeat API of WordPress 3.6 to have your post list automatically updated when a new post is published.
Version: 0.1
Author: Anders Lisspers, Webbgaraget
Author URI: http://www.webbgaraget.se
License: Use the code as you please
*/
add_action(
'plugins_loaded',
array( WG_Posts_Autoreload::get_instance(), 'plugin_setup' )
);
/**
* Plugin demonstrating the use of Heartbeat API for
* autoreloading your posts list when a new post arrives
*
*/
class WG_Posts_Autoreload
{
/**
* Singleton instance
*
* @see get_instance()
* @type WG_Posts_Autoreload
*/
protected static $instance = null;
/**
* URL to this plugin's directory.
*
* @type string
*/
public $plugin_url = '';
/**
* Get the instance of this class
*
* @return WG_Posts_Autoreload
*/
public static function get_instance()
{
null === self::$instance and self::$instance = new self;
return self::$instance;
}
/**
* Constructor intentionally left blank
*
* @see plugin_setup()
*/
public function __construct() {}
/**
* Sets our plugin up
* @wp-hook plugins_loaded
*/
public function plugin_setup()
{
$this->plugin_url = plugins_url( '/', __FILE__ );
// On heartbeat from client
add_action( 'heartbeat_received', array( $this, 'add_new_posts_to_heartbeat_response' ), 10, 2 );
add_action( 'heartbeat_nopriv_received', array( $this, 'add_new_posts_to_heartbeat_response' ), 10, 2 );
// Enqueue our JavaScript
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
}
/**
* Enqueues our script
* @wp-hook wp_enqueue_scripts
*/
public function enqueue_scripts()
{
wp_enqueue_script(
'wg-posts-autoreload',
$this->plugin_url . 'wg-posts-autoreload.js',
array( 'heartbeat', 'jquery' ), // We need both heartbeat and jQuery
false,
true // Output in the footer
);
}
/**
* Check if there are any new posts and if so,
* add them to the heartbeat response
*
* @wp-hook heartbeat[_nopriv]_received
* @param array $response The data being sent to the client
* @param array $data The data received from the client
* @return array
*/
public function add_new_posts_to_heartbeat_response( $response, $data )
{
if ( ! isset( $data['wg-posts-autoreload'] ) )
return $response; // No client of ours has requested new posts
$posts = $this->get_posts_since_date( $data['wg-posts-autoreload'] );
if ( count( $posts ) === 0 )
return $response; // There were no new posts
$new_posts_response = array();
foreach ( $posts as $post )
{
// This is the data being sent back to the client.
// The following code needs to be updated, along with the
// JavaScript receiving it, to match your theme's post list data.
$new_posts_response[] = array(
'title' => apply_filters( 'the_title', $post->post_title ),
'content' => apply_filters( 'the_content', $post->post_content ),
'date' => get_the_time( 'Y-m-d H:i:s', $post->ID ),
'permalink' => get_permalink( $post->ID ),
);
}
// Return our data
$response['wg-posts-autoreload'] = $new_posts_response;
return $response;
}
/**
* Gets all posts that were published since the given date
* @param string $date Date on the format Y-m-d H:i:s
* @return array
*/
public function get_posts_since_date( $date )
{
// Filter the query to only grab posts newer than the specified date
$since_date = create_function( '$where', 'return $where .= " AND post_date > \'' . $date . '\'";' );
add_filter( 'posts_where', $since_date );
$posts = get_posts( array( 'suppress_filters' => false ) );
remove_filter( 'posts_where', $since_date );
return $posts;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment