Custom query: how to get the sticky posts first?

Further upgrade: just built a class to place in functions.php or maybe in a plugin.
I did that mainly because I want almost always have sticky posts, probably in more loops per page. So got a lot of duplication. Therefore here is a basic class, that certainly can be exapanded/perfectioned some way, but for my needs just works:

class Posts_With_Sticky{

public $max_items_amount;
public $normal_items_amount;
public $category;
public $sticky_ids;
public $sticky_query;
public $normal_query;


function __construct($category = null, $max_items_amount = 5){

    $this->max_items_amount = $max_items_amount;
    $this->sticky_ids = get_option('sticky_posts');
    $this->category = $category;

    $this->get_query();
}

public function get_query(){

    //sticky query
    if(count($this->sticky_ids) != 0){
        $this->sticky_query = new WP_Query();
        $this->sticky_query->query(array(
            'category_name' => $this->category,
            'posts_per_page' => $this->max_items_amount,
            'post__in' => $this->sticky_ids
        ));
    }

    //check amount of stikies and room for normals
    if(isset($this->sticky_query)){
        $stikies = count($this->sticky_query->posts);
        if($stikies == $this->max_items_amount) return;
        else $this->normal_items_amount = $this->max_items_amount - $stikies;
    }

    //normal posts query
    $this->normal_query = new WP_Query();
    $this->normal_query->query(array(
        'category_name' => $this->category,
        'posts_per_page' => $this->normal_items_amount,
        'post__not_in' => $this->sticky_ids
    ));

}//end get_query

public function render_posts($sticky_loop_function, 
                                      $normal_loop_function = "", 
                                      $before_markup = "", 
                                      $after_markup = ""){

    if(!$sticky_loop_function) return;

    //shortcut
    $sticky_setted = isset($this->sticky_query);
    $normal_setted = isset($this->normal_query);    

    if(!$sticky_setted && !$normal_setted) return;

    $sticky_loop = $sticky_loop_function;
    $normal_loop = ($normal_loop_function !== "") ? $normal_loop_function : $sticky_loop_function;

    echo $before_markup;

    if($sticky_setted) $sticky_loop($this->sticky_query);
    if($normal_setted) $normal_loop($this->normal_query);

    echo $after_markup;
}//end render_posts

}//end Posts_With_Sticky

Then, in the html page, I’ll write a different loop function for every section, and then pass it to render_posts().

Something like this:

        <?php

    //html output function
    function write_soon_items($query){

        while($query->have_posts()){
            $query->the_post();
            $date = get_the_date('d.m.Y');
            $title = get_the_title();
            $excerpt = get_the_excerpt();
            $link = get_permalink();

            echo <<< ITEM_BLOCK
            <article>
                <h4>
                    $date - $title
                </h4>
                <p>
                    <a href="https://wordpress.stackexchange.com/questions/36280/$link" title="$title">$excerpt</a>
                </p>
                <div class="float-reset"></div>
            </article>
ITEM_BLOCK;
        }
    }//end write_sub_items


    $soon_posts = new Posts_With_Sticky('coming-soon');

            $soon_posts->render_posts('write_soon_items')
    ?>

So, every time I need a loop that honours sticky posts of a certain category, I just make another Posts_With_Sticky instance and then call its render_posts() method passing a custom output loop function.

Note that you can pass render_posts() a function for stickies, a function for normals (if you don’t, the first one will be used), a ‘before_markup’ and a ‘after_markup’.

Hope it helps someone.

Bye

tech