WordPress Post From Front End

I’ve been thinking a lot lately about making WordPress post from front end. Solutions exist, in terms of plugins and specialized themes, but neither fit the bill and there are times when they just aren’t all that flexible. However there’s always the possibility of a custom built WordPress front-end posting plugin that can be adjusted to fit an exact need.

In this article, we’ll look at the reasons why you’ll need WordPress post from front end, using the WordPress API to insert posts and finally putting it all together in the form of an easy to modify WordPress front end posting plugin.

Reasons WordPress Post From Front End

WordPress is getting more and more used as a framework (or application platform) and for good reasons. It’s really well documented, “there’s a plugin for that” phrase is as true as it’s gonna get and you can find really good developers at good prices.

All these combined encourage people to build, build, build:

  • community websites
  • directories
  • Q&A sites
  • photo sharing portals
  • etc.

Creating a WordPress front end posting plugin

We’ll start by getting acquainted with the wp_insert_post(). This WordPress function inserts posts (and pages) into the database. It sanitizes variables, does some checks, fills in missing variables like date/time, etc.

<?php wp_insert_post( $post, $wp_error ); ?>

The $post parameter is an array representing the elements that make up a post. The contents of the post array can depend on how much (or little) you want to trust the defaults. For a full list just check the WordPress Codex entry on wp_insert_post.

There are some particularities you should be aware of:

  • Setting a value for $post['ID'] WILL NOT create a post with that ID number. Instead it will update the post with that ID number.
  • wp_insert_post() passes data through sanitize_post(), which itself handles all necessary sanitization and validation (kses, etc.). However, to remove HTML, JavaScript, and PHP tags from the post_title and any other fields, you need to use the wp_strip_all_tags()

Other WordPress functions needed

In order to get a fully working front end posting plugin, we’ll need to use a couple more WordPress functions. They are:

Anonymous posting or logged in users?

Depending on what your project needs, you can allow anonymous posting, or ask users to register/login before they can post from front end.

Our plugin will require users to login first. However, we won’t deal with the login and registration functionality, instead we’ll let another plugin take care of that: Profile Builder. The free version is perfect for that and all we’ll need to do is add links to the login and registration pages in the same page where we’re adding our front end posting shortcode.

A Shortcode for front end posting

The best way to build our front end functionality in order to make WordPress post from front end is to have it all inside a plugin and make use of a shortcode to display the form that will gather our information.

To test it out, create a new file called simple-fep.php, copy the code bellow and use the shortcode [simple-fep] in a page to show the front end posting form.

<?php
/*
Plugin Name: Simple Front End Posting
Plugin URI: http://cozmoslabs.com/
Description: Really simple way of posting from the front end for WordPress
Author: Cristian Antohe	
Version: 0.1
Author URI: http://cozmoslabs.com/
*/
 
function simple_fep($content = null) {
	global $post;
 
	// We're outputing a lot of html and the easiest way 
	// to do it is with output buffering from php.
	ob_start();
 
?>
<style>
#fep-new-post label{display:inline-block;width:15%;}
#fep-new-post input{width:60%;}
#fep-new-post input[type="submit"]{margin-left:15%;width:30%;padding:7px;}
#fep-new-post textarea{	display:inline-block;width:80%;vertical-align:top;}
</style>
<div id="simple-fep-postbox" class="<?php if(is_user_logged_in()) echo 'closed'; else echo 'loggedout'?>">
		<?php do_action( 'simple-fep-notice' ); ?>
		<div class="simple-fep-inputarea">
		<?php if(is_user_logged_in()) { ?>
			<form id="fep-new-post" name="new_post" method="post" action="<?php the_permalink(); ?>">
				<p><label>Title *</label><input type="text" id ="fep-post-title" name="post-title" /></p>
				<p><label>Content *</label><textarea class="fep-content" name="posttext" id="fep-post-text" tabindex="1" rows="4" cols="60"></textarea></p>
				<p><label>Tags</label><input id="fep-tags" name="tags" type="text" tabindex="2" autocomplete="off" value="<?php esc_attr_e( 'Add tags', 'simple-fep' ); ?>" onfocus="this.value=(this.value=='<?php echo esc_js( __( 'Add tags', 'simple-fep' ) ); ?>') ? '' : this.value;" onblur="this.value=(this.value=='') ? '<?php echo esc_js( __( 'Add tags', 'simple-fep' ) ); ?>' : this.value;" /></p>
				<input id="submit" type="submit" tabindex="3" value="<?php esc_attr_e( 'Post', 'simple-fep' ); ?>" />					
				<input type="hidden" name="action" value="post" />
				<input type="hidden" name="empty-description" id="empty-description" value="1"/>
				<?php wp_nonce_field( 'new-post' ); ?>
			</form>
		<?php } else { ?>		
				<h4>Please Log-in To Post</h4>
		<?php } ?>
		</div>
 
</div> <!-- #simple-fep-postbox -->
<?php
	// Output the content.
	$output = ob_get_contents();
	ob_end_clean();
 
	// return only if we're inside a page. This won't list anything on a post or archive page. 
	if (is_page()) return  $output;
}
 
// Add the shortcode to WordPress. 
add_shortcode('simple-fep', 'simple_fep');
 
 
function simple_fep_errors(){
?>
<style>
.simple-fep-error{border:1px solid #CC0000;border-radius:5px;background-color: #FFEBE8;margin: 0 0 16px 0px;padding: 12px;}
</style>
<?php
	global $error_array;
	foreach($error_array as $error){
		echo '<p class="simple-fep-error">' . $error . '</p>';
	}
}
 
function simple_fep_notices(){
?>
<style>
.simple-fep-notice{ border:1px solid #E6DB55;border-radius:5px;background-color: #FFFBCC;margin: 0 0 16px 0px;padding: 12px;}
</style>
<?php
 
	global $notice_array;
	foreach($notice_array as $notice){
		echo '<p class="simple-fep-notice">' . $notice . '</p>';
	}
}
 
function simple_fep_add_post(){
	if ( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] ) && $_POST['action'] == 'post' ){
		if ( !is_user_logged_in() )
			return;
		global $current_user;
 
		$user_id		= $current_user->ID;
		$post_title     = $_POST['post-title'];
		$post_content	= $_POST['posttext'];
		$tags			= $_POST['tags'];
 
		global $error_array;
		$error_array = array();
 
		if (empty($post_title)) $error_array[]='Please add a title.';
		if (empty($post_content)) $error_array[]='Please add some content.';
 
		if (count($error_array) == 0){
 
			$post_id = wp_insert_post( array(
				'post_author'	=> $user_id,
				'post_title'	=> $post_title,
				'post_type'     => 'post',
				'post_content'	=> $post_content,
				'tags_input'	=> $tags,
				'post_status'	=> 'publish'
				) );			
 
			global $notice_array;
			$notice_array = array();
			$notice_array[] = "Thank you for posting. Your post is now live. ";
			add_action('simple-fep-notice', 'simple_fep_notices');
		} else {
			add_action('simple-fep-notice', 'simple_fep_errors');
		}
	}
}
 
add_action('init','simple_fep_add_post');

Braking down the code

We’ll start by creating plugin header. The only was WordPress knows a particular file is a plugin, is if it contains a short description in the plugin file. Our Simple Front End Posting plugin is no different.

/*
Plugin Name: Simple Front End Posting
Plugin URI: http://cozmoslabs.com/
Description: Really simple way of posting from the front end for WordPress
Author: Cristian Antohe	
Version: 0.1
Author URI: http://cozmoslabs.com/
*/

The Simple Front End Posting form

Our front end form posting will only contain the title, the content and an input field for tags (separated by a coma). This is mostly because it’s only supposed to be a demonstrative piece of code to get you started with front-end posting.

Since we are outputting a lot of HTML and CSS code, the only simple way of doing it is to use output buffering from php. That’s also because when you create a shortcode you should always use return, and not output anything using echo, for example.

An another thing we are doing here, is checking to see if the user is actually logged in or not. If not, we’re simply asking them to login. You can replace that piece of code with a login url of your own choice, and if you’re using Profile Builder for the front-end login, you can link to the page where you have the login shortcode.

function simple_fep_form($content = null) {
	global $post;
 
	// We're outputing a lot of html and the easiest way 
	// to do it is with output buffering from php.
	ob_start();
 
?>
<style>
#fep-new-post label{display:inline-block;width:15%;}
#fep-new-post input{width:60%;}
#fep-new-post input[type="submit"]{margin-left:15%;width:30%;padding:7px;}
#fep-new-post textarea{	display:inline-block;width:80%;vertical-align:top;}
</style>
<div id="simple-fep-postbox" class="<?php if(is_user_logged_in()) echo 'closed'; else echo 'loggedout'?>">
		<?php do_action( 'simple-fep-notice' ); ?>
		<div class="simple-fep-inputarea">
		<?php if(is_user_logged_in()) { ?>
			<form id="fep-new-post" name="new_post" method="post" action="<?php the_permalink(); ?>">
				<p><label>Title *</label><input type="text" id ="fep-post-title" name="post-title" /></p>
				<p><label>Content *</label><textarea class="fep-content" name="posttext" id="fep-post-text" tabindex="1" rows="4" cols="60"></textarea></p>
				<p><label>Tags</label><input id="fep-tags" name="tags" type="text" tabindex="2" autocomplete="off" value="<?php esc_attr_e( 'Add tags', 'simple-fep' ); ?>" onfocus="this.value=(this.value=='<?php echo esc_js( __( 'Add tags', 'simple-fep' ) ); ?>') ? '' : this.value;" onblur="this.value=(this.value=='') ? '<?php echo esc_js( __( 'Add tags', 'simple-fep' ) ); ?>' : this.value;" /></p>
				<input id="submit" type="submit" tabindex="3" value="<?php esc_attr_e( 'Post', 'simple-fep' ); ?>" />					
				<input type="hidden" name="action" value="post" />
				<input type="hidden" name="empty-description" id="empty-description" value="1"/>
				<?php wp_nonce_field( 'new-post' ); ?>
			</form>
		<?php } else { ?>		
				<h4>Please Log-in To Post</h4>
		<?php } ?>
		</div>
 
</div> <!-- #simple-fep-postbox -->
<?php
	// Output the content.
	$output = ob_get_contents();
	ob_end_clean();
 
	// return only if we're inside a page. This won't list anything on a post or archive page. 
	if (is_page()) return  $output;
}
WordPress Post From Front End Form

WordPress Simple Front End Posting form

The function that outputs the our form is actually our shortcode.
To create a shortcode in WordPress is really easy, just need to:

// Add the shortcode to WordPress. 
add_shortcode('simple-fep', 'simple_fep_form');

Where the first parameter is the shortcode name and the second one the function that outputs the content in your page.

Add a post to WordPress programmatically

Now that we have our form we need to process that information. We’re checking to see if our title and content was completed, and if that’s the case use wp_insert_post function to add our content to the database.

function simple_fep_add_post(){
	if ( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] ) && $_POST['action'] == 'post' ){
		if ( !is_user_logged_in() )
			return;
		global $current_user;
 
		$user_id		= $current_user->ID;
		$post_title     = $_POST['post-title'];
		$post_content	= $_POST['posttext'];
		$tags			= $_POST['tags'];
 
		global $error_array;
		$error_array = array();
 
		if (empty($post_title)) $error_array[]='Please add a title.';
		if (empty($post_content)) $error_array[]='Please add some content.';
 
		if (count($error_array) == 0){
 
			$post_id = wp_insert_post( array(
				'post_author'	=> $user_id,
				'post_title'	=> $post_title,
				'post_type'     => 'post',
				'post_content'	=> $post_content,
				'tags_input'	=> $tags,
				'post_status'	=> 'publish'
				) );			
 
			global $notice_array;
			$notice_array = array();
			$notice_array[] = "Thank you for posting. Your post is now live. ";
			add_action('simple-fep-notice', 'simple_fep_notices');
		} else {
			add_action('simple-fep-notice', 'simple_fep_errors');
		}
	}
}
 
add_action('init','simple_fep_add_post');

Error and notices

We also want people to know that the title and content are required fields, as well as congratulating them on the fact that they successfully posted something new.

There are two functions that take care of that. We’re using some global parameters to pass the notices and errors arrays around.

function simple_fep_errors(){
?>
<style>
.simple-fep-error{border:1px solid #CC0000;border-radius:5px;background-color: #FFEBE8;margin: 0 0 16px 0px;padding: 12px;}
</style>
<?php
	global $error_array;
	foreach($error_array as $error){
		echo '<p class="simple-fep-error">' . $error . '</p>';
	}
}
 
function simple_fep_notices(){
?>
<style>
.simple-fep-notice{ border:1px solid #E6DB55;border-radius:5px;background-color: #FFFBCC;margin: 0 0 16px 0px;padding: 12px;}
</style>
<?php
 
	global $notice_array;
	foreach($notice_array as $notice){
		echo '<p class="simple-fep-notice">' . $notice . '</p>';
	}
}

Conclusions

While this was easy and fun to code, I don’t recommend using this in production as it is. There are some things I haven’t treated like checking to see if the $_POST was set (PHP notices will be issued due to that), if you have an error (like you forgot to complete the title, everything you wrote in the content and tags will be lost), no front-end editing of any kind, no integrated login/registration, no options for the shortcode (like selecting the post type where you can post), no image upload and many more NO’s.

This is simply an introduction to making WordPress post from front end. While it looks simple (just 120 lines of code and I’m sure you could do it in less), once you start adding functionality you realize there are many problems that aren’t so easy to solve. But we’ll leave that for another time.

You just finished reading “WordPress Post From Front End” by Cozmoslabs.com.

P.S. If you’re looking for an all-in-one solution to make WordPress post from front end you might want to check out:

WordPress Creation Kit with Front End Posting

wck_pro_icon

Have you tried making WordPress to post something from the front-end? It’s not that straight forward as you might expect it to be.
WCK – Front End Posting tries to solve just that.

  • Create and edit posts/pages/custom post types directly from the front end
  • WYSIWYG editor
  • Easy usage of shortcodes
  • Quick access to Front End Dashboard
  • And much more!

Find out more about WCK – Front End Posting!

About Cristian Antohe

Cristian Antohe is the co-founder Cozmoslabs. He's a WordPress developer, web designer and Open Source fanatic. He's part of the team that developed Profile Builder and WordPress Creation Kit and also helps curate wpMail.me.

Find me on: Google + | Twitter

9 thoughts on “WordPress Post From Front End

  1. Hi,

    That’s a great way to create a frontend submission form, I’ve successfully created and added the files into my website, walllaaah, it’s working perfectly but I was wondering how to modify it to let post into a specific category with a rich text enabled??

    hope to get some help on that,

    Thnx,

  2. quite interesting at start and later i was just puzzled as i am not much into programming. i have tried P2 TWITTER theme which provide front end facility but it didn’t did well as i want facebook wall type fast yet easy front end editor. any suggestion?

  3. Hello,
    thank you for this post

    there is a problem

    if i refresh page after add post

    Warning: : failed to open stream: No such file or directory in C:\xampp\htdocs\wp\wp-includes\class-wp-theme.php on line 948

  4. So are you telling me I can essentially build an app with this plugin? Basically create a template that the user can edit and add content that will populate to the site. Is this true?

Leave a Reply

Your email address will not be published. Required fields are marked *


one × 7 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>