WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] Problem with nested loops (10 posts)

  1. sugardaddy
    Member
    Posted 1 year ago #

    Hi everyone !
    I just met a big problem with nested loops.
    I have a WP_Query (which is inside the main loop), and want to have in it two more loops by get_posts.
    My second loop doesn't work at all (videos).
    My loop gets documents (custom post type), then inside it I get attachments and then only documents from a particular category (videos).
    It's been a long time I'm working on it... so maybe somebody could see the error, better than me !
    Thanks a lot for your help.
    Here's the code :

    <?php $docs = new WP_Query('post_type=documents&orderby=date&order=ASC');
    				while ( $docs->have_posts() ) : $docs->the_post();
    
    				$docs_display = simple_fields_value('pageproduit');
    				$docs_current_product = simple_fields_fieldgroup('produits');
    				$docs_product = (implode(array_keys(array_filter($docs_current_product))));
    
    				// if we check the document to be on product page
    				if( (strpos($docs_product, $product) !==false) && ($docs_display == 1) ) {
    
    				// get the cat name
    				$terms = get_the_terms($post->ID, 'docs_cat');
    					foreach ( $terms as $term ) {
    						$cat = $term->name;
    					}
    
    				// PDF documents (attachments of posts)
    				$args = array( 'post_mime_type' => 'application/pdf', 'post_type' => 'attachment', 'numberposts' => -1, 'post_parent' => $post->ID );
    				$attachments = get_posts($args);
    					if ($attachments) {
    						foreach ( $attachments as $attachment ) {
    							echo '<li>';
    							the_post_thumbnail(array(70,98));
    							echo '<p>';
    							the_attachment_link( $attachment->ID , false );
    							$type = get_post_mime_type( $attachment->ID );
    							if( $type == 'application/pdf' ) :
    								echo '<small>'.$cat.'<br />PDF';
    							endif;
    							echo ' (' . size_format( filesize( get_attached_file( $attachment->ID ) ) ) . ')</small></p></li>';
    						}
    					} else {}
    				wp_reset_postdata();
    
    				// videos
    				$args = array( 'cat' => '173');
    				$videos = get_posts($args);
    					if ($videos) {
    						foreach ($videos as $video) {
    					    	echo '<li class="video">';
    	    			    	the_post_thumbnail(array(175,98));
    	    			    	echo '<p><a>'.the_title('','',false).'</a>';
    	    			    	echo '<small>'.$cat.'</small></p>';
    	    			    	echo '</li>';
        			    	}
        			    } else {}
        			wp_reset_postdata();
    
    				} else {} // end of if we check the document to be on product page
    
    				endwhile; wp_reset_postdata(); // end of while documents
    
    				?>
  2. sugardaddy
    Member
    Posted 1 year ago #

    I just understand where my mistake could be.
    I try to make a new query but I can do an IF passing the term name.
    But, and this is THE problem I'm trying to resolve, I have to write a query with cat ID to be compliant with WPML (multilingual plugin).
    I think I will write a new query outside the WP_Query loop but I was wondering if there's an elegant solution to achieve that in the same Query (by passing the ID of a custom taxonomy).

  3. sugardaddy
    Member
    Posted 1 year ago #

    It works with a second loop, but I get 2 more posts display (as many of the first loop + the correct post) in wrong taxonomy, even if I exclude the taxonomy id from the first loop.
    Here's the new code :

    $docs = new WP_Query('post_type=documents&orderby=date&order=ASC');
    				while ( $docs->have_posts() ) : $docs->the_post();
    
    				$docs_display = simple_fields_value('pageproduit');
    				$docs_current_product = simple_fields_fieldgroup('produits');
    				$docs_product = (implode(array_keys(array_filter($docs_current_product))));
    
    				// if we check the document to be on product page
    				if( (strpos($docs_product, $product) !==false) && ($docs_display == 1) ) {
    
    				// get the cat name
    				$terms = get_the_terms($post->ID, 'docs_cat');
    					foreach ( $terms as $term ) {
    						$cat = $term->name;
    					}
    
    				// PDF documents (attachments of posts)
    				$args = array(
    					'post_mime_type' => 'application/pdf',
    					'post_type' => 'attachment',
    					'numberposts' => -1,
    					'post_parent' => $post->ID,
    					'tax_query' => array(
    						array(
    							'taxonomy' => 'docs_cat',
    							'field' => 'id',
    							'terms' => 173,
    							'operator' => 'NOT IN'
    						)
    					)
    					);
    				$attachments = get_posts($args);
    					if ($attachments) {
    						foreach ( $attachments as $attachment ) {
    							echo '<li>';
    							the_post_thumbnail(array(70,98));
    							echo '<p>';
    							the_attachment_link( $attachment->ID , false );
    							$type = get_post_mime_type( $attachment->ID );
    							if( $type == 'application/pdf' ) :
    								echo '<small>'.$cat.'<br />PDF';
    							endif;
    							echo ' (' . size_format( filesize( get_attached_file( $attachment->ID ) ) ) . ')</small></p></li>';
    						}
    					} else {}
    				wp_reset_postdata();
    
    				// videos
        			$videosargs = array(
        				'post_type' => 'documents',
        				'orderby' => 'date',
        				'order' => 'ASC',
        				'tax_query' => array(
        					array(
        						'taxonomy' => 'docs_cat',
        						'field' => 'id',
        						'terms' => 173
        					)
        				)
        			);
        			$videos = new WP_Query($videosargs);
        			while ($videos->have_posts() ) : $videos->the_post();
        				echo '<li class="video">';
    	    			the_post_thumbnail(array(175,98));
    	    			echo '<p><a>'.the_title('','',false).'</a>';
    	    			echo '<small>'.$cat.'</small></p>';
    	    			echo '</li>';
        			endwhile;
    
    				} else {} // end of if we check the document to be on product page
    
    				endwhile; wp_reset_postdata(); // end of while documents
  4. sugardaddy
    Member
    Posted 1 year ago #

    Well, it seems I need a combination of loops, like here : https://gist.github.com/billerickson/1762204 But as I need a different display, I don't visualize how to achieve it.

  5. sugardaddy
    Member
    Posted 1 year ago #

    To simplify the problem at this time : I have a loop and a nested loop which is quite the same. And that code doesn't work at all :

    $docsargs = array(
      'post_type' => 'documents',
      'orderby' => 'date',
      'order' => 'ASC',
      'tax_query' => array(
        array(
          'taxonomy' => 'docs_cat',
          'field' => 'id',
          'terms' => array( 173 ),
          'operator' => 'NOT IN'
        )
      )
    );
    $docs = new WP_Query($docsargs);
    while ( $docs->have_posts() ) : $docs->the_post();
    // objects
    
    // second nested loop
    $videosargs = array(
      'post_type' => 'documents',
      'orderby' => 'date',
      'order' => 'ASC',
      'tax_query' => array(
        array(
          'taxonomy' => 'docs_cat',
          'field' => 'id',
          'terms' => array( 173 ),
          'operator' => 'IN'
        )
      )
    );
    $videos = new WP_Query($videosargs);
    while ($videos->have_posts() ) : $videos->the_post();
    // objects
    endwhile;
    
    endwhile;

    And the goal is to exclude posts from the first loop but not from the nested one... not so easy ! And what I get is the 2 documents from the first loop with the attachment of the doc from the nested loop. So my first loop doesn't get the posts...

  6. sugardaddy
    Member
    Posted 1 year ago #

    Well, at the end, I completely separate my queries but it's dirty as I repeat some functions like the filter wether a custom field has a certain value or not.
    Still curious to find a better way to write this.

  7. keesiemeijer
    moderator
    Posted 1 year ago #

    Try adding wp_reset_postdata() after the inner loop:
    http://codex.wordpress.org/Function_Reference/wp_reset_postdata

  8. sugardaddy
    Member
    Posted 1 year ago #

    I did it...

  9. sugardaddy
    Member
    Posted 1 year ago #

    But my last example is wrong because I exclude the posts from a custom taxonomy so I can't get them after...
    What I try to do is to have a loop on a custom post type, then having a loop inside for some custom taxonomy (plus a get_posts to get the attachments), and another one for a particular custom taxonomy.
    Litteraly, that means I want to display all the posts (from a custom post type) but displayed differently (by custom taxonomy). These are documents, and I cannot display videos as PDF. And videos are not attachments but links to third-party players.
    Behind this, I MUST call id's (for taxonomies) because I need it to work with WPML (which translate id's), so it excludes the possibility to filter with if statements.

  10. sugardaddy
    Member
    Posted 1 year ago #

    Finally I did it that way :

    Querying all the documents

    $docsargs = array(
      'post_type' => 'documents',
      'orderby' => 'date',
      'order' => 'ASC'
    );
    $docs = new WP_Query($docsargs);
    while ( $docs->have_posts() ) : $docs->the_post();

    Doing a test on some custom fields

    $docs_display = simple_fields_value('pageproduit');
    $docs_current_product = simple_fields_fieldgroup('produits');
    $docs_product = (implode(array_keys(array_filter($docs_current_product))));
    
    // if we check the document to be on product page
    if( (strpos($docs_product, $product) !==false) && ($docs_display == 1) ) {

    Getting some stuff for the taxonomy

    $terms = get_the_terms($post->ID, 'docs_cat');
      foreach ( $terms as $term ) {
        $cat = $term->name;
        $catid = $term->term_id;
        $catslug = $term->slug;
      }

    Doing a test by special taxo and using the WMPL function to translate the ID

    if ($catid == icl_object_id(173, 'docs_cat', false) ) {
      echo '<li class="video"><a class="launchvideo videoscreen" href="'.get_permalink().'">';
      the_post_thumbnail(array(175,98));
      echo '</a><p><a class="launchvideo" href="'.get_permalink().'">'.the_title('','',false);
      echo '<small>'.$cat.'</small></a></p>';
      echo '<div style="display:none">';
      the_content();
      echo '</div>';
      echo '</li>';
    }

    Else the other documents... which could be enhanced for getting different displays

    else {
      $args = array(
        'post_mime_type' => 'application/pdf',
        'post_type' => 'attachment',
        'numberposts' => -1,
        'post_parent' => $post->ID,
      );
      $attachments = get_posts($args);
        if ($attachments) {
          foreach ( $attachments as $attachment ) {
            echo '<li><a href="'.wp_get_attachment_url( $attachment->ID ).'">';
            the_post_thumbnail(array(70,98));
            echo '</a><p>';
            the_attachment_link( $attachment->ID , false );
            $type = get_post_mime_type( $attachment->ID );
            if( $type == 'application/pdf' ) :
              echo '<small>'.$cat.'<br />PDF';
            endif;
            echo ' (' . size_format( filesize( get_attached_file( $attachment->ID ) ) ) . ')</small></p></li>';
          }
        } else {}
    
      } // end of if type of document
    
    } else {} // end of if we check the document to be on product page
    endwhile; wp_reset_postdata(); // end of while documents

Topic Closed

This topic has been closed to new replies.

About this Topic