Submitting WordPress post from frontend without a plugin

Screen Shot
Screen Shot


This tutorial will guide you to create your own custom post composing form to enable fast blogging with your favorite theme without adding a plugin. I’m looking for any alternative to not porting P2, however…. none.,  finally that’s the reason i wrote it, and It was also inspired by the original development from


I found the code from , but it doesn’t  handle file attachment, indeed most people and I was demand on image uploads for status update,  photo blogging.. whatever . But to get working with build-in WordPress media upload function require a lots of code work,  and if you prefer a fully functional media library, you could base on P2 theme instead.

How it work

  1. It create a post form to allow  the post content inserted by wp_insert_post.
  2. following the post_id, it attach the uploaded files to the post.
  3. Set the first ordered image to the post “featured images”
  4. Lastly, you call get_all_thumbnails before the_content() in order to retrieve the uploaded files.


The critical limitation is lack of media features, unlike build-in media library, you can customize your post images and place it on your desired position. Therefore the images only able to retrieve by the_post_thumbnail() for single image or get_all_thumbnails() for multiple images.

Files you need to modify

  1. function.php – Theme function file
  2. header.php – Theme header file
  3. index.php – Theme main body
  4. all template file contenting the_post/the_content loop.

Additional files

  1. multifile_compressed.js – Script for multiple file uploads. Download it from
  2. postbox.css – CSS style for the composing form

1. postbox.css

  • Postbox style
#postBox {
	width: 700px;
	padding: 10px;
	margin: 0 auto 0 auto;

#postBox #post_title {
	border: 1px solid #ddd;


#postBox #post_content {
	border: 1px solid #ddd;
	margin-bottom: 5px;

#postBox #submitPost {
		float: right;

#postBox .post_category {
		float: left;

#postBox .post_tags {
		float: left;
		margin-left: 10px;

#postBox #post_tags {
		border: 1px solid #ddd;
#postBox .post_format {

2. function.php

  • wp_enqueue_script – Load the multifile script
  • insert_attachment – handle $_FILES submission
  • fix_title – automatic fill the title from the content if you leave title blank during your submission.
  • get_all_thumbnails – retrieve all attached images.
wp_enqueue_script('multifile-js', get_bloginfo('template_directory') . '/multifile_compressed.js');

function insert_attachment($file_id,$post_id,$featuredImage) {
		require_once(ABSPATH . "wp-admin" . '/includes/image.php');
		require_once(ABSPATH . "wp-admin" . '/includes/file.php');
		require_once(ABSPATH . "wp-admin" . '/includes/media.php');
		$attach_id = media_handle_upload( $file_id, $post_id );
		if (is_int($attach_id)&&($featuredImage)) update_post_meta($post_id,'_thumbnail_id',$attach_id);
		return $attach_id;

function fix_title($content,$limit) {
  $excerpt = explode(' ', $content, $limit);
  if (count($excerpt)>=$limit) {
    $excerpt = implode(" ",$excerpt);
  } else {
    $excerpt = implode(" ",$excerpt);
  $excerpt = preg_replace('`\[[^\]]*\]`','',$excerpt);
  return $excerpt;

function get_all_thumbnails() {
	global $post;
	$args = array(
	'order'          => 'ASC',
	'orderby'        => 'menu_order',
	'post_type'      => 'attachment',
	'post_parent'    => $post->ID,
	'post_mime_type' => 'image',
	'post_status'    => null,
	'numberposts'    => -1,
	$attachments = get_posts($args);
	$i = 0;
  		if ($attachments) {
			foreach ($attachments as $attachment) {
			echo wp_get_attachment_link($attachment->ID, 'medium', false, false);
			$i = $i + 1;
	if ($i != 0) echo '<div style="clear: both;"><small>' . $i . ' pictures</small></div>';



Add before wp_head()

  • Load the stylesheet for the postbox form
  • Handle the $_POST insert post request.
<link rel="stylesheet" href="<?php bloginfo('template_directory') ?>/postbox.css" type="text/css" media="screen" />

if( $_SERVER['REQUEST_METHOD'] == 'POST' && !empty( $_POST['add_new_post'] ) && current_user_can('level_2')) {
			if (isset ($_POST['post_title'])) {
					$post_title =  htmlentities(trim(stripcslashes($_POST['post_title'])));
			if(empty($_POST['post_title'])) {
					$post_title = htmlentities(trim(stripcslashes(fix_title($_POST['post_content'],15))));
				if (isset ($_POST['post_content'])) {
					$post_content = htmlentities(trim(stripcslashes($_POST['post_content'])));
				} else {
					echo 'Please enter the content';
				if (isset ($_POST['post_category'])) {
					$post_category = $_POST['post_category'];
				} else {
					$post_category = 1;
				if (isset($_POST['post_tags'])) {
					$post_tags = $_POST['post_tags'];

				$post = array(
					'post_title'	=> $post_title,
					'post_content'	=> $post_content,
					'post_category'	=> array($post_category),
					'tags_input'	=> $post_tags,
					'post_status'	=> 'publish',
					'post_type'	=> $_POST['post_type']

			$post_id = wp_insert_post($post);
			if (!empty($_FILES['file_0']['name'])) {
			  foreach ($_FILES as $file_id => $array) {
			  	if($file_id=="file_0") {
			  		$featuredImage = true;
			  	  	$attachment_id = insert_attachment($file_id,$post_id,$featuredImage);
			  	} else {
			  		$featuredImage = false;
			  	  	$attachment_id = insert_attachment($file_id,$post_id,$featuredImage);
                echo "<meta http-equiv='refresh' content='0;url=$location' />";


4.index.php or somewhere you like

  • Display the post form
<div id="postBox">
<form id="new_post" name="new_post" method="post" action="" enctype="multipart/form-data">
<p class="post_title"><label for="post_title">Title</label><br />
<input type="text" id="post_title" value="" tabindex="1" name="post_title"/>
<p class="post_content"><label for="post_content">Content</label><br/>
<textarea id="post_content" tabindex="3" name="post_content"  rows="6"></textarea>
<input type="submit" id="submitPost" value="Publish"/>

<p class="post_category">
<label for="post_category" >Category:</label>
<?php $categories = wp_dropdown_categories("echo=0&hide_empty=0&selected=0");
	preg_match_all('/\s*<option class="(\S*)" value="(\S*)">(.*)<\/option>\s*/', $categories, $matches, PREG_SET_ORDER);
	echo "<select id='post_category' name='post_category'>";
	foreach ($matches as $match){
	echo "<option value='{$match[2]}'>{$match[3]}</option>";
	echo "</select><br />\n";
<p class="post_tags">
<label for="post_tags">Tags:</label>
<input type="text" value="" tabindex="5" size="20" name="post_tags" id="post_tags" /><small>(Comma seperated)</small>
<div style="clear:both;"></div>
<p><label for="attachment">Files: </label><input type="file" id="attachment">
<div id="attachment_list"></div></p>

<input type="hidden" name="post_type" id="post_type" value="post" />
<input type="hidden" name="add_new_post" value="post" />
<?php wp_nonce_field( 'new-post' ); ?>
	var multi_selector = new MultiSelector( document.getElementById( 'attachment_list' ), 0 );
	multi_selector.addElement( document.getElementById( 'attachment' ) );

Wrapping up for the content loops

  • Display the image attachment

Eg: index.php, single.php, archive.php….etc
Place the following code before you call “the_content();”  to allow it to retrieve all images you attached with the post.

<?php if(function_exists('get_all_thumbnails')) get_all_thumbnails(); ?>

or for display single image

<?php if(has_post_thumbnail()); the_post_thumbnail();?>

For example

<?php if(have_posts()): while(have_posts()): the_post(); ?>
<?php if(function_exists('get_all_thumbnails')) get_all_thumbnails(); ?>
<?php the_content();?>
<?php endwhile; endif;?>


Since I am not familiar on PHP, so maybe I could not able to solve your problem on your WordPress setup. Please be patient to raise your problem here, or maybe someone will glad to help. If you like to improve the code, please drop me a line.

Leave a Reply