Wordpress - is get_posts() more efficient than The Loop? - php

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 is more efficient?
From what I have found in searching, get_posts() is for custom templates while The Loop is used inside the template that follows the Wordpress naming convention.
I prefer get_posts(), but if there's a big overhead compared to The Loop, I should re-think it again.

I finally found the answer.
When we open a page using the right template (template that follows the naming convention), Wordpress automatically do query to get all the relevant posts or content
So if I use $posts = get_posts($args);, it means I do additional query which is unnecessary.
$posts = get_posts($args); should only be used outside template for example on sidebar that always be there on every pages.

Related

Why do we use two different loops to create multiple and static wp-query loops?

Why do we use two different loops to create multiple and static wp-query loops?
1_to modify loops & create multiple loops
<?php $the_query = new WP_Query( $args ); ?>
<?php if ( $the_query->have_posts() ) : ?>
<?php while ( $the_query->have_posts() ) : ?>
<?php $the_query->the_post(); ?>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php endif; ?>
2_to create static loop
<?php $custom_posts = get_posts( $args ); ?>
<?php if ( $custom_posts ) : ?>
<?php foreach ( $custom_posts as $post ) : ?>
<?php setup_postdata( $post ); ?>
<?php endforeach; ?>
<?php wp_reset_postdata(); ?>
<?php endif; ?>
This is not easy to understand (and also not to explain) from the outside because of side-effects (and what not).
The first example is making use of these as $the_query->the_post() pushes the current post of the query into the global state (invisible in your code) and moves $the_query to the next element (or the ending terminator).
On the other hand the second example works differently: get_posts( $args ) returns an array that is then iterated over with foreach and each array value - the $post - then needs to be "set-up": again the global state is modified, to create the wanted side-effect, now by setup_postdata( $post );.
Why do we use two different loops to create multiple and static wp-query loops?
Because uncle Matt. There might have been a distraction during important Instagram shootings that prevented the common "Code is poetry" mantra to fully expose its beauty and you just found that historic glitch in the matrix.
Or a clone of Dolly said "hello" and that was part of the confusion as sheep normally don't speak.
The honest truth is, that we can't say here on Stackoverflow, but only the original author(s) if they are willing to remember.
If you can share the actual Wordpress version and the files and the lines of code, it would be possible to at least give reference to the history of these (which can sometimes reveal a rationale if documented with the code). Question remains if it would be really worth to dig deeper on that one.
I suggest to study https://php.net/foreach for more insights as that one is most often the best first utility for loops. Don't take Wordpress code too seriously, there are better examples (there actually was a time where there was no foreach in PHP and the first example is likely originating from that time - maybe 15 years ago or so.).

Wordpress single.php another get_post function destory the first function

I am trying to deal with two get_post functions, in single.php the first get_post function is the post from the wordpress, But after that I called get_post function to other post also to use both of them in the same page but after I call the first get_post ( the main post ) I get the only second data and cant reach the first data.
My code called to the second function ( The first is from wordpress post):
$main_post = get_field('main_post');
$main_p = get_post($main_post->ID);
Then I am trying to use the variable $post OR the_title() OR any other functions to get the first post and it always returning the info of the $main_p post
for example
get_the_title( get_post()->ID )
returns the $main_p post id and not the main post of the single.php
any soulutions ?
I may be wrong, but it seems to me that you are trying to post a different post format with normal post format?
I, myself use get_post_format() so it can be styled differently or have different options.
in single.php I use
<!-- checking if there are any blogposts to be shown using have_posts check which is a wordpress function-->
<?php if(have_posts()) : ?>
<?php while(have_posts()) : the_post(); ?> <!-- the correct syntax for while loop in wordpress to show all the blogposts -->
<?php get_template_part('content', get_post_format()); ?>
<?php endwhile; ?>
<?php else : //else stament if there aren't any posts (put inside if before endif)?>
<p><?php __('No Posts Found'); ?></p>
<?php endif; ?> <!-- stop checking for blog posts-->
</div><!-- /.blog-main -->
Inside functions.php I activated the post-formats inside wp_theme_setup() function
add_theme_support('post-formats', array('aside', 'gallery'));
In this case i activated the gallery and aside posts
That way I have 2 different post types on one page
like this
image from my theme blog page
Here is also a video tutorial on post formats from Traversy media
https://www.youtube.com/watch?v=CRa7eiqyiCM&list=PLc5p9nvpdwBlrNU0hr1f0kXPRkh0aGo1Q&index=7
The key reason why your post values are being overwritten, the additional get_post() declarations are overriding the default query. Now, the code in your pastebin is a pretty massive dog's breakfast, so a direct solution is a rather large undertaking (e.g. the indentation is all over the place, the code snippets are less than ideal regarding their readability, etc...). However, I can point you in the right direction for the solution.
When I pull content from another page on my WordPress sites, I avoid using get_post() in favour of declaring a fresh new WP_Query() (that's just my preference), following it up with a wp_reset_postdata() declaration.
Here's an example of multiple queries on a single template in the WordPress codex:
https://codex.wordpress.org/Class_Reference/WP_Query#Multiple_Loops
The key here is the wp_reset_postdata(). I'd recommend looking into it's purpose. It'll save you a lot of grief:
https://codex.wordpress.org/Function_Reference/wp_reset_postdata

Less posts in loop than in object $wp_query

i'm seeing some strange behaviour I cannot explain inside a category-based template loop.
i have a custom query filter for the category template, preselecting a couple of custom post types to query for:
add_filter( 'pre_get_posts', 'cust_posts_collection' );
function cust_posts_collection( $query ) {
if ( (is_category() && $query->is_main_query()) )
$query->set( 'post_type', array( 'cust_post_type_1', 'cust_post_type1' ) );
return $query;
}
this results in a proper $wp_query object, containing among others an array of posts. let's say for a given category x there are 4 posts. when i var_dump $wp_query i can verify
["posts"]=>&array(4)
and i can see all the posts and their data in the dump.
however, when i loop then over that object:
<?php if ( $wp_query->have_posts() ) while ( $wp_query->have_posts() ) : $wp_query->the_post();
var_dump($post);
endwhile; ?>
all i see is two posts.
how is this possible?
are there any configuration defaults on the loop functions that i am missing?
I was able to solve the bug:
it turns out that there was another loop in the header partial, prior to the loop exposing the bug.
the first loop had a break statement right after an if conditional - the idea: find the first occurrence of a certain custom post type and then break out of the loop.
the problem: this break did not properly reset a global post index variable or something along those lines. the next loop then got a wrong state of the index, causing it to jump as many initial posts as had been looped over in the previous loop.
adding rewind_posts() just before the break fixed this for me.

Add custom posts to search (separately to categories) in Wordpress

I have a search results page under construction, and it splits the posts out in to categories (products, recipes, articles), in 3 separate sections down the page. The categories (recipes and articles) were fine and easy - creating a query to use in 2 separate loops, but I'm having trouble with the custom post type.
I want to pull these in with the loop as well if possible, but not sure whether to do it on the post type or taxonomy. The products are obviously split in to sub categories under the taxonomy, so when I tried it, it was pulling the same product multiple times.
Right now, having given up on trying to pull them through using the taxonomy, I am trying this:
<?php
$args = array(
'post_type'=> 'products'
);
$products = new WP_Query($args);
if ( have_posts() ) :
?>
<div class="product suggestions cfx sub-range">
<h2>We found xx products...</h2>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
This code isn't pulling anything through...will a different query work, or should I still be trying to use the custom taxonomy?
When I search for a solution, pretty much everything I can find is creating a search.php page for displaying only custom post types, or just adding the custom post type to search results, not having a separate loop for custom post types along side the loops for categories...
Thanks
I think I got it. I changed the slug from products and it started working for some reason. So now i have this:
<?php
$args = array ('post_type'=>'product-ranges');
$products = new WP_Query($args);
if ( have_posts() ) :
?>
<div class="product suggestions cfx sub-range">
<h2>We found xx products...</h2>
<?php while ( $products->have_posts() ) : $products->the_post();
?>

Required Wordpress specific category posts display on static page with newer order at the top

I have two different post categories ("Local" & "International") in WordPress and I have displayed the posts in my static page. Right now both categories post are coming on one page. Can I show only local posts in local.php and International posts in International.php page? Also another change please. Can I show newer posts at the top? Right now older post is at the top.
Following is my code.
<?php
require('wp-blog-header.php');
?>
<?php
$posts = get_posts('numberposts=10&order=ASC&orderby=post_title');
foreach ($posts as $post) : start_wp(); ?>
<?php echo "<h1>";the_date();echo "</h1>"; ?>
<?php the_title(); ?>
<?php the_excerpt(); ?>
<?php
endforeach;
?>
Assuming custom page as a page in yours custom plugin. you will need to load wp-load.php to use the WordPress function/loops to fetch the information.
you will need
require_once("../../../wp-load.php"); // ../../../ according to you file location
// now you can loop using get_posts
$posts = get_posts('numberposts=10&category=CATEGORY_ID&order=DESC&');
// loop
If this is not in WordPress, you have to connect to MySQL and the fetch the information from tables with you SELECT query.
Use
$posts = get_posts('numberposts=10&order=DESC&category=[categoryID]&orderby=post_title');
in local.php respectively International.php. Notice that order=DESC instead of order=ASC, this reverses the post order. And be sure to use the appropriate categoryIDs. You find them in your Wordpress administration area.

Categories