0

I'm building a theme that needs some cross-information(?) between custom post types.

I have a metabox to select custom post types and display them inside the single page of another custom post type. So far things work 50%...

Right now I am using this code to display their thumbnail (but I will require their title and own meta):

$guests = get_post_meta($post->ID, 'cl_guest', true);
$guest_id = get_post_meta(get_the_ID(), 'cl_guest', true);
$guest_post = get_post( $guest_id[0] ); 
foreach($guest_id as $guest) { 
echo get_the_post_thumbnail($guest_post->ID, 'thumbnail', array( 
       'class' => "img-responsive img-circle", 
       'alt' => trim(strip_tags( $guest_post->post_title )),
       'title' => trim(strip_tags( $guest_post->post_title ))
       )); 
        }

It displays the correct number of posts, but it repeats the first item (ordered by ascending id).

Any help is appreciated! <3

1 Answer 1

1

Based on the code you've posted I assume cl_guest post meta contains an array of post IDs. Building upon this assumption, you could do something like this.

1) Add these helper functions to your theme's funtions.php file

// custom template tag to render guests
function render_guests( array $guests ) {
  if ( $guests ) {
    // you could use foreach loop instead of array_walk
    array_walk( $guests, 'render_guest' );
  }
}

// Helper function to get guest ids
function get_guest_ids( int $id ) {
  $meta = get_post_meta( $id, 'cl_guest', true);
  return ( $meta && is_array( $meta ) ) ? array_map( 'intval', $meta ) : array();
}

// helper function to render single guest
function render_guest( int $id ) {
  // get meta if needed
  $meta = get_guest_meta( $id );
  $title = get_the_title( $id );
  $thumbnail = get_guest_thumbnail( $id, $title, $title );
  // modify output as needed
  echo '<div class="guest">' . $thumbnail . $title . '</div>';
}

// helper function
function get_guest_meta( int $id ) {
  return get_post_meta( $id, 'some_meta_key', true );
}

// helper function
function get_guest_thumbnail( int $id, string $alt = '', string $title = '' ) {
  return get_the_post_thumbnail(
    $id, 
    'thumbnail', 
    array( 
     'class' => "img-responsive img-circle", 
     'alt'   => esc_attr( $alt ),
     'title' => esc_attr( $title )
    )
  );
}

2) add the custom tempalte tag to your post template where you want to display the guests

<?php render_guests( get_guest_ids( get_the_ID() ) ); ?>

P.S. You might wonder why I've split the code to multiple functions. The reason is that I'm just practicing a new coding style where each function is supposed to do one thing.

EDIT 1 Here's how you could render images and title+meta separately. First couple new helper functions.

function render_guest_images( array $ids ) {
  if ( $ids ) {
    array_walk( $ids, 'render_guest_image' );
  }
}

function render_guest_image( int $id ) {
  $title = get_the_title( $id );
  echo get_guest_thumbnail( $id, $title, $title );
}

function render_guest_infos( array $ids ) {
  if ( $ids ) {
    array_walk( $ids, 'render_guest_info' );
  }  
}

function render_guest_info( int $id ) {
  $title = get_the_title( $id );
  $meta = get_guest_meta( $id ); // this could either return data that you render here or ready-to-use html that you just concatenate to the echo below
  echo '<div class="guest-info">' . $title . '</div>';
}

// add this before you add the rendering functions on your post template
$guest_ids = get_guest_ids( get_the_ID() );

// somewhere on your post template
render_guest_images( $guest_ids );

// somewhere else on your post template
render_guest_infos( $guest_ids );

EDIT 2

without separate helper and render functions

// before any loops
$guest_ids = get_post_meta( get_the_id(), 'cl_guest', true);
$guest_ids = ( $guest_ids && is_array( $guest_ids ) ) ? array_map( 'intval', $guest_ids ) : array();

$guest_posts = array();
if ( $guest_ids ) {
  foreach ( $guest_ids as $guest_id ) {
    if ( $post = get_post( $guest_id ) ) {
      $guest_posts[] = $post;      
    }
  }
}

// titles only
if ( $guest_posts ) {
  foreach( $guest_posts as $guest_post ) {
    echo esc_html( $guest_post->post_title );
  }
}

// thumbnails
if ( $guest_posts ) {
  foreach( $guest_posts as $guest_post ) {
    echo get_the_post_thumbnail( 
      $guest_post->ID, 
      'thumbnail', 
      array( 
      'class' => "img-responsive img-circle", 
      'alt'   => esc_attr( $guest_post->post_title ),
      'title' => esc_attr( $guest_post->post_title )
      )
    );
  }
}

// meta only
if ( $guest_posts ) {
  foreach( $guest_posts as $guest_post ) {
    $meta = get_post_meta( $guest_post->ID, 'some_meta_key', true );
    // do something with meta
  }
}
7
  • Thanks, but it doesn't work, it displays an error now - turning on debug it says: Parse error: syntax error, unexpected '$id' (T_VARIABLE), expecting ',' or ')' in this line: render_guest( int $id ) { Aug 22, 2019 at 16:19
  • @CynthiaLara Whoops, sorry about that. Some silly typos had slipped into the code. They're now fixed and the code should work. Aug 22, 2019 at 18:17
  • Great! It is now working! but I have to ask. I need to have the rendering of different things from guests in different parts of the page - not in the same block. Is there a way to use the title or meta outside the render_guests function? In one section of the page goes the thumbnail, but way below in another section it displays the names and meta, thats why i avoid using functions.php and try to set variables in the divs I need them to be :O Aug 22, 2019 at 18:25
  • Yes, of course, I added couple more examples how to render images and names/meta separately. That is perfectly fine to keep all of the logic and rendering on one template and on the sections where they are needed. The style I've written the examples in is just something I'm practicing as I feel that this style makes my code easier to read, debug, extend and import into other projects. Aug 22, 2019 at 18:52
  • Thank you very much! I'm close but still have a lot of doubt. For the last bit of code (to call infos) how can I render only title, or only meta? What If I need one section with only title, then another section needs a heading tag with title and meta as span? Do I need to create a new function for every render I need? (sorry! Im new to using render functions from the functions.php!) Aug 22, 2019 at 19:14

Your Answer

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

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