Skip to content

Instantly share code, notes, and snippets.

@krystyna93
Last active June 10, 2023 13:13
Show Gist options
  • Save krystyna93/75a05c4863f167879010314b3c8c01f0 to your computer and use it in GitHub Desktop.
Save krystyna93/75a05c4863f167879010314b3c8c01f0 to your computer and use it in GitHub Desktop.
Recent Posts Widget w/ajax Refresh
<?php
class Recent_Posts_Widget extends WP_Widget {
/**
* Register widget with WordPress.
*/
function __construct() {
parent::__construct(
'recent_posts_widget', // Base ID
__( 'Recent Posts Widget', 'text_domain' ), // Name
array( 'description' => __( 'A widget that displays recent posts in a dropdown list and loads them dynamically using AJAX.', 'text_domain' ), ) // Args
);
add_action( 'wp_ajax_recent_posts_widget', array( $this, 'ajax_callback' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
}
/**
* Front-end display of widget.
*/
public function widget( $args, $instance ) {
// Check if there is a cached output.
$cache_key = $this->get_cache_key();
$cached_output = wp_cache_get( $cache_key, 'widget' );
if ( ! empty( $cached_output ) ) {
echo $cached_output;
return;
}
// Build the output.
$output = '';
$title = apply_filters( 'widget_title', $instance['title'] );
// Start the output buffer.
ob_start();
// Get the recent posts.
$recent_posts = get_posts( array(
'posts_per_page' => 10,
'orderby' => 'date',
'order' => 'DESC',
) );
// Create the dropdown list.
?>
<div class="recent-posts-widget">
<?php if ( ! empty( $title ) ) : ?>
<h3><?php echo esc_html( $title ); ?></h3>
<?php endif; ?>
<?php if ( ! empty( $recent_posts ) ) : ?>
<form id="recent-posts-form" action="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>" method="post">
<?php wp_nonce_field( 'recent_posts_widget', 'recent_posts_widget_nonce' ); ?>
<label for="recent-post-select"><?php _e( 'Select a post:', 'text_domain' ); ?></label>
<select name="recent_post_select" id="recent-post-select">
<?php foreach ( $recent_posts as $post ) : ?>
<option value="<?php echo esc_attr( $post->ID ); ?>"><?php echo esc_html( get_the_title( $post->ID ) ); ?></option>
<?php endforeach; ?>
</select>
<input type="submit" value="<?php _e( 'View Post', 'text_domain' ); ?>">
</form>
<div id="recent-post-content"></div>
<?php endif; ?>
</div>
<?php
// End the output buffer and store the output in a variable.
$output = ob_get_clean();
// Add the output to the cache.
wp_cache_set( $cache_key, $output, 'widget' );
// Print the output.
echo $output;
}
/**
* Back-end widget form.
*/
public function form( $instance ) {
$title = ! empty( $instance['title'] ) ? $instance['title'] : __( 'Recent Posts', 'text_domain' );
?>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
</p>
<?php
}
/**
* Sanitize widget form values as they are saved.
*/
public function update( $new_instance, $old_instance ) {
$instance = array();
$instance['title'] = ! empty( $new_instance['title'] ) ? strip_tags( $new_instance['title'] ) : '';
return $instance;
}
/**
* AJAX callback function.
*/
public function ajax_callback() {
// Verify the nonce.
if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'recent_posts_widget_ajax_nonce' ) ) {
wp_send_json_error( 'Invalid nonce.' );
}
// Get the post ID from the request.
$post_id = absint( $_POST['post_id'] );
// Get the post content.
$content = get_post_field( 'post_content', $post_id );
// Send the response.
wp_send_json_success( array(
'content' => apply_filters( 'the_content', $content ),
) );
exit;
}
/**
* Enqueue scripts and styles.
*/
public function enqueue_scripts() {
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'recent-posts-widget', plugin_dir_url( __FILE__ ) . 'js/recent-posts-widget.js', array( 'jquery' ), '1.0', true );
wp_localize_script( 'recent-posts-widget', 'recentPostsWidgetParams', array(
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'recent_posts_widget_ajax_nonce' ),
) );
}
/**
* Get the cache key for the widget.
*/
private function get_cache_key() {
$cache_key = 'recent_posts_widget';
return $cache_key;
}
}
/*
* here's the `recent-posts-widget.js` script:
```js
*/
jQuery(document).ready(function($) {
$('#recent-posts-form').submit(function(e) {
e.preventDefault();
var postId = $('#recent-post-select').val();
var nonce = recentPostsWidgetParams.nonce;
$.ajax({
url: recentPostsWidgetParams.ajaxUrl,
method: 'POST',
data: {
action: 'recent_posts_widget',
nonce: nonce,
post_id: postId,
},
success: function(response) {
if (response.success) {
$('#recent-post-content').html(response.data.content);
} else {
console.log(response.data);
}
},
error: function(error) {
console.log(error.responseText);
},
});
});
});
/*
add to a plugin or your theme's functions.php file.
creates a widget that displays a dropdown list of recent posts and loads the content of the selected post dynamically
using AJAX when the user submits the form. The selected post content is displayed in the #recent-post-content element.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment