Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have a page where I've got all the products on a single page. -- Link to the test site.

What I'd like to do is to get the products ordered using their categories. Juices, nectars, concentrates, etc.

The usual

$orderby =

id
name 
slug
count
term_group 

doesn't get them ordered the way needed. Is it even possible and if so, how would I achieve this?

My products.php:

<?php
/*
Template Name: Products
*/
get_header();
?>
</div>

<?php
$orderby = 'name';
$show_count = 0; // 1 for yes, 0 for no
$pad_counts = 0; // 1 for yes, 0 for no
$hierarchical = 1; // 1 for yes, 0 for no
$taxonomy = 'mahlakategooriad';
$title = '';
$args = array(
'orderby' => $orderby,
'show_count' => $show_count,
'pad_counts' => $pad_counts,
'hierarchical' => $hierarchical,
'taxonomy' => $taxonomy,
'title_li' => $title
);
$term_obj =  get_terms($taxonomy,$args);
$type = 'produktid';
$args = array( 'post_type' => 'produktid', 'posts_per_page' => 1);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post(); ?>
    <?php
    echo '<div class="main small">';
    echo '<h1><a href="'.get_permalink().'">'.get_the_title().'</a></h1>';
    the_content();
    echo '</div>';
?>
<div class="big-pic"><?php echo get_the_post_thumbnail( $loop->post->ID, 'tooted-big' ); ?></div>
<?php
endwhile;
$args=array(
    'post_type' => $type,
    'post_status' => 'publish',
    'posts_per_page' => -1,
    'caller_get_posts'=> 1,
    'orderby' => 'date', 
    'order' => 'ASC' 
);
$my_query = null;
$my_query = new WP_Query($args);
if( $my_query->have_posts() ) {
?>
<div class="tooted">
<?php 
    while ($my_query->have_posts()) : $my_query->the_post(); ?>
    <?php 
    $toote_thumb = get_the_post_thumbnail( $page->ID, 'tooted-thumb' ); 
    $toote_big = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'tooted-big' );
    if ($toote_thumb) {
        echo '<div class="toode">';
        echo '<a href="'.get_permalink().'" class="toote-thumb" data-link="'.$toote_big[0].'">'.$toote_thumb.'</a>';
    }
    ?>
    <a href="<?php the_permalink() ?>" title="<?php the_title_attribute(); ?>" class="toote-title"><?php the_title(); ?></a></div>
    <?php
    endwhile;
}
wp_reset_query();
?>
<div class="clear"></div>
</div>
<div class="clear"></div>
share|improve this question

1 Answer 1

up vote 0 down vote accepted

Before answer I want to say that your code is not really wrong but can be improved:

  1. why run 2 queries when you can run only one?
  2. caller_get_posts is deprecated, use ignore_sticky_posts, instead
  3. get_terms has not title_li nor show_count argument. Moreover $taxonomy is the first argument and do nothing in the $args array (second argument). Seems your arguments are intended wp_list_categories function.
  4. you get the terms from mahlakategooriad taxonomy, but you do no use them in the template. Maybe don't you post all the code?
  5. You set $wp_query to null before effectively fill it? Why? Moreover you use wp_reset_query that is not needed on custom query. Use wp_reset_postdata, instead.

Let's anwer.

The workflow I will follow is run one posts loop, put in a helper array the posts using their category slug as key. During the loop I also put in another variable the first sticky post.

When array is filled I start loop through it and output the markup.

// get posts
$args = array(
  'post_type' => 'produktid',
  'posts_per_page' => -1,
  'orderby' => 'date', 
  'order' => 'ASC' ,
  'ignore_sticky_posts' => true
);
$my_query = new WP_Query( $args );

// init helper vars
$first = null;
$sticky = null;
$ordered = array();

// loop
while ( $my_query->have_posts() ) : $my_query->the_post();    
  $terms = get_the_terms( get_the_ID(), 'mahlakategooriad' );
  $term = array_shift($terms); // get first term
  global $post;
  if ( ! isset($ordered[$term->slug]) ) $ordered[$term->slug] = array();
  $ordered[$term->slug][] = $post;
  if ( $my_query->current_post == 0 ) $first = $post;
  if ( is_null($sticky) && is_sticky() ) $sticky = $post;   
endwhile;
wp_reset_postdata();

// get the array of term slugs and order it by name
$terms = array_keys( $ordered );
sort( $terms );

// get the big thumbnail and print it
$featured = $sticky ? : $first;
if ( ! empty($featured) ) {
  global $post;
  setup_postdata($post);
  echo '<div class="main small">';
  echo '<h1><a href="' . get_permalink() . '">' . get_the_title() . '</a></h1>';
  the_content();
  echo '</div>';
  $big_img = get_the_post_thumbnail( $featured->ID, 'tooted-big' );
  if ( ! empty( $big_img ) ) printf('<div class="big-pic">%s</div>', $big_img);
}
wp_reset_postdata();

// the loop
echo '<div class="tooted">';
if ( ! empty($terms) ) { foreach ( $terms as $term ) {
  $ordered_posts = $ordered[$term];
  $term_obj = get_term_by('slug', $term, 'mahlakategooriad');
  printf('<h3>' . __('Products in %s') . '</h3>', $term_obj->name ); 
  global $post;
  foreach ( $ordered_posts as $post) {
     setup_postdata($post);
     $thumb_id = get_post_thumbnail_id( get_the_ID() );
     $plink = get_permalink();
     $title = get_the_title();
     if ($thumb_id) {
       $thumb = wp_get_attachment_image_src( $thumb_id, 'tooted-thumb' ); 
       $big = wp_get_attachment_image_src( $thumb_id, 'tooted-big' ); 
       echo '<div class="toode">';
       printf(
         '<a href="%s" class="toote-thumb" data-link="%s"><img src="%s" alt="%s" /></a>',
         $plink, $big[0], $thumb[0], esc_attr($title)
       );
    }
    printf(
      '<a href="%s" title="%s" class="toote-title">%s</a></div>',
      $plink, esc_attr($title), $title
    );
  }
  echo '<div class="clear"></div>';
} }
wp_reset_postdata();
echo '<div class="clear"></div></div><div class="clear"></div>';
share|improve this answer
    
When implementing the code I'm getting: Fatal error: Call to undefined function print_f() in /data03/virt21594/domeenid/www.must.ee/htdocs/largo/wp-content/themes/largo/prod‌​uktid.php on line 43 I've also committed all the relevant code here. –  Martin Metsalu Aug 19 '13 at 17:59
    
@MartinMetsalu it was just a typo. Function right name is printf not print_f. I've used several times in this code and only one time was written bad. I've fixed the error and now it should works. If you want test again copy all the code, because I've corrected 2 other typos. –  G. M. Aug 19 '13 at 18:44
    
I can see that the filter is working, which is real good. Only thing is that the small thumbnails are not showing and that the description part is missing. –  Martin Metsalu Aug 20 '13 at 12:00
    
@MartinMetsalu the description part as missing because I've forgot to add a piece of your code. Now it's there. The small thumbnails were missing because of a typo ('$' instead of '%'). Now it should full works. –  G. M. Aug 20 '13 at 12:42
    
it worked like a charm. Thank you very much. I just got one more question about this line of code printf('<h3>' . __('Products in %s') . '</h3>', $term_obj->name );. How would you alter it to leave out the Products in ... on the products page? –  Martin Metsalu Aug 20 '13 at 15:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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