In category.php
, I want to get list of posts in that category.
I found two ways: using get_posts($args)
and The Loop
.
get_posts() way
$args = array (
"category" => ID );
$posts = get_posts($args);
// then use foreach to loop the $posts
The Loop way
<?php if (have_posts() ): ?>
<?php while (have_posts() ): the_post(); ?>
...
<?php endwhile; ?>
<?php endif; ?>
So which one more efficient?
From what I searched, get_posts()
is for custom template while The Loop
is used inside the template that follows WordPress naming convention.
I prefer get_posts()
but if there’s a big overhead compared to The Loop, I should re-think it again.
When WordPress include the
category.php
(just like any other template) the main query (i.e. the query triggered by the url) is already ran: it means that a query on database was already fired and this is the reason why in a template you can run the Loop without calling a query.If you call
get_posts
you ran another query to database, that is completely unnecessary once is identical to the one already ran by WordPress.Also note, that
get_posts
is just a wrapper forWP_Query
so the difference from using the Loop and using theforeach
syntax, does not regard the query itself, but the way you use the result of the query.If you prefer
foreach
overwhile
(the Loop is just awhile
loop) you can use it also calling directlyWP_Query
:So why normally people use the Loop instead of this kind of loop? for 2 reason, at least:
Setup of global
$post
object. When you callthe_post()
inside the Loop, that function globalize the variable$post
containing the current post object. A lot of core functions and plugins rely on that variale, so often is important to setup. However, it can be set up also using a foreach loop, usingsetup_postdata
function, the previous code becomes:Second reason regards template tags, over the direct access to post object properties: when you call
the_title
orthe_content
(or other template tags) filters are fired before output the property, and if you don’t call them, the output can be not the one you expect, again this can be done manually in our foreach loop:Last code block, can be considered almost identical to the Loop.
I said almost because there’s another thing that differe: 2 action hooks,
loop_start
andloop_end
, fired by the Loop. Some plugins can use them, so for better compatibility you should do something like:As already said, this is better used for custom loops, but regarding the main query, calling another
WP_Query
is bad for performance and unnecessary. However, the main query is just aWP_Query
instance, saved in the global variable$wp_query
, so if in your template you do something like:you are doing something very similar (pratically identical) to the Loop, just quite more verbose, but if you just hate
while
loops…In conclusion, regarding main query, for compatibility reasons is advisable (but not mandatory) use the Loop: if you don’t trigger anction and filter hooks there are chance that if you install any plugins some of them will not work…
But for custom loops, sometimes, you don’t need (or you don’t want) to trigger action and filter hooks, and the
foreach
syntax can be preferable in that cases.