WordPress.org

Make WordPress Core

Opened 2 years ago

Last modified 3 months ago

#19949 new enhancement

Make update_post_thumbnail_cache() work for any instance

Reported by: scribu Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version:
Component: Post Thumbnails Keywords: has-patch 3.5-early
Focuses: performance Cc:

Description

It would be useful if update_post_thumbnail_cache() [17883] would accept an optional $wp_query parameter, so that users aren't forced to use query_posts() in order to benefit from it.

Attachments (1)

19949.diff (707 bytes) - added by scribu 2 years ago.

Download all attachments as: .zip

Change History (17)

scribu2 years ago

comment:1 Ploobers2 years ago

Awesome. Easy fix that can have major ramifications on site performance. This will reduce my database calls by over 100 per page without having to do my own queries or leave the WP API.

comment:2 scribu2 years ago

Example usage:

$my_query = new WP_Query( array( 'tag' => 'foo' ) );

update_post_thumbnail_cache( $my_query );

while ( $my_query->have_posts() ) : $my_query->the_post();

  the_post_thumbnail();

endwhile;

Well, actually, that would also cause an update_post_thumbnail_cache() call for the main query, which might be unnecessary.

Version 0, edited 2 years ago by scribu (next)

comment:3 scribu2 years ago

  • Keywords commit removed

comment:4 follow-up: scribu2 years ago

It bugs me how we seem to be pushing users towards query_posts() instead of away from it.

comment:5 in reply to: ↑ 4 nacin2 years ago

Replying to scribu:

It bugs me how we seem to be pushing users towards query_posts() instead of away from it.

I agree.

comment:6 nacin2 years ago

Just a thought:

class Nacin_Cache_Thumbnails_for_Queries {
   public $loops = array();
   function __construct() {
      add_action( 'loop_start', array( $this, 'loop_start' ) );
      add_action( 'loop_end', array( $this, 'loop_end' ) );
      add_action( 'begin_fetch_post_thumbnail_html', array( $this, 'fetch_thumbnail' ) );
   }
   function loop_start( $query ) {
      array_push( $this->loops, $query );
   }
   function loop_end() {
      array_pop( $this->loops );
   }
   function fetch_thumbnail() {
       $query = end( $this->loops );
       update_post_thumbnail_cache( $query );
   }
}
new Nacin_Cache_Thumbnails_for_Queries;

comment:7 nacin2 years ago

  • Keywords 3.5-early punt added

Per conversation in IRC, let's come up with the appropriate balance of API and voodoo, and revisit in 3.5.

comment:8 scribu2 years ago

On the one hand, it would be nice if developers would never have to call update_post_thumbnail_cache() manually. Nacin's solution works pretty well in that respect.

On the other hand, it wouldn't work at all with get_posts().

Ideally, we would have both:

  1. a standalone function that, given an array of posts, caches the thumbnail attachments
  2. some magic that calls that function automatically for any Loop
Last edited 2 years ago by scribu (previous) (diff)

comment:9 nacin2 years ago

In [20646]:

Add $wp_query parameter to update_post_thumbnail_cache(). props scribu. see #19949, fixes that ticket for 3.4.

comment:10 nacin2 years ago

  • Milestone changed from 3.4 to Future Release

comment:11 SergeyBiryukov18 months ago

  • Keywords punt removed

comment:12 follow-up: Ploobers17 months ago

Is this going to make it into 3.5?

comment:13 in reply to: ↑ 12 nacin17 months ago

Replying to Ploobers:

Is this going to make it into 3.5?

Negative. This ticket needs a burst of creativity.

In many respects it is a rethink for how the loop works. Imagine if a post could be tied as coming from a loop (a collection of posts), and when terms, meta, or featured images gets called for that post, we attempt to query all other posts in that collection at once.

comment:14 Ploobers17 months ago

It's become very frustrating for me to try and maintain two separate query styles, as I prefer to use the built-in get_posts, but as I'm using thumbnails all over my site in custom loops, not having the images cached is causing 50-150 extra queries per page. In the meantime, I've just been using my own direct query.

SELECT p.ID, p.post_title, p.post_name, p.post_parent, p.post_type, a.ID AS image_id,
		MAX( IF ( apm.meta_key='_wp_attachment_metadata', apm.meta_value,' ') ) as 'image_data',
		MAX( IF ( apm.meta_key='_wp_attached_file', apm.meta_value,' ') ) as 'filepath'
		FROM sr_posts p
		INNER JOIN sr_postmeta pm ON p.ID = pm.post_id
		INNER JOIN sr_posts a ON pm.meta_value = a.ID
		INNER JOIN sr_postmeta apm ON a.ID = apm.post_id
		WHERE p.post_parent = '$connect_id'
		AND pm.meta_key = '_thumbnail_id'
		AND ( apm.meta_key = '_wp_attachment_metadata'
		OR apm.meta_key = '_wp_attached_file')
		$where GROUP BY p.ID

comment:15 Ploobers17 months ago

Even if running the meta cache is an expensive call, it doesn't even have to be auto-tied into the loop. It could be something for advanced calls through new WP Query objects. As scribu said, it'd be great if it magically worked everywhere, but even a manual call would be a huge improvement.

comment:16 nacin3 months ago

  • Component changed from Performance to Post Thumbnails
  • Focuses performance added
Note: See TracTickets for help on using tickets.