custom post type or taxonomy, which approach is better?

If you need to display the flags of the countries in the post then the best option would be to use custom fields with your own function that will know to translate the value of the custom field in to the right country’s image.

You can also create a custom taxonomy for that with a custom field (best tutorial in the world: how to – WordPress Category Extra Fields) and it would work just fine and will make the connection between a post to a country very easy (as easy as selecting a category ) but you will have to create the upload functionality or upload as media and just save the url as the custom taxonomy field .

But if you are looking for the easiest solution then creating a custom post type will let you use the featured image functionality and a simple metabox in the post’s edit panel with the option to save the country’s Custom Post Type’s id as a custom field.

And it just happens that i have a class that sets a metabox to let you do that, just make sure you set the right post type:

class post_to_post_by_id {
    function __construct() {
        /* Define meta box */
        add_action( 'add_meta_boxes', array($this,'myplugin_add_custom_box' ));
        /* save meta box */
        add_action( 'save_post', array($this, 'myplugin_save_postdata' ));
    }

    /* Define the custom box */
    /* Adds a box to the main column on the Post edit screen */
    function myplugin_add_custom_box() {
        //add metabox to post edit screen
        add_meta_box( 
            'county_sectionid',
            __( 'Select Countries', 'myplugin_textdomain' ),
            array($this,'myplugin_inner_custom_box'),
            'post' 
        );
    }

    /* Prints the metabox content */
    function myplugin_inner_custom_box() {
        global $post;
        // Use nonce for verification
        wp_nonce_field( plugin_basename( __FILE__ ), 'myplugin_noncename' );

        //define your country field settings
        $ptype="page";
        $field_id = 'post_countries';
        $field_desc="this is the field description";

        // The actual fields for data entry
        $data = get_post_meta($post->ID,'post_countries',true);
        if (empty($data)){
            $data = array();
        }

        $args = array( 'numberposts' => -1, 'post_type'=>$ptype ,'post_status' => 'publish' );
        $posts = get_posts($args);
        if ($posts){
            foreach ( $posts as $p ){
                $checked = '';
                if (is_array($data)){
                    if ( in_array( $p->ID, $data ) ){
                        $checked = ' checked="checked"';
                    }
                }
                echo '<input value="'.$p->ID.'" '.$checked .' type="checkbox" name="'.$field_id.'[]" id="'.$field_id.'[]">  '.$p->post_title.'  ';
            }
            echo '<br /><span class="description">'.$field_desc.'</span>';
        }else{
            echo 'No Posts';
        }
    }

    /* When the post is saved, saves our custom data */
    function myplugin_save_postdata( $post_id ) {
        // verify if this is an auto save routine. 
        // If it is our form has not been submitted, so we dont want to do anything
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
            return;

        // verify this came from the our screen and with proper authorization,
        // because save_post can be triggered at other times
        if (!isset($_POST['myplugin_noncename']))
            return;
        if ( !wp_verify_nonce( $_POST['myplugin_noncename'], plugin_basename( __FILE__ ) ) )
            return;
        // Check permissions
        if ( 'page' == $_POST['post_type'] ) 
        {
            if ( !current_user_can( 'edit_page', $post_id ) )
            return;
        }
        else
        {
            if ( !current_user_can( 'edit_post', $post_id ) )
                return;
        }

        // OK, we're authenticated: we need to find and save the data
        if (isset($_POST['post_countries'])){
            update_post_meta($post_id,'post_countries',$_POST['post_countries']);
        }else{
            delete_post_meta($post_id,'post_countries');
        }
    }
}

new post_to_post_by_id();