WordPress Template Custom Queries

Posted: January 4, 2012 in Wordpress

Here is the third part of a tutorial on how to develop WordPress templates, it explains custom queries, the WP_Query, the get_posts and the query_posts.

To access other parts of the tutorial see the WordPress Template Tutorial post.

Custom Queries

You can customize the posts returned within “the loop” by using custom post queries functions, like WP_Query, get_posts or query_posts.

  • WP_Query is more of a general purpose tool, is a bit more complex, with less restrictions, safe to use anywhere
  • get_posts is safe to use anywhere
  • query_posts should be used only if you need to modify main query of page

If you need after the custom query to access the original loop you can use this:

$tmp_post = $post;
// My custom query here
$post = $tmp_post;
The WP_Query

The recommended query to use in your WordPress templates is WP_Query. You can do a WP_Query with the short form like this:

$the_query = new WP_Query('post_type=post&cat=6&order=asc&orderby=id');
while ($the_query->have_posts()) : $the_query->the_post();
  // Inside The Loop is here
  // Use functions like the_title(); or access object variables like $post->post_title;
endwhile;

Add in the parameters additional name value pairs listed down here (like page_id, tag, tag_id, etc..) as needed.

You can also query with array data using a code like this, listed are all the possibilities of query:

$args = array(
  'post_type' => 'post', // 'post', 'page', 'any', custom type
  'post_status' => 'publish', // 'publish, 'pending', 'draft', 'future', 'private', 'trash'
  'numberposts' => 5, // Limit the query to a numberposts
  'offset' => 1, // Query start from result offset
  'order'  => 'asc', // 'asc', 'desc'
  'orderby'  => 'id', // 'none', 'id', 'author', 'title', 'date', 'modified', 'parent', 'rand', 'comment_count', 'menu_order', 'meta_value', 'meta_value_num'
  'meta_key'  => 'keyname' // If you are using orderby 'meta_value' or 'meta_value_num'
  'year'  => '2001', // Query by time. 4 digit year
  'monthnum'  => '6', // Query by time. Month number (from 1 to 12)
  'w'  => '0', // Query by time. Week of the year (from 0 to 53)
  'day'  => '1', // Query by time. Day of the month (from 1 to 31)
  'hour'  => '11', // Query by time. Hour (from 0 to 23)
  'minute'  => '12', // Query by time. Minute (from 0 to 60)
  'second'  => '19', // Query by time. Second (from 0 to 60)
  'p'  => '10', // Query by post ID
  'name'  => 'myname', // Query by post slug
  'page_id'  => '10', // Query by page ID
  'pagename'  => 'myname', // Query by page slug
  'post_parent'  => '10', // Query by post ID. Return just the child Pages
  'post__in'  => '', // Query by post ID. Specify posts to retrieve
  'post__not_in'  => '', // Query by post ID. Specify post NOT to retrieve
  'post__in'  => array( '595', '33', 44 ),
  'author'  => '123', // Query by author ID
  'author'  => array( '-12','-34','-56' ), // Filter out author ID
  'author_name'  => 'rami', // Query by author name
  'showposts'  => '5', // Limits the query to 5 results
  'cat'  => '4', // Query by category ID
  'cat'  => array( '-12','-34','-56' ), // Filter out category ID
  'category_name'  => 'staff', // Query by category slug
  'category__and'  => array( '2','6' ), // Query by category ID. Filter posts that are in both categories 2 and 6
  'category__in'  => array( '2','6' ), // Query by category ID. Filter posts that are either in category 2 OR 6
  'category__not_in'  => array( '2','6' ), // Query by category ID. Filter posts that are not either in category 2 OR 6
  'tag'  => 'cooking', // Query by tag slug
  'tag'  => 'bread+baking+recipe', // Query by tag slug. That have "all" of these tags
  'tag'  => array( 'bread','baking' ), // Query by tag slug. That have "either" of these tags
  'tag_id'  => '13', // Query by tag ID
  'tag__and'  => array( '37','47' ), // Query by tag ID. Tagged with both tag id 37 and tag id 47
  'tag__in'  => array( '37','47' ), // Query by tag ID. Tagged with either tag id 37 or tag id 47
  'tag__not_in'  => array( '37','47' ), // Query by tag ID. Tagged with neither tag id 37 and tag id 47
  'tag_slug__and'  => array( 'bread','baking' ), // Query by tag slug. Tagged with both bread and baking
  'tag_slug__in'  => array( 'bread','baking' ), // Query by tag slug. Tagged with either bread or baking
  'meta_query' => array( // You can query by custom fields
    array(
      'key' => 'color',
      'value' => 'blue',
      'compare' => 'NOT LIKE'
    ),
    array( // You can query multiple custom fields
      'key' => 'price',
      'value' => array( 20, 100 ),
      'type' => 'numeric', // Custom field type. 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'
      'compare' => 'BETWEEN' // Operator to test. 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', >, >= <, <=
    )
  ),
  'tax_query' => array( // You can query by taxonimies
    'relation' => 'AND', // Display posts that are in categories with id 103, 115, 206 AND not tagged with 'bruce', under 'people' custom taxonomy
    array(
      'taxonomy' => 'category', // 'tag', 'category', 'custom taxonomy'
        'field' => 'id',
      'terms' => array( 103, 115, 206 ),
    ),
    array(
      'taxonomy' => 'people',
      'field' => 'slug', // 'id' or 'slug'
      'terms' => array( 'bruce' ),
      'operator' => 'NOT IN', // Operator to test. 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', >, >= <, <=
    )
  )
);
$the_query = new WP_Query( $args );
while ($the_query->have_posts()) : $the_query->the_post();
  // Inside The Loop is here
  // Use functions like the_title(); or access object variables like $post->post_title;
endwhile;

The queries above are unable to fetch posts from a timespan relative to the present, so queries like “Posts from the last 30 days” or “Posts from the last year” are not possible with a basic query, and require use of the posts_where filter to be completed, like:

// Return posts from the last 30 days:
function filter_where( $where = '' ) {
  $where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
  return $where;
}
add_filter( 'posts_where', 'filter_where' );
$query = new WP_Query( $query_string );
while ($the_query->have_posts()) : $the_query->the_post();
  // Inside The Loop is here
  // Use functions like the_title(); or access object variables like $post->post_title;
endwhile;

// Return posts 30 to 60 days old
function filter_where( $where = '' ) {
  $where .= " AND post_date >= '" . date('Y-m-d', strtotime('-60 days')) . "'" . " AND post_date <= '" . date('Y-m-d', strtotime('-30 days')) . "'";
  return $where;
}
add_filter( 'posts_where', 'filter_where' );
$query = new WP_Query( $query_string );
while ($the_query->have_posts()) : $the_query->the_post();
  // Inside The Loop is here
  // Use functions like the_title(); or access object variables like $post->post_title;
endwhile;

Then when you have setup the query you can use the results like this, using the post variables inside ‘the loop’:

while ($the_query->have_posts()) : $the_query->the_post();
  // Inside The Loop is here
  // Use functions like the_title(); or access object variables like $post->post_title;
endwhile;

For all the functions and variables that you can access within “the loop” see WordPress Template Content.

The Wp_query object holds also some useful query parameters:

$wp_query->query; // Holds the query string that was passed to the $wp_query object
$wp_query->query_vars; // An associative array containing the dissected $query
$wp_query->queried_object; // Holds information on the requested category, author, post or page
$wp_query->queried_object_id; // Holds the ID of the requested category, author, post or page
$wp_query->posts; // Gets filled with the requested posts from the database
$wp_query->post_count; // The number of posts being displayed
$wp_query->current_post; //  Index of the post currently being displayed
$wp_query->post; // The post currently being displayed
$wp_query->is_single // Booleans dictating what type of request this is. Can be also is_page, is_archive, is_preview, is_date, is_year, is_month, is_time, is_author, is_category, is_tag, is_tax, is_search, is_feed, is_comment_feed, is_trackback, is_home, is_404, is_comments_popup, is_admin, is_attachment, is_singular, is_robots, is_posts_page, is_paged
The get_posts

This is the second favouire way to customize “the loop” query. You can use the get_posts function like this:

$args = array(
  'category' => , // Query by category ID
  'order' => 'DESC', // 'asc', 'desc'
  'orderby' => 'post_date', // 'none', 'id', 'author', 'title', 'date', 'modified', 'parent', 'rand', 'comment_count', 'menu_order', 'meta_value', 'meta_value_num'
  'include' => ,
  'exclude' => ,
  'numberposts' => 5, // Limit the query to a numberposts
  'offset' => 0, // Query start from result offset
  'meta_key' => , // If you are using orderby 'meta_value' or 'meta_value_num'
  'meta_value' => , // If you are using orderby 'meta_value' or 'meta_value_num'
  'post_type' => 'post', // 'post', 'page', 'any', custom type
  'post_mime_type' => ,
  'post_parent' => , // Query by post ID. Return just the child Pages
  'post_status' => 'publish' // 'publish, 'pending', 'draft', 'future', 'private', 'trash'
);
$myposts = get_posts( $args );
foreach( $myposts as $post ) :	setup_postdata($post);
	// Inside The Loop is here
	// Use functions like the_title(); or access object variables like $post->post_title;
endforeach;

For all the functions and variables that you can access within “the loop” see WordPress Template Content.

The query_posts

The last method should not be used anywhere, but only if you need to modify main query of page. You can use query_posts like this:

$args = array(
  'p' => '5', // Query by post ID
  'category' => , // Query by category ID
  'category_name' => 'The Category Name', // Query by category slug
  'order' => 'DESC', // 'asc', 'desc'
  'orderby' => 'post_date', // 'none', 'id', 'author', 'title', 'date', 'modified', 'parent', 'rand', 'comment_count', 'menu_order', 'meta_value', 'meta_value_num'
  'include' => ,
  'exclude' => ,
  'numberposts' => 5, // Limit the query to a numberposts
  'offset' => 0, // Query start from result offset
  'year'  => '2001', // Query by time. 4 digit year
  'monthnum'  => '6', // Query by time. Month number (from 1 to 12)
  'w'  => '0', // Query by time. Week of the year (from 0 to 53)
  'day'  => '1', // Query by time. Day of the month (from 1 to 31)
  'hour'  => '11', // Query by time. Hour (from 0 to 23)
  'minute'  => '12', // Query by time. Minute (from 0 to 60)
  'second'  => '19', // Query by time. Second (0 to 60)
  'meta_key' => , // If you are using orderby 'meta_value' or 'meta_value_num'
  'meta_value' => , // If you are using orderby 'meta_value' or 'meta_value_num'
  'post_type' => 'post', // 'post', 'page', 'any', custom type
  'post_mime_type' => ,
  'post_parent' => , // Query by post ID. Return just the child Pages
  'post_status' => 'publish' // 'publish, 'pending', 'draft', 'future', 'private', 'trash'
);
query_posts( $args );
while ( have_posts() ) : the_post();
	// Inside The Loop is here
	// Use functions like the_title(); or access object variables like $post->post_title;
endwhile;
wp_reset_query();

For all the functions and variables that you can access within “the loop” see WordPress Template Content.

Courtesy

Source :-http://www.minimit.com/articles/wordpress-template-custom-queries

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s