The WordPress query_posts command allows you to query the WordPress wp_posts database and retrieve post objects (e.g. posts, pages, attachments) based on their attributes.
get_posts is similar to query_posts and is also used to query the wp_posts database. You will note however, that the argument list it uses is slightly different compared to query_posts, therefore make sure to refer to the WordPress codex to ensure that you are using the right argument names for each of these commands.
Both query_posts and get_posts are based on the WP_Query object. However, query_posts creates a global WP_Query object that is stored in the $wp_query global variable, whereas get_posts creates a local WP_Query object that only exists within the function.
The global $wp_query variable is later used by multiple functions within the WordPress Loop. That is why it is important NOT to use query_posts within an existing WordPress Loop because it will replace the existing Loop object (contained in $wp_query) with a new WP_Query object.
query_posts is most useful when you are writing a plugin, and want to display a list of post objects within a WordPress administration menu. In the administration area, there is no Loop to worry about.
When you are operating outside of the WordPress administration area (i.e. WordPress Dashboard), it is best to use the get_posts command so that you do not inadvertently corrupt your WordPress Loop.
Incidentally, if you want to use query_posts type attributes within a WordPress Loop, then you can just create your own local WP_Query object as follows –
<?php $tmp_query = new WP_Query; return $tmp_query->query($atts); ?>
$atts should contain an attribute array similar to what you would use in the query_posts function. Here are the list of parameters for query_posts.
Here is another example –
<?php $tmp_query = new WP_Query; $tmp_result = $tmp_query->query('category_name=aciform'); ?>
How to Paginate Your query_posts Results
Sometimes, you may only want to show a certain fixed number of post objects per page, and allow users to browse through several pages of results. The code below will allow you to achieve this (partially extracted from the wp-admin/upload.php file).
<?php if (isset($_GET['paged'])) $cur_page = absint($_GET['paged']); else $cur_page = 1; // Get posts $args = array( 'post_type' => 'attachment', 'posts_per_page' => 5, 'paged'=> $cur_page ); query_posts($args); global $wp_query; $page_links_total = $wp_query->max_num_pages; $page_links = paginate_links( array( 'base' => add_query_arg( 'paged', '%#%' ), 'format' => '', 'prev_text' => __('«'), 'next_text' => __('»'), 'total' => $page_links_total, 'current' => $cur_page )); if ( $page_links ) : ?> <div class="tablenav-pages"> <?php $page_links_text = sprintf( '<span class="displaying-num">' . __( 'Displaying %s–%s of %s' ) . '</span>%s', number_format_i18n( ( $cur_page - 1 ) * $wp_query->query_vars['posts_per_page'] + 1 ), number_format_i18n( min( $cur_page * $wp_query->query_vars['posts_per_page'], $wp_query->found_posts ) ), number_format_i18n( $wp_query->found_posts ), $page_links ); echo $page_links_text; ?> </div> <?php endif; ?>
Line 2 – The current page that the user is on is set as an address line argument ($_GET['paged']) by the paginate_links function (line 16). The argument name ‘paged’ is set on line 17.
Line 9 – Make sure to include this page value while calling query_posts so that you will retrieve the right set of post objects for a given page.
Line 16 -Get the proper set of links for each page. Note that the paginate_links function is not dependent on any global variables (i.e. it is not dependent on $wp_query) so you can use it to generate page links for any list of objects by entering in proper values for total (total number of pages) and current (the current page).
Lines 27-35 -Display the page links returned by the paginate_links function.