+1 to both of the other answers, for explaining the primary differences between actions and filters.
However, to answer your specific question, about which to use for modifying a query:
- Injecting your custom query into the template does, as you guessed, require hooking into an existing action. (Whether or not
wp_footer
is the correct/ideal action is another matter, and would depend on exactly how you intend to use said query. - Allowing your custom query is probably best accomplished using a custom filter, that other Plugins can hook into.
For example, starting with this code:
function get_page_list() {
$pages_args = array(
'post_type' => 'page',
'posts_per_page' => '1'
);
$pages_query = new WP_Query( apply_filters( 'myfilter', $pages_args ) );
if( $pages_query->have_posts() ) {
while ( $pages_query->have_posts() ) : $pages_query->the_post();
echo get_the_title();
endwhile;
// Reset Post Data
wp_reset_postdata();
}
else echo 'no results found';
}
add_action( 'wp_footer', 'get_page_list', 1);
If you want this code to be extensible, you need to provide a way for others to extend it. I would recommend making your custom query args extensible, via custom filter. e.g. this:
$pages_args = array(
'post_type' => 'page',
'posts_per_page' => '1'
);
…could easily become this:
$pages_args = apply_filters(
'custom_filter_name',
array(
'post_type' => 'page',
'posts_per_page' => '1'
)
);
Which would then allow other Plugins to modify your query args. For example, if a Plugin wanted to return two posts, instead of one:
function wpse73840_modify_custom_filter_name( $args ) {
// Modify posts_per_page
$args['posts_per_page'] = '2';
// Return modified args
return $args;
}
add_filter( 'custom_filter_name', 'wpse73840_modify_custom_filter_name' );
I think this gets to what you’re asking. If not, let me know in the comments.