WordPress provides a number of useful utility functions used to get post data. Post data is understood as the data of a specific article such as ID, post content, thumbnail, author, … or it can also be an array of articles that meet one or more certain conditions.
First, we will look at how to get the content of the post based on the ID, using the get_post() function
The return value of this function will be an array or an object.
Print_r(get_post($post_id));
//return object
get_post($post_id,'OBJECT');
//return array type: Returns an associative array of field names to values
get_post($post_id,'ARRAY_A');
//returns a numeric array of field values
get_post($post_id,'ARRAY_N');
To learn more, please read the article get post by id
Table of Contents
Get posts that match your criteria
3 common functions to get posts are: get_posts(), new WP_Query(), query_posts()
- query_posts: usually get the main posts in the template (main query).
- get_posts and WP_Query: often used to get posts with conditions like getting all posts in a category…
These 3 functions all use parameters of type string or array.
$args=array( 'name'=>'sample-post-slug', 'post_status' => 'publish' ); $data=get_posts($args);
In the above example, It will get a post with slug=’sample-post-slug’ and the status of the post is published. Pass the array parameter to get_posts. Then use a PHP Foreach loop to split the data and display it.
foreach($data as $post){ //show post data the_title(); the_content(); }
Note: for the case of getting independent posts using get_posts, if we want to use the template tag like above eg: the_title, the_content we need to get each post data into the $post variable in the iterative array returned by the get_posts function. And before you can use the template tag you will have to configure the global post using the setup_postdata function. Note that the $post variable must not be renamed with another name, the template tag will not work properly.
This does not apply to WP_Query.
Use main query loop and secondary query loops
When you get data by get_posts or WP_Query function called get second data after main page’s data. For example, the data loop in the template single.php, page.php, or category.php is the main query loop. We still often use the loop to get the data of the detail post page:
<?php while ( have_posts() ) : the_post(); ?> <?php get_template_part( 'content', get_post_format() ); ?> <?php endwhile; // end of the loop. ?>
If you want to use the get_posts & WP_Query function to get the data before using the main data in the template, i.e. put the get data with these functions before the while loop above, then before starting the fetch. main data you need to restore the current template’s data by calling the wp_reset_postdata() function. Eg:
<?php // example args $args = array( 'posts_per_page' => 10 ); // the query $the_query = new WP_Query( $args ); ?> <?php if ( $the_query->have_posts() ) : ?> <!-- start of the loop --> <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?> <?php the_title(); ?> <?php the_excerpt(); ?> <?php endwhile; ?><!-- end of the loop --> <!-- put pagination functions here --> <?php wp_reset_postdata(); ?> <?php else: ?> <p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p> <!-- main query loop --> <?php while ( have_posts() ) : the_post(); ?> <?php get_template_part( 'content', get_post_format() ); ?> <?php endwhile; // end of the loop. ?> <?php endif; ?>
The difference between the main query loop and secondary query loops is:
The main query loop is based on the URL since the single and category URL template will output different data and be processed before loading the template. While the secondary loops are standalone queries using WP_Query.
Unlike get_posts & WP_Query, the query_posts function has the effect of modifying the parameters before getting the main data in the template. Example: edit option ‘posts_per_page’
<?php global $query_string; query_posts($query_string.'&posts_per_page=10'); while(have_posts()):the_post(); endwhile; ?>
WordPress stores the parameter string in the global $query_string variable. Another way to get the query parameter from the $wp_query variable:
<?php global $wp_query; $args=array('posts_per_page'=>10); query_posts(array_merge($wp_query->query_vas,$args)); while(have_posts()):the_post(); endwhile; ?>
Query Data
$args=array( 'numberposts' => 12, //quantity to get -1 for all 'showposts'=>6, //quantity to show 'posts_per_page' => 3, //number of posts on the page (pagination) );
Note: numberposts is the number of posts to be retrieved including pagination, showposts: the number of posts to be retrieved does not include pagination.
Sort the returned data
Sort by Alphabet
– by title title
– the name of the author of the article (author)
– according to the post slug name
Example sorting by article title from [a-z]
$args=array( 'post_type'=>'post', 'orderby' => 'title', 'sort_order'=>'asc' ); // reverse reverse [z-a] $args=array( 'orderby' => 'title', 'order'=>'desc' );
Sorting forward or backward or ascending or descending can use sort_order or order, both of which play the same role.
Sort by date-time
- Published date
- Modified date
The following example sorts the articles by date, i.e. articles written later will be displayed at the back.
global $query_string; query_posts($query_string."&orderby=date&order=asc"); //loop while(have_posts()): the_post(); endwhile;
Normally WordPress will sort in reverse, new posts are displayed at the top.
$args=array( 'orderby' => 'date', 'order'=>'desc' ); global $wp_query; $args=array_merge($wp_query->query_vars,$args); $query=new WP_Query($args); while($query->have_posts()): $query->post->ID; //return the post's ID endwhile;
This parameter is already there by default, so when you design a WordPress template, you do not need to specify this parameter. In the above example, we use the WP_Query class to get the posts data, you are familiar with the data constructor for each post the_post which takes the post ID the_ID() or get_the_ID(). Alternatively, you can use the $query->post->ID variable without having to call the_post() first.
Sort by number
- by post/page id ID
- sort by number of comments (comment_count)
- sort by post/page parent id.
Example: Sort posts/pages/custom post types with decreasing number of comments.
$args=array( 'orderby'=>'comment_count', 'order'=>'desc' );
Sort by custom field:
A custom field is a field added by the user in addition to the fields provided by the data type eg: the post data type has some fields like title, content, excerpt,… Specify the field name by the meta_key parameter, the field value is sorted by alphabet or number. The following example sorts a custom field by alpha.
$args=array( 'meta_key'=>'field1', 'orderby'=>'meta_value', 'order'=>'asc' );
If the value of the custom field is numeric, instead of using meta_value you use meta_value_num to tell WordPress to sort this field by numeric. The following example sorts posts with the custom field “field1” in descending value.
$args=array( 'post_type'=>'post', 'meta_key'=>'field1', 'orderby'=>'meta_value_num', 'order'=>'desc' );
Random sort:
Randomize post/page/custom post types. Use “orderby”=>”rand”
array( 'orderby'=>'rand' );
Custom post type
Get the data of the custom post type. Specify the custom post type name in the post_type parameter.
$args=array( 'post_type' => 'custom-post-name',);
Filter posts by taxonomy. Compare 1 or more taxonomy with relation ‘AND’, ‘OR’
$args=array( 'tax_query' => array( 'relation' => 'AND', array ( 'taxonomy' => 'business-type', 'field' => 'slug', 'terms' => array('term1','term2') 'operator'=>'IN' ), array( 'taxonomy' => 'actor', 'field' => 'id', 'terms' => array( 103, 115, 206 ), 'operator' => 'NOT IN' ) ),);
And compare the taxonomy of one of the exact values with the operand operator. eg: IN, NOT IN
Note: the same type of comparison but filtering custom fields with ‘meta_query’ will use a different parameter name ‘compare’.
Filter posts with custom post fields. The simple way is to compare a field’s value.
$args=array( 'meta_key'=>'field-name', 'meta_value'=>'field-value' );
If the value of the field is not known, do not provide it. The result will list all posts with that field.
$args=array( 'meta_key'=>'field-name', );
To compare multiple fields, we use the meta_query parameter.
$args=array( 'meta_query'=>array( 'relation'=>'AND', array( 'key' => 'color', 'value' => 'blue', 'compare' => 'NOT LIKE' ), array( 'key' => 'price', 'value' => array( 20, 100 ), 'type' => 'numeric', 'compare' => 'BETWEEN' ), array( 'key' => 'places_lat', 'value' => array($lat_min, $lat_max), 'compare' => 'BETWEEN', //'type' => 'DECIMAL', ), array( 'key' => 'colors', 'compare' => 'NOT EXISTS' // doesn't work ), array( 'key' => 'colors', 'value' => 'blue' ), ), );
You can also sort data with ‘meta_query’ using the compare attribute. Note: if the meta condition does not exist (compare=’NOT EXISTS’) then its value is meaningless, see also: https://codex.wordpress.org/Class_Reference/WP_Meta_Query.
You want to compare a field but at the same time that data line has other fields, For example, I want to return articles with post date from date xx onwards by field value “the_date”, The following code we have meta_key and meta_query attributes can be combined.
<?php $today = date('Ymd'); $args = array( 'post_type' => 'post', 'posts_per_page' => '4', 'meta_key' => 'the_date', 'meta_query' => array( array( 'key' => 'skyali_feature' ), array( 'key' => 'the_date', 'value' => $today, 'compare' => '>=' ) ), 'orderby' => 'meta_value_num', 'order' => 'ASC' ); $your_custom_query = new WP_Query($args); ?>
The comparison field is the_date and the comparison type is greater than or equal to (>=). To sort the ASC form of the return result of the field “the_date”, we need to declare an additional field in the meta_key attribute like above. You can use other attributes to filter posts as you like eg: post_type.
Of course, Woocommerce Product is also a custom post type in WordPress, so these data retrieving functions can also get product data in Woocommerce. Many Woocommerce functions use data retrieval functions like get_posts or WP_Query.
Filter by tag and category
Filter posts with Tag.
$args=array( 'tag__in'=>array(1,35,5), //belongs to 1 of the tag 'tag_slug__in' => array('forrest-gump', 'forest-gump', 'questend') //search tags 'tag'=>'tag1,tag2' //search tag );
Filter posts with category.
$args=array( 'category' => 3, //category id =3 'category_name'=>'category1', //category slug );
Get only post with thumbnail support
Note: Posts with featured images or thumbnails have the field attribute ‘_thumbnail_id’.
$args=array( 'meta_key' => '_thumbnail_id', );
Exclude posts from the results
Get all but Exclude these posts. Pass the array of IDs of the posts you want to remove in the result.
$args=array( 'post__not_in' => array($post->ID), );
Modify the where SQL statement
The parameters of the data-retrieving functions like get_posts, WP_Query, query_posts provide quite complete data filtering, can do everything, but if you don’t see the response enough or you have an idea to intervene. where string subject to interfering more deeply with the SQL command and you can even combine with other table’s data. Now you need the posts_where hook.
In the following example, I limit posts by author, the results only return posts by one author. We pass the restrict_manage_posts URL parameter to filter the author.
add_filter( 'posts_where' , 'posts_where' ); function posts_where( $where ) { if( is_admin() ) { global $wpdb; if ( isset( $_GET['author_restrict_posts'] ) && !empty( $_GET['author_restrict_posts'] ) && intval( $_GET['author_restrict_posts'] ) != 0 ) { $author = intval( $_GET['author_restrict_posts'] ); $where .= " AND ID IN (SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id=$author )"; } } return $where; }
Write the where clause in the SQL statement to the $where a variable, all functions that get data in WordPress use this same filter. And any functions that get data will be modified depending on the function associated with the posts_where filter.
You can also allow the data filter function to ignore the posts_where filter by adding an additional parameter with the suppress_filters=>false attribute:
<?php //some function that modifies the query function useless_condition ( $where ) { return $where . ' AND 1=1 '; } //attach your function to the posts_where filter add_filter( 'posts_where' , 'useless_condition' ); //get posts AND make sure filters are NOT suppressed $posts = get_posts( array( 'suppress_filters' => FALSE ) ); ?>
Get post results (Loop each post)
Using get_posts()
$data=get_posts(..) foreach($data as $post){ setup_postdata($post); //configure post, it is mandatory to get the post into the $post variable to be able to use the_title, the_permalink.. //show post data $post->ID; //post id //template tags the_title(); the_post(); }
Using WP_Query()
$query = new WP_Query( $args ); //wp object while($query->have_posts()){ $query->the_post(); //configure post //use regular loop functions $query->next_post(); //forward post->in recent versions no need to call this function. }
Use query_posts
query_posts($args); while(have_posts()){ the_post(); //configure post }