0

It would be great to make a single DB request but I don't know how to do that either. I have this code and it works but I want to change it to be more efficient:

$cs = get_categories(array(
    'orderby' => 'name',
    'order' => "ASC",
));

$params = array(
    'last_five_articles' => array()
);
foreach ($cs as $c) {
    $rp = wp_get_recent_posts(array(
        'numberposts' => 5,
        'post_status' => 'publish',
        'category' => $c->term_id
    ));

    foreach ($rp as $idx => $crt)
    {
        $rp[$idx]["post_content"] = NULL;

        $rp[$idx]["url"] = esc_url(get_permalink($crt["ID"]));

        $rp[$idx]["is_current"] = $crt["ID"] === get_the_ID();
    }

    $params['last_five_articles'][$c->slug] = $rp;
}

Update 1

The fields that I use from each post are:

  • url (custom field)
  • is_current (custom field)
  • post_title
  • post_date

The rest should be ignored.

6
  • 2
    If you want 5 (or a certain number of) posts from each category, then your code is already good - multiple wp_get_recent_posts() calls is needed.
    – Sally CJ
    Sep 17, 2021 at 15:22
  • @SallyCJ I believe it is good but I want to make it more close to optimal. I think that if this code is executed on each page load there are too many requests to the DB. Am I wrong? Sep 17, 2021 at 15:33
  • 1
    No, you're not. But that's just how it would be done, unless of course if you cache the results. (I.e. Persistent caching like set_transient())
    – Sally CJ
    Sep 17, 2021 at 15:42
  • 1
    wp_get_recent_posts is a middleman function, bypass this function and all the extra rules and weirdness it adds, if you want to get the most recent posts that sounds like you want a post query, so just use WP_Query. Afterall wp_get_recent_posts uses it. Also Sally is right, you can't do this in a single query, if you want the latest posts for each of 5 categories, it must be done in 5 queries
    – Tom J Nowell
    Sep 17, 2021 at 16:12
  • 1
    Otherwise, if the question is just how to make it faster, you need to state that clearly. You did not state that in your question, therefore that is not what you asked. Use the edit link to clarify your question otherwise Sally is right and she should write an answer. Also your title and the question content are not the same, please fix this as it is confusing
    – Tom J Nowell
    Sep 17, 2021 at 16:13

1 Answer 1

2

How to obtain the recent posts without their content?

The same way you would any other post, just don't use the post content.

Not fetching the post content will not improve performance, and may actually hurt performance. This is because WordPress would need to make an additional query if it needed the post content. When you query a post, WP primes temporary caches, this way it only requests a post once in a request, no matter how many times you ask for it.

By being more specific about which fields you want, you may think you're improving performance, but you're actually hurting it as WP can no longer cache, and has to generate bespoke couture results.

Asking only for specific fields is great for minimising bandwidth use between a server and a browser, you get a nice chunk of data with a footprint perfect for a mobile phone. But you are not a mobile phone, you're a server in a data centre, and the database is probably on the same machine.

You want to be able to cache and bulk request data so that the query is cheap and reusable. This is especially powerful when combined with object caching.

It would be great to make a single DB request but I don't know how to do that either.

This cannot be done, what you want to do requires multiple queries.

Even if you did find an API function to do it, that function would make 5 separate queries internally, no performance gains would be made.

other notes:

  • wp_get_recent_posts is a helper function. Cut it out and go directly to WP_Query
  • Posts are not arrays, they are meant to be objects of type WP_Post, so use $post->post_content instead
  • You would be better off storing either the post IDs or the post itself in $params['last_five_articles']
  • You should not modify post objects directly, it is bad practice and will cause issues and inconsistencies that lead to bugs.
    • For example, if you want to modify post titles, don't change the posts title field, use a filter to modify the output instead
3
  • 1. Is there any advantage in my situation to using WP_Query instead of wp_get_recent_posts? 2. What is wrong in grouping the posts by category into the $params['last_five_articles']? 3. In my situation I use the post objects just to set a JS variable in a script. Is it OK in this case to modify the post objects directly? Is there a way to clone the objects if it is still not OK? Sep 17, 2021 at 18:25
  • 1
    1. Yes, wp_get_recent_posts uses it internally, so cut out the extra cruft and go straight to the source 2. I think you've misunderstood, but also not shared important context ( is this an X Y problem? ), this is the first time you've mentioned this is for preparing data for inline JS 3. it sounds like you're either unaware of the REST API, or you're unaware of REST API preloading. There is a standard post JSON object complete with a schema, you don't need to reinvent it.
    – Tom J Nowell
    Sep 18, 2021 at 1:33
  • 1
    And it is never ok to modify a WP_Post object. Copy data out of it if you really must, but the object should be considered immutable and unchangable. Trying to change a WP_Post class or an object of that type is usually a sign of poor code or a misunderstanding of WP APIs.
    – Tom J Nowell
    Sep 18, 2021 at 1:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.