Create a “report post” form in WordPress

In a previous post I wrote about how to build a Mailchimp subscription form using the native WordPress Ajax API, jQuery and the Mailchimp API. Today we use the same Ajax API and jQuery to create a simple report post form. You can use that (additional) form to get a quick feedback from your blog’s reader without using the WordPress comment function.

Why a report post function instead of the regular comment form?

You might have lots of visitors every day, but only a few comments. Not every visitor like to tell you something about your post or has a question. If you use a the “report post” function as feedback form too, you get some more response on your work. It’s also an interaction on your site and maybe you like to give a tiny award to you visitors, for example showing a “secret” link in response.

The tutorial, create the feedback form

First I create a small HTML form, using the WordPress shortcode feature I’m able to place my form inside an article or a theme file (you need to use the short code inside the loop). Create a file named “my-report-post.php” inside the plugin directory and add the following code:

Plugin Name: Report post
Plugin URI:
Description: Creates a simple report post form that gives the visitor the ability to report the article he is reading
Version: 1.0
Author: Olaf Lederer
Author URI:
$rp_options = array(
	'broring' => 'This is really boring',
	'difficult' => 'I don\'t understand this',
	'great' => 'Great stuff, need more'
$mail_report_to = '');
function createReportPostForm() {
	global $rp_options, $post;
	$html = '
	<div id="formcont">
		<h3>Report this article</h3>
		<form id="myform">
				<label for="name">What\'s wrong?</label>
				<select name="report-msg" id="report-msg">
					<option val="">...</option>';
	foreach ($rp_options as $ok => $ov) {
		$html .= '
					<option val="'.$ok.'">'.$ov.'</option>';
	$html .= '
				<input type="hidden" name="posturl" value="'.get_permalink().'" />
				<input type="hidden" name="action" value="ajax_action" />
				<input type="button" value="Submit" id="submit_button" />
	<div id="output"></div>';
	return $html;
add_shortcode('rp-form', 'createReportPostForm');

I used the array named $rp_options outside the function to make it easier for the WordPress admin to edit the messages or options.

jQuery Ajax code

Next I use the following Ajax code to process my form; create a JavaScript file with the name “rp-script.js” and add the code:

jQuery(document).ready(function($) {
	$('#submit_button').click(function() {
			type: 'POST',
			url: ajax_object.ajaxurl,
			data: $('form#myform').serialize(),
			dataType: 'json',
			beforeSend: function() {
				var report = $('#report-msg').val();
				if (!report) {
					return false;
			success: function(response) {
				if (response.status == 'success') {

Inside the code I’ve used two members of the ajax_object, I need to define the two values inside the functions.php file now:

function rp_add_header() {
	if (is_single() || is_page()) { 
		// include the jquery Ajax/form validation javascript file
		wp_enqueue_script( 'ajax-script', plugin_dir_url(__FILE__).'rp-script.js', array('jquery'), 1.0 ); 
		// create the three Ajax variables used in your template file
		wp_localize_script( 'ajax-script', 'ajax_object', array(
						'ajaxurl' => admin_url( 'admin-ajax.php' ),
						'errorEmpty' => __( 'You need to select one of the options.' )
		add_action( 'wp_ajax_ajax_action', 'ajax_action_stuff' ); 
		add_action( 'wp_ajax_nopriv_ajax_action', 'ajax_action_stuff' ); 

I use the same function to include the JavaScript file I’ve created before. I like to include the code only inside pages from the type single post or page.

Process and email the form values

After the visitor has submitted the report post form, I need to process the form values and after that the result is send by email:

function ajax_action_stuff() {
	global $mail_report_to;
	$resp['status'] = 'error';
	$resp['errmessage'] = '';
	if (!empty($_POST['report-msg'])) {
		$report_msg = $_POST['report-msg'];
		$report_url = $_POST['posturl'];
		$subject = 'Post report['.get_option('blogname').']';
		$header = 'From: '.get_option('blogname').' <'.get_option('admin_email').'>' . "\r\n";
		$message = '
Someone has reported a post:
Report: '.$report_msg.'
Post URL: '.$report_url.'
Visitor IP: '.$_SERVER['REMOTE_ADDR'].'
Date/time: '.date('Y-m-d H:i:s');
		if ( wp_mail($mail_report_to, $subject, $message, $header) ) {
			$resp['status'] = 'success';
			$resp['errmessage'] = 'Your report is submitted, thanks.';
		} else {
			$resp['errmessage'] = 'Something went wrong, please try again later.';
	} else {
		$resp['errmessage'] = 'Please select one of the options.';
	header( "Content-Type: application/json" );
	echo json_encode($resp);

This function is called by the WordPress Ajax API and the email address I defined in the beginning is used to send the email message. After the email message is processed the script returns a few value pairs (using JSON formatting) and the client side code will parse these values to show the visitor a message based on his request.

This code is just an example, it depends on your site what kind of feedback you like to request. Change the messages for the select menu to the values which ever you like. You can download the report post plugin here.

Published in: WordPress Development


  1. A nice thing about this approach is that most of it is client-side- the PHP portion could be replaced by any templating/rendering language. For example here’s how one might rewrite the inner loop of “createReportPostForm” in Scheme, a language I like to use for templating:

    (define (render-option ok ov)`(option (@ (val ,ok)) ,ov))
    (hash-map->list render-option rp-options)

  2. Hi Greg,
    right the function is very simple, but normally the array of option is obtained from the database, where people enter the values in some WordPress admin panel. That’s the reason why I used the array instead of some static HTML code.

  3. Nice function, while my site has more than 500 unique visitors a day, I have almost no comments. Using this function I hope to get some response from visitors.

Comments are closed.