You need a couple of things. A shortcode handler, and a custom query:
function wpse_186346_excerpt_length() {
return 50;
}
function wpse_186346_excerpt( $atts ) {
$atts = wp_parse_args( $atts,
array(
'posts_per_page' => 2,
// Any other default arguments
)
);
// We don't need paging, always save a query
$atts['no_found_rows'] = true;
// Create query based off arguments from shortcode
$query = new WP_Query( $atts );
// Start the buffer to "catch" our output below, so that we can return it as a string
ob_start();
// Set our custom excerpt length
add_filter( 'excerpt_length', 'wpse_186346_excerpt_length' );
// Loop over the posts and output whatever markup you need
while ( $query->have_posts() ) {
$query->the_post();
the_title( '<h4 class="excerpt-title"><a href="' . get_permalink() . '">', '</a></h4>' );
the_excerpt();
}
// Remove our custom excerpt length
remove_filter( 'excerpt_length', 'wpse_186346_excerpt_length' );
// Restore the current global post
wp_reset_postdata();
return ob_get_clean();
}
add_shortcode( 'excerpt', 'wpse_186346_excerpt' );
And use it like so:
[excerpt tag="test_tag"]
Your shortcode arguments just need to match those available, so you’re not limited to only tags!