Forums

The forums ran from 2008-2020 and are now closed and viewable here as an archive.

Home Forums Back End Display custom post type list according to term attached

  • This topic is empty.
Viewing 12 posts - 1 through 12 (of 12 total)
  • Author
    Posts
  • #188339
    Jane
    Participant

    Hi! I’m going nuts trying to get this to work. It’s pretty straightforward.

    I have 2 custom post types: events and speakers;
    I have 1 custom taxonomy called event-names attached to both;
    I have 3 terms for event-names: A, B, and C

    My single-events.php template contains the event loop with nested speakers loop.

    When event A is displayed, I want only the list of speakers attached to term A to be displayed. Right now, When event A (or B or C) is displayed, ALL the speakers are displayed, not just the ones that are attached to their term.

    To try to achieve this, I made 3 separate custom sidebars for the speakers lists: sidebar-accountability.php, sidebar-reorganizing.php, and sidebar-embedding.php. In those I have the following code:

    `
    $IDOutsideLoop = $post->ID;
    global $post;

    $myposts = get_posts( array(
        'post_type' => 'speakers',
        'event-names' => 'embedding',
         'orderby'=>'title',
         'order'=>'ASC'
        ) );
    foreach($myposts as $post) :
    
    <div class="speakerbio left clearfix" id="post-<?php the_ID(); ?>" <?php
            if(is_single() && $IDOutsideLoop == $post->ID) 
    
            {
            echo "class='current'";
            }
    

    //stuff here
    </div> <!– END speakerbio –>
    <?php endforeach; ?>
    `

    Then I call that code on the events page with this code:

    `
    $the_query = new WP_Query( array(
    ‘post_type’ => ‘speakers’,
    ‘taxonomy’ => ‘event-names’,
    ‘orderby’=>’title’,
    ‘order’=>’ASC’
    ));

      if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post(); 
    
            if ( has_term( 'embedding', 'event-names' ) ) {
    
                echo get_sidebar('embedding'); 
    
            } else if ( has_term( 'reorganizing', 'event-names' ) ) {
    
                echo get_sidebar('reorganizing'); 
    
            } else if ( has_term( 'accountability', 'event-names' ) ) {
    
                echo get_sidebar('accountability'); 
    
            } else {
                echo "<p>That's all.</p>";
            } // That's all, folks
    
          endif; 
    
        endwhile; 
    
     endif; 
    wp_reset_query();
    

    `

    I would love some guidance, if you can. Thanks so much in advance.

    #188385
    Chris Bloomfield
    Participant

    Do you have a link please? I’m not sure if I have the right idea of how this should all come together, but the issue could just be that when you query the speakers post type, you’re querying by taxonomy (event-names) but not by term. So, every ‘speaker’ post type within the taxonomy ‘event-names’ is being returned.

    If this is the case, you could get the term of your single event, save it in a variable (like $current_event_term), then add this to your speaker query:

    'event-names' => $current_event_term,

    Again though, not sure if I’ve visualised this properly so sorry if that doesn’t help!

    #188386
    Jane
    Participant

    Hi Chris,

    Thanks for replying! I am working locally in MAMP, so unfortunately don’t have a link.

    I only want my speakers to display on the events page, and not have an archive page. So I registered the custom post type speakers with has_archive as false.

    I think the problem is that when I click on an event on my archives page it goes to single-events.php, not a taxonomy page. Can you tell me what I should include in my taxonomy template, and what it should be named?

    taxonomy-event-names.php or taxonomy-event-names-A.php, taxonomy-event-names-B.php, taxonomy-event-names-C.php , or taxonomy-events-event-names.php or taxonomy-events-event-names-A.php, …B.php, …C.php, or taxonomy-speakers-event-names.php or taxonomy-speakers-event-names-A.php, etc, or single-taxonomy-events-speakers…., etc…

    As you can see I’m so confused! The WordPress codex I think I know inside and out, I’ve spent endless weeks on it trying to find the answer, and there is no answer on it.

    #188388
    Jane
    Participant

    And thank you for your suggestion! I will try it with different code. My code was saying, if you’re on this single-events.php page show this sidebar, but the main query on the archives page does not have any args for terms! So that’s a problem I assume. It just shows whatever event I created from the custom post type.

    Do I query the terms on the archives-events.php page or the single-events.php page?

    #188390
    Chris Bloomfield
    Participant

    Here’s an image showing what I think your single event page layout looks like, as well as what it sounds like you would like to do, and how I reckon you can do it:

    http://i.imgur.com/ChbbYo3.png

    You can create a whole bunch of taxonomy page templates if you like, but as you’ve shown naming them can be tricky, and your code will get pretty unwieldy.

    The code shown in that image should do the trick – i.e., running a query on the single event page to retrieve posts of the type ‘speakers’, but only if they are assigned to a certain term.

    Also, to answer your last question: If you only need to show event speakers on the single event page, you only need to query the term in the single-events.php template.

    You would get that single event’s ‘events-name’ term while running through the single post’s output loop, save the term to a variable, then limit your query in the sidebar using the saved variable.

    Note that if your sidebar is in a different template, you won’t be able to access your saved variable right away, since variables aren’t shared across templates. The easiest way around this would be to make the saved term variable global.

    #188391
    Jane
    Participant

    This is soo great, thanks so much! The diagram is so helpful, and yes, that’s what it is set up like.

    Yes, the sidebar is separate. I would love to know how to make the saved term variable global.

    Also on the events page is another nested loop with the same speakers list. I coded it where each speaker in the sidebar list has a corresponding anchor link:

    <a href="#post-<?php the_ID(); ?>">Go to Bio</a>

    to scroll to the corresponding speaker by adding id="post-<?php the_ID(); ?>" to the speaker loop div on the event page. It works well, I’m happy to say!

    Some questions before I dig in:

    So I can work with the single-events.php template and don’t need to make a special taxonomy template?

    Does the main query on the single-events page have to have an if ( is_main_query() ); or a ‘pre_get_posts’ in my functions.php? May I ask you for an example? I’m still learning the main loop query. And then the nested speakers loop I assume would be a new WP_Query with a wp_reset_query(); ?

    #188393
    Jane
    Participant

    I tried this for the main query loop, but it doesn’t work. (thought I’d give it a shot myself, since I’m so stoked it’s so close)

    <?php  $term = ( 'event-names' term ); ?>    
    <?php if ( $term->have_posts() ): ?>           
     <?php while ( $term->have_posts()) : $term->the_post();?>
    
    <!-- Event stuff -->
    
    <!-- Nested Speaker loop using new wp_query, args you outlined and reset -->
    
    <?php endwhile; ?>                
    <?php endif; ?>

    Hmmmm….

    Then I tried this, but no go:

    <?php $events = get_posts( array(
    ‘taxonomy’ => ‘event-names’,
    ‘event-names’ => $term,
    ‘orderby’=>’title’,
    ‘order’=>’ASC’
    ) ); ?>

    <?php if ( $events->have_posts() ): ?>
    <?php while ( $events->have_posts()) : $events->the_post();?>

    Then I changed the name of my terms in the dashboard (I’m using CPTUI plugin), reset the permalinks and refreshed, but the old term names are still showing up in address bar. Is this a clue?

    #188432
    Jane
    Participant

    Then I tried this, but still a white page:

    
    /**
    *Template Name: Single Events
     */
    
    $events = query_posts( array( 
    'post_type' => 'events',
    'taxonomy' => 'event-names',
    'event-names' => $term,
       ) ); 
    
    if ( $events->have_posts() ): 
    while ( $events->have_posts()) : $events->the_post();
    
    // Event stuff
    
    $speakerpics = new WP_Query( array( 
    'post_type' => 'speakers',
    'taxonomy' => 'event-names',
    'event-names' => $term,
     'orderby'=>'title',
    'order'=>'ASC'
    ) );    
    
    if ( $speakerpics->have_posts(): 
    while ( $speakerpics->have_posts() ) :  $speakerpics->the_post(); 
    
    // Speaker stuff
    
    endwhile;
     endif;
    $speakerpics->reset_postdata();
    
    // continue Event stuff
    
    endwhile;   
    endif; 
    $events->reset_postdata();

    Is there a way to flush my terms cache?

    #188450
    Chris Bloomfield
    Participant

    You got a lot of questions there, not sure if I can answer all of them at once!

    If you’ve got a white page, there’s a PHP error in your code somewhere. You can enable debugging mode in WP to get a message telling you about any errors. To do this, edit wp-config.php (in your WP installation root), and find the line that looks like this:

    define( ‘WP_DEBUG’, false );

    Just change ‘false’ to ‘true’, like so:

    define( ‘WP_DEBUG’, true );

    Upload your new wp-config.php file and refresh your blank page to see what’s causing the issue. If you get an error saying “unexpected end of file”, that means it’s a standard PHP error, which means the syntax is broken somewhere. You can use an online PHP code validator to find PHP errors. If your query loops aren’t working, you could try generating one with wpgenerate.com.

    Regarding the $terms global variable, you use it like so, inside your single event page loop:

    global $single_event_terms; // Declare this as a global variable
    $single_event_terms = (current post term); // Set the value of the variable to the current post term

    I referred to $terms before, but it’s best to use a more descriptive variable name, like the one shown above. Once you’ve set $single_event_terms you can use it elsewhere, in other templates. To do this, just use that first line again before you want to use the variable:

    global $single_event_terms; // Get data for this global variable

    Now you can use it inside your queries. From the code above, it looks like you added ‘event-names’ => $term to your event post type loop, but you don’t need to do that yet. Remove that to make the single event post type loop work, then, while inside your single event post type loop, set up the global variable.

    You’ve got your speakers list nested inside your main single event post query loop, so it looks like your speakers list isn’t in a separate template file. In this case, you don’t need to declare the variable as being global – just set a value for the variable:

    $single_event_terms = (current post term); // Set the value of the variable to the current post term

    Global variables are useful if you need to carry data across template files, but if you’re setting the value of a variable up within the same file as when you retrieve it, using a global variable isn’t necessary. (Note: They are also bad practice so are generally frowned upon, but this seemed to be the best solution.)

    The big part that I’ve missed in all this is that you need to get the term for your current single event post. Getting terms can be tricky, I can’t remember the correct usage, and I’m afraid I’m not currently in a position where I can test any code I could offer you to properly get a post’s terms. But I think the WP function ‘wp_get_post_terms’ will help you here. You’ll probably spend a while trying to get the terms, I certainly struggle sometimes with them at first. It’s also worth Googling “wordpress get term” for other help with getting your terms.

    #188460
    Jane
    Participant

    Thanks so much Chris! I appreciate your thoughtful reply. I LOVE the debug thing, it’s so helpful!! I put it to the test, and found one error which I fixed. Now the single-event.php pg. shows a white blank page but now it at least shows the loader gif (it didn’t show it before), but alas now there is no debug info.

    Thanks for the global variable info, I will try it out.

    I think I’m left wondering what taxonomy.php files I’m missing and how to set them up. I will keep on searching, but many thanks for your time and knowledge!!!

    #188549
    Jane
    Participant

    Update: I did find a solution that I would like to share. The reason the urls were not changing was that it was not calling my taxonomy templates. So with much searching I found this magical code:

    <?php the_terms( $post->ID, 'eventnames', ' ', ', ', ' ' ); ?>

    Once I popped it into my template, I realized what it does. It displays a link that calls my taxonomy-eventnames-term.php templates! The url was now correct, and all was right with the world. So I replaced the permalink code, which you would normally use to link to your custom post, and that’s how I got it to work.

    Question, though: Do permalinks not work with taxonomies?

    And further question: How can I make the above code display something other than the TITLE as a link? Because I want the link to say, “MORE DETAILS”. Seems like it would be so simple but I can’t find the answer.

    Anyway, getting back to my solution, I then created 3 taxonomy-eventnames-term.php templates, each one called their respective terms, meaning the names of each event, and it worked.

    Still left wondering: Seems like there could be a step I could save by making only ONE taxonomy.eventnames.php template and calling each event term with a conditional statement. For this project I only have 3 events, but what if I had 30? Would I have to create 30 new templates for each?

    #189248
    Shpend Berisha
    Participant

    Cannot post

    Block details

    URL: css-tricks.com/forums/reply/189248/
    Your Browser: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:32.0) Gecko/20100101 Firefox/32.0
    Block ID: SQLi71
    Block reason: SQL injection was detected and blocked.
    Time: Wed, 26 Nov 2014 04:24:16 -0500
    Server ID: cp402
    
Viewing 12 posts - 1 through 12 (of 12 total)
  • The forum ‘Back End’ is closed to new topics and replies.