Skip to content

Instantly share code, notes, and snippets.

@birgire
Last active December 4, 2018 16:44
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save birgire/439e36a6b08f1159f653 to your computer and use it in GitHub Desktop.
Save birgire/439e36a6b08f1159f653 to your computer and use it in GitHub Desktop.
WordPress: The Sponsor Posts Injector plugin
/**
* The Sponsor Posts Injector - Usage Example
*
* @version 0.0.3
* @uses content-sponsor.php
* @file functions.php
* @see http://wordpress.stackexchange.com/q/158133/26350
*/
/**
* Inject a sponsor post after the first post on the home page,
* and then again for every third post within the main query.
*/
add_action( 'wp', 'my_sponsor_injections' );
function my_sponsor_injections()
{
if( ! class_exists( 'SponsorPostsInjector' ) ) return;
// We want the sponsor post injections only on the home page:
if( ! is_home() ) return;
// Setup the injection:
$injector = new SponsorPostsInjector(
array(
'items_before_each_inject' => 3,
'items_per_inject' => 1,
'template_part' => 'content-sponsor',
)
);
// Setup the injection query:
$injector->query(
array(
'post_type' => 'sponsor',
'tax_query' => array(
array(
'taxonomy' => 'country',
'terms' => 'sweden',
'field' => 'slug',
)
)
)
);
// Inject:
$injector->inject();
}
<?php
/**
* Plugin Name: Sponsor Posts Injector
* Description: This plugin helps you to automatically inject sponsor posts into the loop. You must use custom code to start the injection. See the example.
* Plugin URI: http://wordpress.stackexchange.com/a/141612/26350
* Author: birgire
* Author URI: https://github.com/birgire
* License: GPL2+
* Version: 0.0.3
*/
/**
* class SponsorPostsInjector
*
* Inject custom posts into the main loop, through hooks,
* with only a single WP_Query() call
*
* @link http://wordpress.stackexchange.com/a/141612/26350
*
* Definitions:
* Posts per page: PPP
* Custom post type: Y
* Main query post type: X
* How many Y posts to inject: y
* How many X posts to display before injecting the Y posts: x
*
* Formula:
* PPP(Y) = y * floor( ( PPP(X) -1 ) / x )
* where PPP(X), x and y are positive
*/
class SponsorPostsInjector
{
protected $results = null;
protected $query = null;
protected $nr = 0;
protected $inject_mode = false;
protected $args = array();
protected $query_args = array();
public function __construct( $args = array() )
{
$defaults = array(
'items_before_each_inject' => 1,
'items_per_inject' => 1,
'template_part' => 'content-page',
);
$this->args = wp_parse_args( $args, $defaults );
}
public function query( $query_args = array() )
{
$defaults = array(
'paged' => ( $pgd = get_query_var( 'paged' ) ) ? $pgd : 1,
'suppress_filters' => true,
);
$this->query_args = wp_parse_args( $query_args, $defaults );
}
public function inject()
{
add_action( 'loop_start', array( $this, 'loop_start' ) );
add_action( 'loop_end', array( $this, 'loop_end' ) );
}
public function items_on_this_page( WP_Query $query )
{
$count = $this->args['items_per_inject'] * floor( ( $query->get( 'posts_per_page' ) -1 ) / $this->args['items_before_each_inject'] );
return ( $count > 0 ) ? $count : 1;
}
public function loop_start( WP_Query $query )
{
$this->query = $query;
if( $query->is_main_query() )
{
$this->query_args['posts_per_page'] = $this->items_on_this_page( $query );
$this->results = new WP_Query( $this->query_args );
add_action( 'the_post', array( $this, 'the_post' ) );
}
}
public function loop_end( WP_Query $query )
{
if( $query->is_main_query() )
remove_action( 'the_post', array( $this, 'the_post' ) );
}
public function the_post()
{
if( ! $this->inject_mode
&& 0 < $this->nr
&& 0 === $this->nr % $this->args['items_before_each_inject'] )
{
$this->inject_mode = true;
$this->results->rewind_posts();
$this->results->current_post = ( absint( $this->nr / $this->args['items_before_each_inject'] ) -1 ) * $this->args['items_per_inject'] - 1;
$j = 1;
if ( $this->results->have_posts() ) :
while ( $this->results->have_posts() ) :
$this->results->the_post();
get_template_part( $this->args['template_part'] );
if( $this->args['items_per_inject'] < ++$j )
break;
endwhile;
wp_reset_postdata();
endif;
$this->inject_mode = false;
}
if( ! $this->inject_mode )
$this->nr++;
}
} // end class
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment