0

I'm developing my first custom theme from scratch (using Roots as base framework). The theme has 2 CPT, one for events and one for associations with a correlation one to many between the two (an association can have many events associated).

I modified the main query with pre_get_posts to display events in homepage.

Now I want to create a widget on sidebar to display a list of the associations that have events associated with them. I also want to display the number of events associated near the name of every association. If I click on one of them, I want to go on an archive page with a list events only for that association.

Think of it like the standard archive plugin but with associations instead of months.

I don't have idea of which type of query I have to do inside the custom widget main function. This is my code at the moment:

private function getAssociationsList(){

  // The Query
  $associations = new WP_Query( array('post_type' => 'associations' ) );

  if($associations->found_posts > 0) {
    echo '<ul>';
      while ($associations->have_posts()) {
        $associations->the_post();

        $events_query = array(
          'post_type' => 'events',
          'meta_query'=> array(
            array(
              'key'   => 'mlw_event_association',
              'value' => get_the_ID()
            )
          )
        );

        $events_for_this_association = new WP_Query($events_query);

        if($events_for_this_association->found_posts > 0){
          $listItem = '<li>'; 
          $listItem .= '<a href="' . get_permalink() . '">';
          $listItem .= get_the_title() . '</a>';
          $listItem .= ' ('. $events_for_this_association->post_count . ')</li>'; 
          echo $listItem;
        }
      }
    echo '</ul>';
    wp_reset_postdata(); 

  }else{
    echo '<p>_("No association with upcoming events at the moment")</p>';
  } 
}

The problem here is that get_permalink() is the link to the association page, not to a "filtered" archive page. Also with this query the tag is always shown, even if there aren't associations with events associated.

Any suggestion would be very appreciated.

Thank you!

1 Answer 1

0

I re-wrote the function, taking a few liberties with it.

The main change was specify the ID of the association to link to in your call to get_permalink and to just use $association->ID instead of calling get_the_title (though you could just place the same ID in get the title).

I also switched from using the_post() to using next_post() which pulls the next post into a variable instead of stomping on the various post global variables.

Finally, since the function is getAssociationsList, I had it return the output instead of echoing it. (and I changed the name ... as using underscores helps when people need to translate your function names a little)

Anywise, I hope this helps!

private function get_associations_list(){
    $associations = new WP_Query( array('post_type' => 'associations' ) );
    $output = '';

    if( $associations->found_posts > 0 ) {
        $output .= '<ul>';
        while ($associations->have_posts()) {
            # changed to use next_post() so we can avoid messing with the global query
            # which avoids needing to use reset below.
            $association = $associations->next_post();

            # block this out as we no longer need it
            # $associations->the_post();

            # Changed value to use the objects ID rather than calling an extra function to get it
            $events_query = array(
                'post_type' => 'events',
                'meta_query'=> array(
                    array(
                        'key'   => 'mlw_event_association',
                        'value' => $association->ID
                    )
                )
            );

            # Checked via have_posts
            # - added target object to get permalink and title for
            # - changed count to use found_posts instead of post_count
            $events_for_this_association = new WP_Query($events_query);
            if ( $events_for_this_association->have_posts() ) {
                # There is at least one
                $association_link = get_permalink( $association->ID );
                $association_title = $association->post_title;
                $association_event_count = $events_for_this_association->found_posts;
                $output .= <<<HTML
<li><a href="{$association_link}">{$association_title}</a> ({$association_event_count})</li>
HTML;

            }
        }
        $output .= '</ul>';

        # no longer needing to reset post data as we never used the global space
        # wp_reset_postdata(); 

    }else{
        $output = '<p>' . __("No association with upcoming events at the moment") . '</p>';
    }

    # Maybe give caller option to echo it immediately instead of echoing it.
    return $output;
}
2
  • Thank you for refactoring my code in a more elegant way. The only thing i noticed is that next_post() function seems deprecated according to the codex
    – Alerosa
    Commented Feb 2, 2015 at 22:53
  • Strange, I can't seem to find that. Maybe the next_post() function is deprecated, but the next_post method of the WP_Query class is not, so the above shouldn't be problematic. Very welcome.
    – Privateer
    Commented Feb 2, 2015 at 23:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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