Three techniques to alter the query in WordPress


Howdy WP developer!

In this snippet, I will describe three different techniques to alter the WordPress default query with an example showing how to add a secondary page to the front page in the Customizr theme

Those are quite advanced WordPress programming techniques, so before diving into it make sure you are familiar with the following concepts :

 

Altering the WordPress default query in WordPress

There are many ways to get posts in WordPress, but we can distinghish two techniques :

  • Altering the WordPress default query in a particular context => what we are going to do here
  • Creating a new query from scratch with get_posts()  or a new WP_query  for example. This topic will not be treated here.

In the following snippets review the different techniques to alter the WordPress default query :

  1. the pre_get_posts way
  2. the query_posts way
  3. the SQL statement filters way
  4. New : the wp_the_query way

 

Case study : adding a second page to the front page in the Customizr theme

Let’s say you have defined a static page as front page and you want to display another page below it.


How to use this code? The following code snippets have to be copied and pasted in the functions.php file of a child theme.

 

The pre_get_posts way

This is the easiest and recommended way to alter the main query. This 'pre_get_posts'  hook is called after the query variable object is created, but before the actual query is run.

 

The query_posts() way

query_posts() is meant for altering the main loop. It does so by replacing the query used to generate the main loop content. Once you use query_posts(), your post-related global variables and template tags will be altered. Conditional tags that are called after you call query_posts() will also be altered – this may or may not be the intended result.

Even if this is a not the best way to alter the query, this technique shows how to make use of some interesting hooks before and after the loop in the Customizr theme.

This whole query_posts() issue is well explained by Andrew Nacin (WP core developer), here :
http://wordpress.tv/2013/03/15/andrew-nacin-wp_query-wordpress-in-depth/

 

The SQL statement filters way

Last but not least, this is a more advanced technique offering more flexibility if you need to do complex queries. For example this technique is the best way to build a query that compares dates from custom fields. (I will give an example of this approach soon)

In this example, we filter the where and orderby sql statements. The  join statement does not need to be modified here.

 

 

The $wp_the_query way

The following generic code snippet uses a global var called $wp_the_query where WordPress carrefully store the initial main query.

@see core code in wp-settings.

The snippets uses the wordpress template_redirect hook : it’s defined in wp-includes/template-loader.php.
I kind of like it because it is fired once the main query and conditional tags have been fully setup and before the wp_head action.
It’s a really the perfect place to setup hooks that will handle conditions on the main query elements.

 

 

These techniques can easily be adapted to many cases : custom post types, taxonomies, custom fields, …

Related resources :


Related Snippets you may also like


We can help you to implement this snippet

Coding is our job and we know WordPress inside and out. We can help you to customize your website with small chunks of code snippets like this one.

Send us your request and we'll get back to you quickly.



33 thoughts on “Three techniques to alter the query in WordPress

  • VOX Diseño Web

    Great in depth explanation. I’d like to add (for any newbie in the WP world, like I was once) that it’s possible to alter SOME query parameters using query_posts while ALSO preserving the rest of the original query, by doing:

    In this case the order parameter was changed… but the rest of the query is preserved.

  • bob

    hi im trying to overide the default page wordpress shows as static. i am using a preg_match to choose what language is displayed.
    (i modified my get_locale() for this to work)

    when wp loads it always loads the “page_on_front” value from the db . the idea here is to use some hook and tell wp to load an alternate page stored as “page_on_front_en”

    I created a file that is “required” at the beginning of functions.php from the code posted above then i improvised .not too sure i am going the right direction but this dosen’t work.

  • Fabrizio

    Great articles, but I still have a problem: I can’t search a querytring at same time in TITLE or BODY or POST META.

    Looking at generated query I realized the problem, the query is something like

    …in order words, it will list posts only if their title and/or body contain my query string.
    Any suggestion?

    Thanks in advance
    Fabrizio

  • Benny Powers

    Hi thanks for the great article!

    I’m trying to alter the home page’s main query to 1) show only CPTs and 2) order them by the event start date, rather than post date. This is what I have so far, but it won’t change the order. Removing the comments breaks all the queries on the page including the main nav. using $query->set() statements for meta_key etc either breaks the main query (no posts) or simply fails to orderby. Any help you can offer is greatly appreciated.

  • Dario

    Hi Nicolas,
    is there a way to create complex custom SQL JOIN query and get results into the global $post variable?
    I can’t use args array for WP_Query since I need to query meta_key from post joining users meta_key and terms taxonomy too.

    Many thanks in advance.
    Dario.

  • francis

    Hi, I would like to change the post_type that is handled by my theme and replace post by products

    I i use pre_get_post to set the query on products i can’t access my pages or other posts.
    what do you recommand?
    thanks

  • Bogdan

    I have /mypage i want to behave,act, be same style, like my taxonomy product-category/clothing/ but without shortcode , how convert page query to taxonomy query ?

  • Martin

    Hi Nicolas,
    I’m trying to create a simple sort so my visitors can order my custom post types from A-Z and from A-Z.

    I thought this was a simple task but wasn’t able to find a solution. I don’t know if you can guide me to the right direction. I understand that I need to use add_query_arg to modify my url and that I need to use pre_get_post to alter the query.

    I want the user to click the link on the page to sort the posts alphabetically (title).

    • Nicolas Post author

      Hi Martin,
      you could pass the order as an URL parameter and use it to get the order value with $_GET.
      Hope this helps!

  • Jeffrey Renza

    I have a custom db that has user content that is separate from the WP db. I would like to be able to use php within my pages. For instance,: Hello . Can you point me in a direction?

  • TAC

    HI!
    I would change my website home page. I don’t like the default page because it’s too empty(with only the slider and the circle bottoms). I would add some writing with the news or redo it.
    How can I do?

    • Nicolas Post author

      Hi TAC, you could start by playing with the Front page settings in the WordPress customizer. There you can choose to disaply your last blog post a specific page on home, below the slider and the featured pages.
      Hope this helps!

  • Jaume Albaigès

    Hi Nicolas,

    I’m not sure if the question I’m going to ask is related to this post or not, but I haven’t find any better post. I try it anyway, so please forgive me if I’m wrong.

    I would like to create a special category template to be used when displaying certain category archive. I’ve been reading some articles at wordpress codex but I feel I can’t use what they say because the file structure in Customizr is a bit different. Could you tell me how to address this situation?

    Thank you very much.

    Jaume

    • Jaume Albaigès

      Hello Nicolas,

      I see you’re around here at this moment. 😉

      Could you tell me anything about this question I sent you some days ago?

      Thank you very much.

      Jaume

    • Nicolas Post author

      Hi Jaume,
      In Customizr, you can use the WordPress template hierarchy like in any other WordPress themes. I personnaly prefer the “hook” way because I don’t like to repeat myself when coding. :).
      To create a special templates for specific category,
      1)just follow WordPress guidelines explained here :https://codex.wordpress.org/Template_Hierarchy to name your file
      2) copy the entire content of index.php file from Customizr in your category template
      3) customize your code.

      Another way would be to use the Customizr hook API with conditional tags.
      Hope this helps!

  • Rachel Krino

    Hi- I am also trying something similar. I would like to keep the posts on the front page but also have a page for the blog posts so viewers can see if both places. Any ideas. I’ve created a blog template page but can’t get the sidebars to show up like other single post pages. Any suggestions would be great!
    dev.srbenefitsolution.com

    • Kenneth

      In the end I solved it using the “add posts to pages” plugin.
      The layout isn’t as nice as the one from the theme itself but it did the trick.

      Nevertheless it would be a fine extra for the customizr theme.

  • Kenneth

    Hi,

    I’m looking for a way to keep the theme front page and make al the post appear on a static page.
    Is there any way to do so ?

    thx!

    • Nicolas Post author

      Hi Kenneth, you can do that without adding a single line of code in Customizr.
      Open the customizer options, then go to Front Page > Front Page displays and choose a static page (which could be empty if you don’t need any content on home). Then choose the page for your blog posts.
      Hope this helps!

  • Brandon

    Nicolas & Co,

    Thank you guys for creating this great theme, Your work and such good support in regards to it is well appreciated! If you ever have those moments (we all do) where your feeling overwhelmed just remember your making an awesome difference to people both newbies and experienced alike,

    Thanks Heaps guys/gals! Love your work and much respect from Australia.
    -Brandon

  • Viktor hafner

    can you help me to get the functions.php right?
    I want to show all posts from category 2 on the page with id 662

    thx

  • viktor Hafner

    I am looking for help to build a static page, which contains all posts from a specific category – can you help me?

    • Nicolas Post author

      Hi Viktor, you might want to use the pre_get_posts way to do so.

      To set a particular category, use the following code :

      you can set several categories id separated by commas, and you can also exclude some categories by prefixing their id with a minus sign.

      Hope this will help you

      • viktor hafner

        I am afraid, I cannot get it right:
        It works for posts but not for pages: what do I have to change for the function alter_query to show posts of a category on a page?
        thanx!

Comments are closed.