This cannot be done inside the tr tags, you need to separate this out into two stages. First collect the data ( without displaying any HTML ), then display that data.
For example:
$editor = new WP_Query( [
'posts_per_page' => 20
] );
// each item in this array will be a post/an array of all
// the fields in a post
$table = [];
// and these are the items/rows we want to display
$labels = [ 'first', 'second', 'third' ];
// First fill $table with data
if ( $editor->have_posts() ) {
while( $editor->have_posts() ) {
$editor->the_post();
$table[] = [
'first' => get_post_meta( get_the_ID(), 'firstmeta', true ),
'second' => get_post_meta( get_the_ID(), 'second', true ),
'third' => get_post_meta( get_the_ID(), 'third..etc', true ),
];
}
}
// Second, display the data we just collected
?>
<table >
<tbody>
<?php
foreach( $labels as $label ) {
?>
<tr>
<th class="am-t-lable"><?php echo esc_html( $label ); ?></th>
<?php
foreach( $table as $post ) {
?>
<td class="am-t-value"><?php echo esc_html( $post[ $label ] ); ?></td>
<?php
}
?>
</tr>
}
?>
</tbody>
</table>
Importantly, this is not the only way to do something like this, there are lots of alternatives, some that don’t involve loops at all but use functions such as array_map
etc.
The most important part, is that you don’t have to fetch the data and display it at the same time and mix that code together. In the above example you could take each step and make them their own function completely separate! Separation of concerns is a good skill and best practice in programming.