-
-
Save srikat/8e7ecf30329462f91e8d15d9ff448aef to your computer and use it in GitHub Desktop.
Custom Featured Posts Widget plugin: Skeleton for amending the output of the Genesis Featured Posts widget. https://sridharkatakam.com/custom-featured-post-widget-plugin/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name | |
* | |
* @package Custom_Featured_Post_Widget | |
* @author Gary Jones | |
* @license GPL-2.0+ | |
* @link http://gamajo.com/ | |
* @copyright 2013 Gary Jones, Gamajo Tech | |
*/ | |
/** | |
* Custom Featured Post widget class. | |
* | |
* @package Custom_Featured_Post_Widget | |
* @author Gary Jones | |
*/ | |
class Custom_Featured_Post extends Genesis_Featured_Post { | |
/** | |
* Echo the widget content. | |
* | |
* @since 1.0.0 | |
* | |
* @global WP_Query $wp_query Query object. | |
* @global array $_genesis_displayed_ids Array of displayed post IDs. | |
* @global int $more | |
* | |
* @param array $args Display arguments including `before_title`, `after_title`, | |
* `before_widget`, and `after_widget`. | |
* @param array $instance The settings for the particular instance of the widget. | |
*/ | |
public function widget( $args, $instance ) { | |
global $wp_query, $_genesis_displayed_ids; | |
// Merge with defaults. | |
$instance = wp_parse_args( (array) $instance, $this->defaults ); | |
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
echo $args['before_widget']; | |
if ( ! empty( $instance['title'] ) ) { | |
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ) . $args['after_title']; | |
} | |
$query_args = [ | |
'post_type' => 'post', | |
'cat' => $instance['posts_cat'], | |
'showposts' => $instance['posts_num'], | |
'offset' => $instance['posts_offset'], | |
'orderby' => $instance['orderby'], | |
'order' => $instance['order'], | |
'ignore_sticky_posts' => $instance['exclude_sticky'], | |
]; | |
// Exclude displayed IDs from this loop? | |
if ( $instance['exclude_displayed'] ) { | |
$query_args['post__not_in'] = (array) $_genesis_displayed_ids; | |
} | |
$wp_query = new WP_Query( $query_args ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Reset later. | |
if ( have_posts() ) { | |
while ( have_posts() ) { | |
the_post(); | |
$_genesis_displayed_ids[] = get_the_ID(); | |
genesis_markup( | |
[ | |
'open' => '<article %s>', | |
'context' => 'entry', | |
'params' => [ | |
'is_widget' => true, | |
], | |
] | |
); | |
$image = genesis_get_image( | |
[ | |
'format' => 'html', | |
'size' => $instance['image_size'], | |
'context' => 'featured-post-widget', | |
'attr' => genesis_parse_attr( 'entry-image-widget', [] ), | |
] | |
); | |
if ( $image && $instance['show_image'] ) { | |
$role = empty( $instance['show_title'] ) ? '' : ' aria-hidden="true" tabindex="-1"'; | |
printf( | |
'<a href="%s" class="%s"%s>%s</a>', | |
esc_url( get_permalink() ), | |
esc_attr( $instance['image_alignment'] ), | |
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaping breaks output here | |
$role, | |
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaping breaks output here | |
wp_make_content_images_responsive( $image ) | |
); | |
} | |
if ( ! empty( $instance['show_gravatar'] ) ) { | |
echo '<span class="' . esc_attr( $instance['gravatar_alignment'] ) . '">'; | |
echo get_avatar( get_the_author_meta( 'ID' ), $instance['gravatar_size'] ); | |
echo '</span>'; | |
} | |
if ( $instance['show_title'] || $instance['show_byline'] ) { | |
$header = ''; | |
if ( ! empty( $instance['show_title'] ) ) { | |
$title = get_the_title() ?: __( '(no title)', 'genesis' ); | |
/** | |
* Filter the featured post widget title. | |
* | |
* @since 2.2.0 | |
* | |
* @param string $title Featured post title. | |
* @param array $instance { | |
* Widget settings for this instance. | |
* | |
* @type string $title Widget title. | |
* @type int $posts_cat ID of the post category. | |
* @type int $posts_num Number of posts to show. | |
* @type int $posts_offset Number of posts to skip when | |
* retrieving. | |
* @type string $orderby Field to order posts by. | |
* @type string $order ASC for ascending order, DESC for | |
* descending order of posts. | |
* @type bool $exclude_displayed True if posts shown in main output | |
* should be excluded from this widget | |
* output. | |
* @type bool $show_image True if featured image should be | |
* shown, false otherwise. | |
* @type string $image_alignment Image alignment: `alignnone`, | |
* `alignleft`, `aligncenter` or `alignright`. | |
* @type string $image_size Name of the image size. | |
* @type bool $show_gravatar True if author avatar should be | |
* shown, false otherwise. | |
* @type string $gravatar_alignment Author avatar alignment: `alignnone`, | |
* `alignleft` or `aligncenter`. | |
* @type int $gravatar_size Dimension of the author avatar. | |
* @type bool $show_title True if featured page title should | |
* be shown, false otherwise. | |
* @type bool $show_byline True if post info should be shown, | |
* false otherwise. | |
* @type string $post_info Post info contents to show. | |
* @type bool $show_content True if featured page content | |
* should be shown, false otherwise. | |
* @type int $content_limit Amount of content to show, in | |
* characters. | |
* @type int $more_text Text to use for More link. | |
* @type int $extra_num Number of extra post titles to show. | |
* @type string $extra_title Heading for extra posts. | |
* @type bool $more_from_category True if showing category archive | |
* link, false otherwise. | |
* @type string $more_from_category_text Category archive link text. | |
* } | |
* @param array $args { | |
* Widget display arguments. | |
* | |
* @type string $before_widget Markup or content to display before the widget. | |
* @type string $before_title Markup or content to display before the widget title. | |
* @type string $after_title Markup or content to display after the widget title. | |
* @type string $after_widget Markup or content to display after the widget. | |
* } | |
*/ | |
$title = apply_filters( 'genesis_featured_post_title', $title, $instance, $args ); | |
$heading = genesis_a11y( 'headings' ) ? 'h4' : 'h2'; | |
$header .= genesis_markup( | |
[ | |
'open' => "<{$heading} %s>", | |
'close' => "</{$heading}>", | |
'context' => 'entry-title', | |
'content' => sprintf( '<a href="%s">%s</a>', get_permalink(), $title ), | |
'params' => [ | |
'is_widget' => true, | |
'wrap' => $heading, | |
], | |
'echo' => false, | |
] | |
); | |
} | |
if ( ! empty( $instance['show_byline'] ) && ! empty( $instance['post_info'] ) ) { | |
$header .= genesis_markup( | |
[ | |
'open' => '<p %s>', | |
'close' => '</p>', | |
'context' => 'entry-meta', | |
'content' => genesis_strip_p_tags( do_shortcode( $instance['post_info'] ) ), | |
'params' => [ | |
'is_widget' => true, | |
], | |
'echo' => false, | |
] | |
); | |
} | |
genesis_markup( | |
[ | |
'open' => '<header %s>', | |
'close' => '</header>', | |
'context' => 'entry-header', | |
'params' => [ | |
'is_widget' => true, | |
], | |
'content' => $header, | |
] | |
); | |
} | |
if ( ! empty( $instance['show_content'] ) ) { | |
genesis_markup( | |
[ | |
'open' => '<div %s>', | |
'context' => 'entry-content', | |
'params' => [ | |
'is_widget' => true, | |
], | |
] | |
); | |
if ( 'excerpt' === $instance['show_content'] ) { | |
the_excerpt(); | |
} elseif ( 'content-limit' === $instance['show_content'] ) { | |
the_content_limit( (int) $instance['content_limit'], genesis_a11y_more_link( esc_html( $instance['more_text'] ) ) ); | |
} else { | |
global $more; | |
$orig_more = $more; | |
$more = 0; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Temporary change. | |
the_content( genesis_a11y_more_link( esc_html( $instance['more_text'] ) ) ); | |
$more = $orig_more; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Global is being restored. | |
} | |
genesis_markup( | |
[ | |
'close' => '</div>', | |
'context' => 'entry-content', | |
'params' => [ | |
'is_widget' => true, | |
], | |
] | |
); | |
} | |
genesis_markup( | |
[ | |
'close' => '</article>', | |
'context' => 'entry', | |
'params' => [ | |
'is_widget' => true, | |
], | |
] | |
); | |
} | |
} | |
// Restore original query. | |
wp_reset_query(); // phpcs:ignore WordPress.WP.DiscouragedFunctions.wp_reset_query_wp_reset_query -- Making sure the query is really reset. | |
// The EXTRA Posts (list). | |
if ( ! empty( $instance['extra_num'] ) ) { | |
if ( ! empty( $instance['extra_title'] ) ) { | |
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
echo $args['before_title'] . '<span class="more-posts-title">' . esc_html( $instance['extra_title'] ) . '</span>' . $args['after_title']; | |
} | |
$offset = (int) $instance['posts_num'] + (int) $instance['posts_offset']; | |
$query_args = [ | |
'cat' => $instance['posts_cat'], | |
'showposts' => $instance['extra_num'], | |
'offset' => $offset, | |
]; | |
$wp_query = new WP_Query( $query_args ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Reset later. | |
$listitems = ''; | |
if ( have_posts() ) { | |
while ( have_posts() ) { | |
the_post(); | |
$_genesis_displayed_ids[] = get_the_ID(); | |
$listitems .= sprintf( '<li><a href="%s">%s</a></li>', esc_url( get_permalink() ), esc_html( get_the_title() ) ); | |
} | |
if ( '' !== $listitems ) { | |
printf( '<ul class="more-posts">%s</ul>', $listitems ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped before. | |
} | |
} | |
// Restore original query. | |
wp_reset_query(); // phpcs:ignore WordPress.WP.DiscouragedFunctions.wp_reset_query_wp_reset_query -- Making sure the query is really reset. | |
} | |
if ( ! empty( $instance['more_from_category'] ) && ! empty( $instance['posts_cat'] ) ) { | |
printf( | |
'<p class="more-from-category"><a href="%1$s" title="%2$s">%3$s</a></p>', | |
esc_url( get_category_link( $instance['posts_cat'] ) ), | |
esc_attr( get_cat_name( $instance['posts_cat'] ) ), | |
esc_html( $instance['more_from_category_text'] ) | |
); | |
} | |
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
echo $args['after_widget']; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Custom Featured Post Widget | |
* | |
* @package Custom_Featured_Post_Widget | |
* @author Gary Jones | |
* @license GPL-2.0+ | |
* @link http://gamajo.com/ | |
* @copyright 2013 Gary Jones, Gamajo Tech | |
* | |
* @wordpress-plugin | |
* Plugin Name: Custom Featured Post Widget | |
* Plugin URI: http://gamajo.com/... | |
* Description: Provides a canvas for modifying Genesis Featured Post Widget. | |
* Version: 1.0.3 | |
* Author: Gary Jones | |
* Author URI: http://gamajo.com/ | |
* Text Domain: custom-featured-post-widget | |
* License: GPL-2.0+ | |
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt | |
* Domain Path: /languages | |
*/ | |
// If this file is called directly, abort. | |
if ( ! defined( 'WPINC' ) ) { | |
die; | |
} | |
register_activation_hook( __FILE__, 'custom_activation_check' ); | |
/** | |
* Check if Genesis is the parent theme. | |
*/ | |
function custom_activation_check() { | |
$theme_info = wp_get_theme(); | |
$genesis_flavors = array( | |
'genesis', | |
'genesis-trunk', | |
); | |
if ( ! in_array( $theme_info->Template, $genesis_flavors, true ) ) { | |
deactivate_plugins( plugin_basename( __FILE__ ) ); // Deactivate ourself. | |
$message = sprintf( | |
/* translators: %s: URL to Genesis Framework. */ | |
__( 'Sorry, you can\'t activate this plugin unless you have installed <a href="%s">Genesis</a>.', 'genesis-simple-hook-guide' ), | |
esc_url( 'https://my.studiopress.com/themes/genesis/' ) | |
); | |
wp_die( $message ); | |
} | |
} | |
add_action( 'widgets_init', 'custom_featured_post_widget', 15 ); | |
/** | |
* Register widgets for use in a Genesis child theme. | |
* | |
* @since 1.0.0 | |
*/ | |
function custom_featured_post_widget() { | |
require plugin_dir_path( __FILE__ ) . 'class-custom-featured-post.php'; | |
unregister_widget( 'Genesis_Featured_Post' ); | |
register_widget( 'Custom_Featured_Post' ); | |
} | |
/* Note: If the require is happening too late, then move into a new function, hooked to genesis_setup, 15 instead: | |
add_action( 'genesis_setup', 'custom_featured_post_load_class', 15 ); | |
function custom_featured_post_load_class() { | |
require plugin_dir_path( __FILE__ ) . 'class-custom-featured-post.php'; | |
} | |
*/ |
@WPDevHQ I've created an issue in Genesis GH repo. Will update this based on the replies I get there.
@WPDevHQ Here's the response from Bill Erickson:
wp_reset_query()
is correct because those widgets are overwriting the global$wp_query
.wp_reset_query()
resets this back to the correct global$wp_query
, using$wp_the_query
, then runswp_reset_postdata()
.If those widgets used a different variable for the query, like
$loop = new WP_Query()
, then we could usewp_reset_postdata()
as the only global variable that needs resetting is$post
.
@grcwordpress Done.
I'm getting a blank site when I try to activate - does the plugin work with the most recent Genesis install?
@mmgmoro Yes, it works fine the current latest Genesis. No problem here.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great plugin, thanks!