3

So in the template I've multiple featured posts and sliders and 2 default loops.

I use get_posts for everything except default loops (obviously).

Now the issue I'm having is excluding get_posts posts from main loops. I could have gone query_posts way but impact on performance is bad and I want to work on main loop even before its generated.

So I'm going to use pre_get_posts in functions.php.

Inside pre_get_posts I'm going to modify main loop and exclude get_posts data.

I've following problems:

  1. I need to use get_posts inside template, so I need to declare variable holding those as global :( otherwise it will not be accessible inside my template.

  2. get_posts inside pre_get_posts gives me memory issues: Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 130968 bytes


function RoomsGazette_homepage_content( $query ) {

    //$tweets         = getTweets( 4, $titan->getOption( 'tweets_from_user' ) );

    $header_sliders = get_posts( array( 'meta_key' => 'roomsgazette_hp_position', 'meta_value' => 1, 'posts_per_page' => 5, ) );

    //$footer_sliders = get_posts( array( 'meta_key' => 'roomsgazette_hp_position', 'meta_value' => 2, 'posts_per_page' => 5, ) );

    //$featured       = get_posts( array( 'meta_key' => 'roomsgazette_hp_position', 'meta_value' => 3, 'posts_per_page' => 2, ) );

    $exclude_ids    = array();

    foreach ( $header_sliders as $tmp ) {
        array_push( $exclude_ids, $tmp->ID );
    }

    foreach ( $footer_sliders as $tmp ) {
        array_push( $exclude_ids, $tmp->ID );
    }

    foreach ( $featured as $tmp ) {
        array_push( $exclude_ids, $tmp->ID );
    }

    if ( $query->is_home() && $query->is_main_query() )
    {
        $query->set( 'post__not_in', $exclude_ids );
    }

}
add_action( 'pre_get_posts', 'RoomsGazette_homepage_content' );
5

Firstly, you are invoking an infinite loop, which causes the memory exhaustion. To avoid it, put the following at the beginning of your function:

// avoid infinite loop
remove_action( 'pre_get_posts', __FUNCTION__ ); 

It makes sure the you are not hooking it into pre_get_posts over and over again, re-initiating your get_posts() call over and over again.

Secondly, make use of WP_Query's - and subsequently get_posts's - the fields parameter, choosing ids as value, which reduces the memory-/workload by getting only IDs.

|improve this answer|||||
  • Thanks! Second part: WP_Query instead of get_posts? I'm using not only IDS, I also need $featured inside theme file, so I can display them. Or do you think its better to have two get_posts one in pre_get_posts with only IDS and one in template? Seems redundant – user8842 May 24 '15 at 10:51
  • Is there a way to get $header_sliders inside template without declaring it as global? – user8842 May 24 '15 at 10:52
  • You can use 'fields' => 'ids' with get_posts(), which is only a wrapper for WP_Query. Using a global is probably the simplest way, otherwise you could use transients, especially if the values stay the same a lot, or you construct a class, whose instance contains/stores the data. The last two options need some more work though. @SandroDzneladze – Nicolai May 24 '15 at 10:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy