0

I would like to use a custom field "topic" to order Wordpress posts. This seems quite doable using

'orderby' => 'meta_value', 'meta_key' => 'topic'

But I would also like to have a title of "topic" at the start of each topic.

topic 1

  • post one on topic 1
  • post two on topic 1

topic 2

  • post one on topic 2
  • post two on topic 2

etc...

I was thinking I could have a loop that first gets the posts in order of "topic"

displays the "topic" for the first post and

then calls my templet to display the rest of the post using.

<?php get_template_part( 'partials/content', 'page' ); ?>

I could get it to continue to do this for all posts but add an if statement that says

"If the 'topic' is the same the topic for the last post do not add a topic title before posting the post"

This is the first time I have tried to come up with something new in Wordpress - not copying and pasting from examples, And I am finding it really hard to do, I just spent 2 day doing code academy PHP to try and figure it out for my self. But it is still causing me problems (complete confusion).

Any help would be really appreciated.

  • I think the easiest way to do this would be to just have a loop for each Topic and so you can physically put a title above each loop versus an if statement that has to run every post through the loop and check whether it's the first post in a specific topic. Is there any reason why you want just one loop to output all of the posts? – RachieVee Jun 27 '14 at 16:13
  • @RachieVee hey thanks for the advice! The reason for trying to do it in one loop Is that I was under the impression that each loop adds to the number of database queries and in the end can slow the page down. This page has the latest products listed by topic and will be linked to a weekly email update. It is likely going to be the landing page for most of the visitors to the site, and the majority of them will come all at the same time (when the email arrives on friday morning - or when ever it is). So I am attempting to keep the page as fast as posable. Dose this make sense? – user3497301 Jun 28 '14 at 0:17
  • p.s. I think I have solved it, writing my own answer to my question now. – user3497301 Jun 28 '14 at 0:18
2

OK I got it working. Not sure if it is the best way but I thought I would add a reply anyway.

Set up the information needed for the custom loop using $args = array As described in http://codex.wordpress.org/Class_Reference/WP_Query

$args = array(
'post_type'      => 'product',
'meta_key'       => 'wpcf-topic',
'orderby'        => 'meta_value',
'order'          => 'ASC',
'posts_per_page' => -1,
'date_query'     => array(
    array(
        'column' => 'post_date_gmt',
        'after'  => 'Monday 1 week ago',
        ),      
    ),
);

I used this to select the post type as product, order them by topic in ascending order (alphabetical order), set the posts per page to all of them (I think that is what -1 does), and finally limit it to only get the products added after "monday 1 week ago" using the new date_query introduced in Wordpress 3.7

declared a new variable with nothing in it

$last_topic="" 

started the custom loop with

$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
    while ( $loop->have_posts() ) : $loop->the_post();

set a new variable $topic to the value of my custom field using

$topic=(get_post_meta( get_the_ID(), 'wpcf-topic', true ));

( I used types plugin to create a new custom field and it adds wpcf to the start of the field meta_key so I need to use 'wpcf-MyFieldName' for the meta_key when referring to the custom field)

used an if to show the title only if $topic is not the same as $last_topic

    if ($last_topic !== $topic){ echo "<h1>"  .  $topic   .  "</h1>";
}  

Then, after the rest of my loop template I added

    $last_topic=$topic;

So now topic and last topic are the same and the topic tile will not be echoed until it changes to something different to the last one. This only makes sense because they are ordered by topic already so all products in a topic will be in the same place.

I closed the loop with

    endwhile;
wp_reset_postdata(); // resets the loop back to the standard Wordpress loop

} else {
    echo __( 'No products found' );
}

All the code I used is below

$args = array(
'post_type'      => 'product',  
'meta_key'       => 'wpcf-topic',
'orderby'        => 'meta_value',
'order'          => 'ASC',
'posts_per_page' => -1,
'date_query'     => array(
    array(
        'column' => 'post_date_gmt',
        'after'  => 'Monday 1 week ago',
        ),      
    ),
);

$last_topic="";

$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
    while ( $loop->have_posts() ) : $loop->the_post();

    $topic=(get_post_meta( get_the_ID(), 'wpcf-topic', true ));

    if ($last_topic !== $topic){

    echo "<h1 class='red grid__item'>"  . $topic .  "</h1>";
    }
         woocommerce_get_template_part( 'content', 'product' ); // gets templet for product 

    $last_topic=$topic;
    endwhile;
wp_reset_postdata();
} else {
echo __( 'No products found' );
}

The reasoning behind doing it this way rather than looping through each topic one after another is that I don't want to limit it to a set number per topic, rather get all new products after monday one week ago. I also wanted to limit the number of loops to reduce the number of calls to the database. I am still learning so cannot say how much (if at all) doing it this way speeds up things, or reduces strain on the database. But in as I am expecting about 50 products per week to be added, in about 10-15 categories, it seemed like that would be a lot of loops per page load if I had a new loop for each topic found.

One final thing. The reasoning behind setting a custom field for topic, when it sort of looks like it should be a taxonomy (in fact in my case it will almost always make sense to be the same as the parent taxonomy for the product) is that you cannot order posts by taxonomy, for reasons explained very clearly here.

http://ottopress.com/2011/when-to-not-use-a-custom-taxonomy/ without that post I would have never got this far in understanding what to do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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