3. Filters

Héctor Cabrera edited this page Jul 9, 2018 · 12 revisions

Filter hooks are one of the most versatile and useful features that WordPress has to offer. It allows maximum flexibility when it comes to modifying stuff, be it a theme, a plugin and even WordPress itself.

WordPress Popular Posts takes advantage of this to let you modify the plugin (HTML output, plugin behavior, et cetera) so it matches your specific needs. To use these filters, put them in your theme's functions.php file (or you can also create a plugin for this purpose, if you know how to).

Available filter hooks:

wpp_custom_html

Since: 3.0.0.

With wpp_custom_html you get full control of the HTML output. This filter receives two parameters:

  • $popular_posts, an array of popular posts objects.
  • $instance, an array of options from the widget/shortcode/template tag.

Keep in mind that the data you'll receive depends on what options you have enabled/disabled in the widget/shortcode/template tag.

Here's an example:

/**
 * Builds custom HTML.
 *
 * With this function, I can alter WPP's HTML output from my theme's functions.php.
 * This way, the modification is permanent even if the plugin gets updated.
 *
 * @param	array	$mostpopular
 * @param	array	$instance
 * @return	string
 */
function my_custom_popular_posts_html_list( $popular_posts, $instance ){
	$output = '<ol class="wpp-list">';

	// loop the array of popular posts objects
	foreach( $popular_posts as $popular_post ) {
		
		$stats = array(); // placeholder for the stats tag

		// Comment count option active, display comments
		if ( $instance['stats_tag']['comment_count'] ) {
			// display text in singular or plural, according to comments count
			$stats[] = '<span class="wpp-comments">' . sprintf(
				_n( '1 comment', '%s comments', $popular_post->comment_count, 'wordpress-popular-posts' ),
				number_format_i18n( $popular_post->comment_count )
			) . '</span>';
		}

		// Pageviews option checked, display views
		if ( $instance['stats_tag']['views'] ) {

			// If sorting posts by average views
			if ($instance['order_by'] == 'avg') {
				// display text in singular or plural, according to views count
				$stats[] = '<span class="wpp-views">' . sprintf(
					_n( '1 view per day', '%s views per day', intval($popular_post->pageviews), 'wordpress-popular-posts' ),
					number_format_i18n( $popular_post->pageviews, 2 )
				) . '</span>';
			} else { // Sorting posts by views
				// display text in singular or plural, according to views count
				$stats[] = '<span class="wpp-views">' . sprintf(
					_n( '1 view', '%s views', intval($popular_post->pageviews), 'wordpress-popular-posts' ),
					number_format_i18n( $popular_post->pageviews )
				) . '</span>';
			}
		}
		
		// Author option checked
		if ( $instance['stats_tag']['author'] ) {
			$author = get_the_author_meta( 'display_name', $popular_post->uid );
			$display_name = '<a href="' . get_author_posts_url( $popular_post->uid ) . '">' . $author . '</a>';
			$stats[] = '<span class="wpp-author">' . sprintf( __( 'by %s', 'wordpress-popular-posts' ), $display_name ). '</span>';
		}

		// Date option checked
		if ( $instance['stats_tag']['date']['active'] ) {
			$date = date_i18n( $instance['stats_tag']['date']['format'], strtotime( $popular_post->date ) );
			$stats[] = '<span class="wpp-date">' . sprintf( __( 'posted on %s', 'wordpress-popular-posts' ), $date ) . '</span>';
		}

		// Category option checked
		if ( $instance['stats_tag']['category'] ) {
			$post_cat = get_the_category( $popular_post->id );
			$post_cat = ( isset( $post_cat[0] ) )
			  ? '<a href="' . get_category_link( $post_cat[0]->term_id ) . '">' . $post_cat[0]->cat_name . '</a>'
			  : '';

			if ( $post_cat != '' ) {
				$stats[] = '<span class="wpp-category">' . sprintf( __( 'under %s', 'wordpress-popular-posts' ), $post_cat ) . '</span>';
			}
		}
		
		// Build stats tag
		if ( !empty( $stats ) ) {
			$stats = '<div class="wpp-stats">' . join( ' | ', $stats ) . '</div>';
		}
		
		$excerpt = ''; // Excerpt placeholder
		
		// Excerpt option checked, build excerpt tag
		if ( $instance['post-excerpt']['active'] ) {

			$excerpt = get_excerpt_by_id( $popular_post->id );
			if ( !empty( $excerpt ) ) {
				$excerpt = '<div class="wpp-excerpt">' . $excerpt . '</div>';
			}

		}

        $output .= "<li>";
		$output .= "<h2 class=\"entry-title\"><a href=\"" . get_permalink( $popular_post->id ) . "\" title=\"" . esc_attr( $popular_post->title ) . "\">" . $popular_post->title . "</a></h2>";
		$output .= $stats;
		$output .= $excerpt;
		$output .= "</li>" . "\n";

	}
	
	$output .= '</ol>';

	return $output;
}

add_filter( 'wpp_custom_html', 'my_custom_popular_posts_html_list', 10, 2 );

/**
 * Gets the excerpt using the post ID outside the loop.
 *
 * @author		Withers David
 * @link		http://uplifted.net/programming/wordpress-get-the-excerpt-automatically-using-the-post-id-outside-of-the-loop/
 * @param		int	$post_id
 * @return		string
 */
function get_excerpt_by_id( $post_id ){

	// Get post data
	$the_post = get_post( $post_id );
	// Get post_content
	$the_excerpt = $the_post->post_content;
	// Set excerpt length to 35 words, feel free to change this to whatever you like
	$excerpt_length = 35;
	// Remove all HTML tags
	$the_excerpt = strip_tags( strip_shortcodes( $the_excerpt ) );

	$words = explode( ' ', $the_excerpt, $excerpt_length + 1 );
	
	if ( count( $words ) > $excerpt_length ) :
		array_pop( $words );
		array_push( $words, '...' );
		$the_excerpt = implode( ' ', $words );
	endif;
	
	$the_excerpt = '<p>' . $the_excerpt . '</p>';

	return $the_excerpt;
}

wpp_post

Since: 3.0.0.

Unlike wpp_custom_html, this filter only changes the output of each single post (instead of the entire list). It receives three parameters:

  • $post_html, the original single post HTML output (just in case you only need to append extra markup to the original one).
  • $popular_post, the single post object.
  • $instance, an array of options from the widget/shortcode/template tag.

Keep in mind that the data you'll receive depends on what options you have enabled/disabled in the widget/shortcode/template tag.

Here's an example:

/**
 * Display the title and the publish date
 */
function my_custom_single_popular_post( $post_html, $popular_post, $instance ){	
	$output = '<li><a href="' . get_permalink($popular_post->id) . '" class="my-custom-title-class" title="' . esc_attr($popular_post->title) . '">' . $popular_post->title . '</a> <div class="my-custom-date-class">' . date( 'Y-m-d', strtotime($popular_post->date) ) . '</div></li>';	
	return $output;
}
add_filter( 'wpp_post', 'my_custom_single_popular_post', 10, 3 );

wpp_no_data

Since: 3.3.0.

The wpp_no_data filter is used to filter the HTML output when WPP is unable to find popular posts (in other words, gives you the ability to change the "Sorry. No data so far." message).

/**
 * Change WPP's 'Sorry. No data so far.' message
 */
function my_custom_no_posts_found( $no_data_html ){	
	$output = '<p>Um, err... Nothing to see here, move along!</p>';	
	return $output;
}
add_filter( 'wpp_no_data', 'my_custom_no_posts_found', 10, 1 );

wpp_trackable_post_types

Since: 3.3.3.

By default, WordPress Popular Posts tracks the page views from all public post types. You can change this behavior by using the wpp_trackable_post_types filter to tell WPP which post types should be tracked.

/**
 * Have WPP track only 'post' and 'review' post types page views, ignore the rest
 */
function my_trackable_post_types( $post_types ){	
	$track_these_post_types_only = array( 'post', 'review' );	
	return $track_these_post_types_only;
}
add_filter( 'wpp_trackable_post_types', 'my_trackable_post_types', 10, 1 );
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.