Can someone please explain how "$posts" is used within the loop?
It returns the array of queried posts , but it is insignificant and not used at all: if you remove it than the code works the same:
if (have_posts()) : while (have_posts()) : the_post();
This is because
query_posts() override global
$wp_query object, that is the same query object that loop functions like
the_post() use to display posts.
and this is the reason why that function should not be used:
- overriding a widely used global variable it easily has side effects
- it is very slow, because you override a already ran query with another, running query to database 2 times.
If you need a separate query from main (global) query, than make no sense override main query, just perform a secondary query using
WP_Query object or
If you need to modify main query, than modify it before it runs, in this way you'll run only 1 query instead of 2 and your code will be faster. To edit main query before it runs, use
'pre_get_posts' action hook.