[wp-trac] [WordPress Trac] #36097: wp_filter reset after sub-queries

WordPress Trac noreply at wordpress.org
Fri Mar 4 23:57:03 UTC 2016


#36097: wp_filter reset after sub-queries
--------------------------+-----------------------------
 Reporter:  cartpauj      |      Owner:
     Type:  defect (bug)  |     Status:  new
 Priority:  normal        |  Milestone:  Awaiting Review
Component:  Query         |    Version:  4.4.2
 Severity:  normal        |   Keywords:
  Focuses:                |
--------------------------+-----------------------------
 I have a shortcode which implements a sub-query and loops through calling
 the_content() in the process. At the end I call wp_reset_query() and
 wp_reset_postdata().

 That's all fine and good, but the problem I'm experiencing is that the
 content from the main query (where the shortcode was placed to begin with)
 no longer executes any filters on the_content.

 Here's a real world example of what I'm experiencing. Let's say I have a
 shortcode [some-custom-loop] which outputs a custom loop.

 {{{
 function my_shortcode_callback($atts, $content = '') {
     global $post;
     global $wp_query;

     $args          = array(//SOME ARGS HERE//);
     $original_post = $post;
     $wp_query      = new WP_Query($args);

     ob_start();

     while($wp_query->have_posts()) {
       $wp_query->the_post();

       //Avoid infinite loop
       if($original_post->ID === $post->ID) {
         continue;
       }

       the_content();
     }

     // Reset the global query.
     wp_reset_query();
     wp_reset_postdata();

     return ob_get_clean();
 }
 add_shortcode('some-custom-loop', 'my_shortcode_callback');
 }}}

 Now, this filter below does not get applied to the_content of posts from
 the main query which contain this shortcode, but it is applied to
 the_content on the post(s) from the sub-query

 {{{
 function append_to_content($content) {
   return $content . "<p>Hello WP!</p>";
 }
 add_filter('the_content', 'append_to_content');
 }}}

 I'm honestly not even sure what to recommend as a fix at this point, but
 doing the following with $wp_filter global is working as a work-around for
 now.
 {{{
 function my_shortcode_callback($atts, $content = '') {
     global $post;
     global $wp_query;
     global $wp_filter; //Changed

     $original_filter = $wp_filter; //Changed
     $args            = array(//SOME ARGS HERE//);
     $original_post   = $post;
     $wp_query        = new WP_Query($args);

     ob_start();

     while($wp_query->have_posts()) {
       $wp_query->the_post();

       //Avoid infinite loop
       if($original_post->ID === $post->ID) {
         continue;
       }

       the_content();
     }

     // Reset the global query.
     wp_reset_query();
     wp_reset_postdata();

     $wp_filter = $original_filter; //Changed

     return ob_get_clean();
 }
 add_shortcode('some-custom-loop', 'my_shortcode_callback');
 }}}

 So to sum up what is happening (I think):
 1. apply_filters is called on the_content
 2. do_shortcode runs creating a sub-query
 3. apply_filters is called on the_content again since the shortcode is
 calling the_content();
 4. All of the_content's filters are run in the sub-query
 5. When the do_shortcode call is finished, all of the filters for
 the_content ($wp_filter) have already run, so any after that don't get
 called on the main content.

--
Ticket URL: <https://core.trac.wordpress.org/ticket/36097>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list