Something I forgot in my previous comment was that shortcodes return content, both the suggested include
and my alternative get_template_part
will directly output the content (which is what you are seeing with the content appearing at the top of your page instead of where the shortcode is called). To counteract this we must use output buffering.
Define the shortcode in your functions.php (or your site’s site-specific functions file).
function my_form_shortcode() {
ob_start();
get_template_part('my_form_template');
return ob_get_clean();
}
add_shortcode( 'my_form_shortcode', 'my_form_shortcode' );
Then in your theme folder you need a file called my_form_template.php
which will be loaded anywhere you place the shortcode.