There is a hook called edit_form_after_title
that seems built for this case. That plus a custom meta field should do it.
function after_title_cb($post) {
$af = get_post_meta($post->ID,'_after_title',true);
echo '<input id="aftertitle" name="_after_title" value="'.$af.'">';
}
add_action('edit_form_after_title','after_title_cb');
function save_after_title( $post_id ) {
$mydata = (!empty($_POST['_after_title']))
? wp_kses($_POST['_after_title'])
: '';
update_post_meta( $post_id, '_after_title', $mydata );
}
add_action( 'save_post', 'save_after_title' );
You can even wrap the whole thing in a standard metabox if you'd like.
function after_title_cb($post) {
$af = get_post_meta($post->ID,'_after_title',true);
echo '<input id="aftertitle" name="_after_title" value="'.$af.'">';
}
function add_before_editor($post) {
global $post;
add_meta_box(
'generic_box', // id, used as the html id att
__( 'Text Only Content' ), // meta box title
'after_title_cb', // callback function, spits out the content
'post', // post type or page. This adds to posts only
'pre_editor', // context, where on the screen
'high' // priority, where should this go in the context
);
do_meta_boxes('post', 'pre_editor', $post);
}
add_action('edit_form_after_title','add_before_editor');
function save_after_title( $post_id ) {
$mydata = (!empty($_POST['_after_title']))
? wp_kses($_POST['_after_title'])
: '';
update_post_meta( $post_id, '_after_title', $mydata );
}
add_action( 'save_post', 'save_after_title' );
On the front end you'd grab and display the value with something like this:
// careful with $post
// This must be in a Loop to be reliable
$af = get_post_meta($post->ID,'_after_title',true);
if ( !empty($af) ) {
echo $af;
}