Two things were wrong (three, counting the missing global $post; line) :
1) I was using the_permalink() instead of get_the_permalink(), and that was causing the output buffer.
2) I had to append each row to a final output variable. So I added this at the end of the while loop: $final_output .= $output; Then this at the end to return: return $final_output;
Thanks for your help John!