How To Create a Custom Database Query in WordPress with WP_Query

WordPress makes queries to the database depending on the current URL. When you have to create a custom database query, do not query the database directly. WordPress offers a robust abstraction layer, the WP_Query class.

The Famous Loop, but with WP_Query

The Famous WordPress Loop will also work with WP_Query with minor changes to syntax. For example, to get the titles of the 5 recent posts in the category ‘wordpress‘:

$args = [
    'posts_per_page' => 5,
    'category_name'  => 'wordpress',
];

$custom_query = new WP_Query($args);

if ($custom_query->have_posts()) {
    echo '<ul>';
    while ($custom_query->have_posts()) {
        $custom_query->the_post();
        echo '<li>' . get_the_title() . '</li>';
    }
    echo '</ul>';
} else {
    echo 'No posts found';
}

/* Restore original Post Data */
wp_reset_postdata();

Remember to set wp_reset_postdata(); after each custom query.

Custom sorting

If you want the titles sorted alphabetically, set the $args:

$args = [
    'posts_per_page' => 5,
    'category_name'  => 'wordpress',
    'orderby'        => 'title',
    'order'          => 'ASC',
];

Custom post type

If you want to query a custom post type (other than post which is the default):

$args = [
    'posts_per_page' => 5,
    'post_type'      => 'movie',
    'orderby'        => 'title',
    'order'          => 'ASC',
];

Display all results

Set posts_per_page to -1. Example $args

$args = [
    'posts_per_page' => -1,
    'category_name'  => 'wordpress',
];

The versatile ‘meta_query’

Get the products with orange color OR with red color and size small:

$args = [
    'post_type'  => 'product',
    'meta_query' => [
        'relation' => 'OR',
        [
            'key'     => 'color',
            'value'   => 'orange',
            'compare' => '=',
        ],
        [
            'relation' => 'AND',
            [
                'key'     => 'color',
                'value'   => 'red',
                'compare' => '=',
            ],
            [
                'key'     => 'size',
                'value'   => 'small',
                'compare' => '=',
            ],
        ],
    ],
];