Lately I’ve been working on another side project. A wine rating site that we hope to launch soon. But one of the requirements for the site was that once a wine rater logged in, they should have access to a form to rate wines. I didn’t want anyone to have to fuss with the back end of WordPress. I just wanted to present them with a simple form to fill out. Let’s look into how that’s done.
The first thing you need to figure out is the details. Sketch out your form, what types of data do you need? Is it just normal post stuff (title, post, categories, keywords), or do you need more? You can use custom fields/meta boxes from the front end. You can also allow thumbnail uploads to set as the featured image, or multiple image uploads. Today we will just look at the basic stuff. Tomorrow we will add image uploads.
After you have your form all filled out you need to figure out some more details. Since the main focus of my site is going to be wine rating, I want to use the standard post as wine rating. I will also use the standard categories to present a dropdown of wine types. And I will use the normal tagging system to allow for keywords. You can follow the same setup, or you can register a new post type, and use custom taxonomies, these things would only require some simple changes in the code I’ll give you, and I’ll point them out.
Now that we have all the details figured out, we need to get into the code. I set up a simple page template first. Now since this is just another form really, I borrowed heavily from my own article here about Contact Form 7. You’ll see a few blocks of code down a setup for a simple page template, it looks like:
<?php /* Template Name: Wine Rating Form */ get_header(); ?> <div id="container"> <div id="content" role="main"> <?php if ( have_posts() ) while ( have_posts() ) : the_post(); ?> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <?php if ( is_front_page() ) { ?> <h2 class="entry-title"><?php the_title(); ?></h2> <?php } else { ?> <h1 class="entry-title"><?php the_title(); ?></h1> <?php } ?> <div class="form-content"> <?php the_content(); ?> <?php wp_link_pages( array( 'before' => '<div class="page-link">' . __( 'Pages:', 'twentyten' ), 'after' => '</div>' ) ); ?> <?php edit_post_link( __( 'Edit', 'twentyten' ), '<span class="edit-link">', '</span>' ); ?> </div><!-- .entry-content --> </div><!-- #post-## --> <?php comments_template( '', true ); ?> <?php endwhile; // end of the loop. ?> </div><!-- #content --> </div><!-- #container --> <?php get_sidebar(); ?> <?php get_footer(); ?>
You’ll see that the template is the same as on the example in the previous post, except I change the name to Wine Rating Form in the header of the code. So save that as whatever you like, I called it ratewine.php. You’ll see a call to the_content on line 20. I’m going to put my new form directly under that. You can do the same, or you can delete the_content, it’s up to you. I left it in as I may decide later to add some instructions through the normal WP page interface.
You’ll also notice that on line 19, I have div class=form-content rather than the normal entry-content from twenty ten. That is just to avoid having twenty ten’s css play too much on our form. That is explained in this article as well.
Let’s add in our form now! Again looking at the article from before you can see how I like to lay out my forms. I’m going to follow the same format here:
<!-- WINE RATING FORM --> <div class="wpcf7"> <form id="new_post" name="new_post" method="post" action="" class="wpcf7-form" enctype="multipart/form-data"> <!-- post name --> <fieldset name="name"> <label for="title">Wine Name:</label> <input type="text" id="title" value="" tabindex="5" name="title" /> </fieldset> <!-- post Category --> <fieldset class="category"> <label for="cat">Type:</label> <?php wp_dropdown_categories( 'tab_index=10&taxonomy=category&hide_empty=0' ); ?> </fieldset> <!-- post Content --> <fieldset class="content"> <label for="description">Description and Notes:</label> <textarea id="description" tabindex="15" name="description" cols="80" rows="10"></textarea> </fieldset> <!-- post tags --> <fieldset class="tags"> <label for="post_tags">Additional Keywords (comma separated):</label> <input type="text" value="" tabindex="35" name="post_tags" id="post_tags" /> </fieldset> <fieldset class="submit"> <input type="submit" value="Post Review" tabindex="40" id="submit" name="submit" /> </fieldset> <input type="hidden" name="action" value="new_post" /> <?php wp_nonce_field( 'new-post' ); ?> </form> </div> <!-- END WPCF7 -->
You’ll notice I have some tags in there that come from Contact Form 7. we wrap the form in a wpcf7 class, and apply the wpcf7-form class to the actual form. This is not required of course. I just did it because I already have css in place from this tutorial. If I apply the same classes, I can reuse the css with no edits. Keep things simple eh!
The important part is to make sure the name and ID on these inputs match up with what I have. That is because we are using standard inputs. These will save to specific values that go to your database from the block of code I’m about to give you. You will also notice the second block makes use of wp_dropdown_categories, I like the idea of giving a list of categories here, since my cats are wine types. This is one place you could swap in a custom taxonomy. And finally at the bottom you’ll notice a little use of wp_nonce_field again, just a simple verification on where the data is coming from.
So that has our form all built. If you saved it now, and then applied this template to a page you would have your post form. Depending on if you followed this tutorial before, it may or may not be styled. But the big thing you would notice is that the form doesn’t do anything! You can fill it out for sure, but the data does nothing. Let’s fix that!
Way at the top of our template, under the page template header, but above the get_header call, we are going to put some code.
if( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] ) && $_POST['action'] == "new_post") { // Do some minor form validation to make sure there is content if (isset ($_POST['title'])) { $title = $_POST['title']; } else { echo 'Please enter the wine name'; } if (isset ($_POST['description'])) { $description = $_POST['description']; } else { echo 'Please enter some notes'; } $tags = $_POST['post_tags']; // ADD THE FORM INPUT TO $new_post ARRAY $new_post = array( 'post_title' => $title, 'post_content' => $description, 'post_category' => array($_POST['cat']), // Usable for custom taxonomies too 'tags_input' => array($tags), 'post_status' => 'publish', // Choose: publish, preview, future, draft, etc. 'post_type' => 'post' //'post',page' or use a custom post type if you want to ); //SAVE THE POST $pid = wp_insert_post($new_post); //SET OUR TAGS UP PROPERLY wp_set_post_tags($pid, $_POST['post_tags']); //REDIRECT TO THE NEW POST ON SAVE $link = get_permalink( $pid ); wp_redirect( $link ); } // END THE IF STATEMENT THAT STARTED THE WHOLE FORM //POST THE POST YO do_action('wp_insert_post', 'wp_insert_post');
Up at the top are some instruction to WordPress to use this as a post, and we set up new_post which is what our nonce_field verifies against. After that we do some validation. Just some basic fields we want to require. And then we set up the array which grabs the data from our form and puts it all together to insert into the WordPress database. The wp_redirect line is optional, this redirects the user to their new post once they hit submit. This works great on a wine rating site I thought, take the user right to their post. (redirect threw errors, working on it) I have update the above code again. Everything works splendidly. The redirect block of code is optional or can be edited to redirect where you would like.
I’ve tried to mark with comments in the code where custom post types and custom taxonomies can be swapped out. But that pretty well does it! With this code you can have your own front end post form.
If your form isn’t styled, just take a look at this post, it has the styling I use for Contact Form 7, which if you set up your form using the layout I did above, it will work for this form as well.
Now just save up this page template to your theme and apply it to a page, and you have a post from the front end form available to your users! You probably don’t want this available to just anyone, I keep the access restricted to authors and above on my site.
Notes For Multi Category Select:I haven’t had time to totally sort this out yet, but I’m posting it here for info.
If you replace the wp_dropdown_categories line with this:
<?php $select_cats = wp_dropdown_categories( array( 'echo' => 0, 'taxonomy' => 'category', 'hide_empty' => 0 ) ); $select_cats = str_replace( "name='cat' id=", "name='cat[]' multiple='multiple' id=", $select_cats ); echo $select_cats; ?>
It will allow for multiple category select. However, something needs done with the processing code above to allow that array to be handled.
Around line 16 (of the processing code), where we set up the post tags, I have this
$post_cat = $_POST['cat'];
And then in the array, I replaced the post category line with this
'post_category' => $post_cat,
And that was it, I am now able to select and save multiple categories!
UPDATE: If you check out this post, the end review of this form, down at the bottom we have an update with a possible fix to get the validation working properly. If you have a chance to try the fix out and report back if it works, that would be awesome!
UPDATE(2): If you cruise around the site, and search a little, you’ll find that there are a whole variety of posts related to this frontend post form. But here is a couple valuable links – our great VoodooPress readers have been busy! One of our readers provided his technique for editing and deleting these posts from the front end. Another reader got validation working and provided us with that code! That’s a lot of cool stuff! If you have anything to add here, feel free to submit your stuff, or even ask about a guest post! We are well on our way to posting perfection!