Get X posts with the same terms as the current post (custom post type and custom taxonomy)

  • It’s not limiting to 5 posts

That’s because the posts_per_page arg should actually be in the same level as the post_type arg and not put inside the tax_query array. I.e.

$args = array(
    'post_type'      => 'oferta',
    'posts_per_page' => 5, // add it here
    'tax_query'      => array(
        array(
            'taxonomy'       => 'categoria',
            'posts_per_page' => 5, // NOT here
            ...
        ),
    ),
);
  • It’s duplicating the li elements (1 correct element, 1 empty element)

That’s very likely because you didn’t close the elements, i.e. you forgot the closing </li> tag and instead (mistakenly) used <li>. So make sure to properly close your li tag:

echo '<li><a href="'.get_permalink().'">'.get_the_title().'</a></li>';  // correct - use </li>
//echo '<li><a href="'.get_permalink().'">'.get_the_title().'</a><li>'; // incorrect
  • It’s showing the current post also on the list (I only want to show the other posts with the same term, not the current post)

You could use the post__not_in arg, i.e. add 'post__not_in' => array( get_the_ID() ), to your $args array, but NOT IN queries are known to cause performance issues (just like 'orderby' => 'rand'), so as an alternate way, you can instead use PHP to ignore the current post, but you should set the posts_per_page to 6 since we’re not excluding the current post at the database level.

Working example:

// Assign the current post ID to a variable.
$current_post_id = get_the_ID();

// Make the custom posts query.
$loop = new WP_Query( $args );

// Post counter; if the value has reached 5, then we exit the `while` loop below.
$counter = 0;

// Display the posts.
echo '<ul>';
while ( $loop->have_posts() ) {
    if ( $counter >= 5 ) {
        break;
    }

    $loop->the_post();
    // Display the post if it's not the current post with the ID $current_post_id
    if ( $current_post_id !== get_the_ID() ) {
        echo '<li>your HTML/code here..</li>';
        $counter++;
    }
}
echo '</ul>';