Create a Voting Plugin for WordPress

Share this article

Introduction
WordPress, as a platform, has moved from only being a blogging platform, to a platform for a wide variety of websites. One major reason for this, is how easily WordPress can be customized and extended. This enables programmers to create far more functional sites than a normal blog. In the following tutorial we are going to create a plugin which will make wordpress an article voting site and also create a widget to display the top voted posts.

Creating the Plugin

To create a plugin create a file voteme.php in your wp-content/plugins/voteme folder. To create a plugin we have to add the plugin header as follows
<?php
/*
Plugin Name: Vote Me
Plugin URI:
Description: This plugin to add vote in posts
Author: Abbas
Version: 0.1
Author URI:
*/
We will also define some named constants for our plugin base url, and the plugin path as follows:
define('VOTEMESURL', WP_PLUGIN_URL."/".dirname( plugin_basename( __FILE__ ) ) );
define('VOTEMEPATH', WP_PLUGIN_DIR."/".dirname( plugin_basename( __FILE__ ) ) );
Also, create a js folder in your voteme folder, and add a file voteme.js file in it. The folder structure of the plugin would be as follows. We will now enqueue the scripts by with ‘wp_enqueue_scripts’ and enqueue our JS file, and localize it to store the WP Ajax url which we will use for our ajax calls.
function voteme_enqueuescripts()
{
	wp_enqueue_script('voteme', VOTEMESURL.'/js/voteme.js', array('jquery'));
	wp_localize_script( 'voteme', 'votemeajax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
add_action('wp_enqueue_scripts', voteme_enqueuescripts);</pre>
After this we should be able to see our plugin in the plugin list and we should activate it. 2

Adding the vote link to posts

Now we will add a link to all the posts displaying the current votes and a link to add the vote by ajax. Following is the code
function voteme_getvotelink()
{
$votemelink = "";

$post_ID = get_the_ID();
$votemecount = get_post_meta($post_ID, '_votemecount', true) != '' ? get_post_meta($post_ID, '_votemecount', true) : '0';

$link = $votemecount.' <a onclick="votemeaddvote('.$post_ID.');">'.'Vote'.'</a>';

$votemelink = '<div id="voteme-'.$post_ID.'">';
$votemelink .= '<span>'.$link.'</span>';
$votemelink .= '</div>';

return $votemelink;
}

function voteme_printvotelink($content)
{
return $content.voteme_getvotelink();
}
add_filter('the_content', voteme_printvotelink);
Here, we create a function voteme_getvote link which first gets the current post id and then reads the post meta _votemecount using get_post_meta. We use the post meta _votemecount to store the votes for a particular post. Then we create a link by adding the JavaScript function votemeaddvote on the click of the link. The function votemeaddvote we will see shortly. Next, we use the WordPress filter the_content to hook our function to add this link after each post. You will be able to see the number of votes and vote link below each post now. 3

Adding votes using Ajax

As we have added the vote link to every posts its time we make it functional to actually add votes. The JavaScript function which does the AJAX vote posting is below
function votemeaddvote(postId)
{
	jQuery.ajax({
	type: 'POST',
	url: votemeajax.ajaxurl,
	data: {
	action: 'voteme_addvote',
	postid: postId
},

success:function(data, textStatus, XMLHttpRequest){

	var linkid = '#voteme-' + postId;
	jQuery(linkid).html('');
	jQuery(linkid).append(data);
	},
	error: function(MLHttpRequest, textStatus, errorThrown){
		alert(errorThrown);
		}
	});
}
This sends an AJAX request to WordPress, and sends the action as voteme_addvote
and the post ID. If the AJAX call is successful it just adds the data in the div for that post. If there is an error it will just display the error. To handle the AJAX request we will have to create a function as follows
function voteme_addvote()
{
		$results = '';
		global $wpdb;
		$post_ID = $_POST['postid'];
		$votemecount = get_post_meta($post_ID, '_votemecount', true) != '' ? get_post_meta($post_ID, '_votemecount', true) : '0';
		$votemecountNew = $votemecount + 1;
		update_post_meta($post_ID, '_votemecount', $votemecountNew);

		$results.='<div class="votescore" >'.$votemecountNew.'</div>';

		// Return the String
		die($results);
	}

		// creating Ajax call for WordPress
		add_action( 'wp_ajax_nopriv_voteme_addvote', 'voteme_addvote' );
		add_action( 'wp_ajax_voteme_addvote', 'voteme_addvote' );
In function voteme_addvote we get the post ID from the posted data and then get the current vote count for that post. Then we increment the vote by 1 and update the post meta again. Then we create a div with the new vote details and sent that back by using die($results); To register this function to handle AJAX request for action: ‘voteme_addvote’ using the following wordpress hooks
// creating Ajax call for WordPress
		add_action( 'wp_ajax_nopriv_voteme_addvote', 'voteme_addvote' );
		add_action( 'wp_ajax_voteme_addvote', 'voteme_addvote' );</pre>
Now we’ll be able to click the vote link to add the vote on the post with AJAX. 4

Customizing WordPress admin to show post votes

It would be very convenient for the admin to be able to see the votes on the post edit page. Then from there he would be able to see the post details, and also the vote details on that page. To add the vote details we need to add a hook on the filter ‘manage_edit-post_columns’ to add the Votes as a column on the post edit page as follows.
add_filter( 'manage_edit-post_columns', 'voteme_extra_post_columns' );
function voteme_extra_post_columns( $columns ) {
$columns[ 'votemecount' ] = __( 'Votes' );
return $columns;
}
Now we need to provide the value to display for this column. To do this we need to hook into the filter manage_posts_custom_column. When we hook into this filter our function voteme_post_column_row is called and with the post column name. Here we only process out column votemecount and give the value for it. We read the value from our custom column _votemecount and echo it. The complete code for this is as follows.
function voteme_post_column_row( $column ) {
	if ( $column != 'votemecount' )
	return;

	global $post;
	$post_id = $post->ID;
	$votemecount = get_post_meta($post_id, '_votemecount', true) != '' ? get_post_meta($post_id, '_votemecount', true) : '0';
	echo $votemecount;

}

add_action( 'manage_posts_custom_column', 'voteme_post_column_row', 10, 2 );
On the post edit page you should be able to see the vote details column. 5

Sorting post on basics of votes in WordPress admin

It would be convenient for the admin if we make the vote column sortable. He would be able to see the most voted posts and also the least voted posts. To do this first we must make the Vote column clickable for sorting. To do this we hook into the filter manage_edit-post_sortable_columns and add the vote column to it as follows.
add_filter( 'manage_edit-post_sortable_columns', 'voteme_post_sortable_columns' );

function voteme_post_sortable_columns( $columns )
{
	$columns[ 'votemecount' ] = votemecount;
	return $columns;
}
Then we add a hook onto the load-edit.php hook when we have the order by request for votemecount we merge the sort parameters with
'meta_key' => '_votemecount',
'orderby' => 'meta_value_num'
So that it sorts on the basics of custom column and considers that column as numeric rather than as a string. The code for it is as follows.
add_action( 'load-edit.php', 'voteme_post_edit' );

function voteme_post_edit()
{
	add_filter( 'request', 'voteme_sort_posts' );
}
	function voteme_sort_posts( $vars )
{
	if ( isset( $vars['post_type'] ) &amp;&amp; 'post' == $vars['post_type'] )
	{
		if ( isset( $vars['orderby'] ) &amp;&amp; 'votemecount' == $vars['orderby'] )
		{
			$vars = array_merge(
			$vars,
			array(
			'meta_key' => '_votemecount',
			'orderby' => 'meta_value_num'
			)
			);
		}
	}
return $vars;
}
Now in the admin page the vote column will be clickable and clicking on it will sort the post on the basics of votes. 6

Allowing only Registered users to vote

We might want that not anyone can vote on the post. We might want to check that only users who are registered on our site will be able to vote. We’ll control this via creating a setting page for our plugin as follows
// Settings

add_action('admin_menu', 'voteme_create_menu');

function voteme_create_menu() {
add_submenu_page('options-general.php','Vote Me','Vote Me','manage_options', __FILE__.'voteme_settings_page','voteme_settings_page');
}
function voteme_settings_page() {
?>

<div class="wrap">

<?php
global $blog_id;

if( isset( $_POST['votemeoptionssubmit'] ) )
{
update_option( 'votemelogincompulsory' , $_POST[ 'votemelogincompulsory' ] );
}

?>
<div id="settingsform">
<form id='votemesettingform' method="post" action="">

<h1><?php echo 'Vote Me Settings'; ?></h1>

<Input type = 'Radio' Name ='votemelogincompulsory' value= 'yes' <?php if( get_option('votemelogincompulsory') == 'yes' ) echo 'checked';?> >User Must be logged in for voting
<br/>
<Input type = 'Radio' Name ='votemelogincompulsory' value= 'no' <?php if( get_option('votemelogincompulsory') != 'yes' ) echo 'checked';?> >User might not be logged in for voting
<br/><br/>
<p class="submit">
<input type="submit" id="votemeoptionssubmit" name="votemeoptionssubmit" class="button-primary" value="<?php echo 'Save'; ?>" />
</p>

</form>

</div>

</div>
<?php }
Here we hook onto admin_menu and create our setting page to show radio buttons for whether to allow voting for registered users only. Then based on the option selected by the admin we update the option votemelogincompulsory. The settings page will look as follows. 7 Then, update the voteme_getvotelink function to read the option votemelogincompulsory and to show the votelink or the login link depending on the option selected by the user and wthere the user is logged in or no. The code for it is as follows
function voteme_getvotelink()
{
	$votemelink = "";
	if( get_option('votemelogincompulsory') != 'yes' || is_user_logged_in() )
	{
		$post_ID = get_the_ID();
		$votemecount = get_post_meta($post_ID, '_votemecount', true) != '' ? get_post_meta($post_ID, '_votemecount', true) : '0';

		$link = $votemecount.' <a onclick="votemeaddvote('.$post_ID.');">'.'Vote'.'</a>';

		$votemelink = '<div id="voteme-'.$post_ID.'">';
		$votemelink .= '<span>'.$link.'</span>';
		$votemelink .= '</div>';
	}
else
{
	$register_link = site_url('wp-login.php', 'login') ;
	$votemelink = '<div class="votelink" >'." <a href=".$register_link.">"."Vote"."</a>".'</div>';
}

return $votemelink;
}

Creating a widget to display Top voted posts.

Now we will create a widget to display the top voted posts. First we create a function called voteme_get_highest_voted_posts which takes the number of posts and then displays those many post in order of the highest voted posts. It also displays the number of vote for each post.
function voteme_get_highest_voted_posts($numberofpost)
{
	$output = '';
	$the_query = new WP_Query( 'meta_key=_votemecount&amp;orderby=meta_value_num&amp;order=DESC&amp;posts_per_page='.$numberofpost );
	// The Loop
	while ( $the_query->have_posts() ) : $the_query->the_post();
	$output .= '<li>';
	$output .= '<a href="'.get_permalink(). '" rel="bookmark">'.get_the_title().'('.get_post_meta(get_the_ID(), '_votemecount', true).')'.'</a> ';
	$output .= '</li>';
	endwhile;
	wp_reset_postdata();
	return $output;
}
Then we create a widget which takes the number of post and the title from the user and uses the abpve function to display the top voted posts.
class VoteMeTopVotedWidget extends WP_Widget {

	function VoteMeTopVotedWidget() {
	// widget actual processes
	$widget_ops = array('classname' => 'VoteMeTopVotedWidget', 'description' => 'Widget for top voted Posts.' );
	$this->WP_Widget('VoteMeTopVotedWidget','VoteMeTopVotedWidget', $widget_ops);
}

function form($instance) {
	// outputs the options form on admin
	$defaults = array( 'title' => 'Top Voted Posts', 'numberofposts' => '5' );
	$instance = wp_parse_args( (array) $instance, $defaults );

	?>
	<p>
	<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php echo 'Title:'; ?></label>
	<input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" class="widefat" />
	</p>
	<p>
	<label for="<?php echo $this->get_field_id( 'numberofposts' ); ?>"><?php echo 'Number of Posts'; ?></label>
	<input id="<?php echo $this->get_field_id( 'numberofposts' ); ?>" name="<?php echo $this->get_field_name( 'numberofposts' ); ?>" value="<?php echo $instance['numberofposts']; ?>" class="widefat" />
	</p>

	<?php

}

function update($new_instance, $old_instance) {
	// processes widget options to be saved

	$instance = $old_instance;
	$instance['title'] = strip_tags( $new_instance['title'] );
	$instance['numberofposts'] = $new_instance['numberofposts'];
	return $instance;
}

function widget($args, $instance) {
	// outputs the content of the widget
	extract( $args );
	$title = apply_filters('widget_title', $instance['title'] );
	echo $before_widget;
	if ( $title )
	echo $before_title . $title . $after_title;

	echo '<ul>';
	echo voteme_get_highest_voted_posts($instance['numberofposts']);
	echo '</ul>';
	echo $after_widget;
}

}

function voteme_widget_init() {

	// Check for the required API functions
	if ( !function_exists('register_widget') )
	return;

	register_widget('VoteMeTopVotedWidget');
}

add_action('widgets_init', 'voteme_widget_init');</pre>
The widget will look as follows 8 On the front, the widget will look as follows 9

Conclusion.

With custom fields, WordPress makes it easy for us to extend it to use for different purposes. WordPress has good support for AJAX as we have seen in this tutorial. So, happy WordPress development!

Frequently Asked Questions about Creating a Voting Plugin for WordPress

How can I customize the design of my voting plugin?

Customizing the design of your voting plugin can be done through CSS. Most voting plugins come with a default design, but you can modify it to match your website’s theme. You can change the colors, fonts, button styles, and more. If you’re not familiar with CSS, there are many online tutorials that can guide you through the process. Alternatively, you can hire a web developer to do the customization for you.

Can I use a voting plugin on a multi-language site?

Yes, most voting plugins support multi-language sites. They usually come with .po and .mo files which you can use to translate the plugin into your desired language. Some plugins also support WPML and Polylang, two popular WordPress translation plugins.

How can I prevent fraudulent votes?

Most voting plugins have built-in measures to prevent fraudulent votes. These include IP checking, cookie checking, and captcha verification. Some plugins also allow you to set a voting frequency limit, such as one vote per day, to further prevent vote manipulation.

Can I display the voting results on my site?

Yes, most voting plugins allow you to display the voting results on your site. You can usually choose to display the results in different formats, such as a bar graph, pie chart, or simple text. Some plugins also allow you to hide the results until the voting period is over.

Can I use a voting plugin for user-generated content?

Yes, some voting plugins allow users to submit their own options or answers. This can be useful for polls or contests where you want to involve your audience more directly. However, you should be aware that this feature may require additional moderation to prevent inappropriate submissions.

How can I export the voting data?

Most voting plugins allow you to export the voting data in various formats, such as CSV or Excel. This can be useful if you want to analyze the data further or use it in other applications.

Can I integrate a voting plugin with my email marketing software?

Some voting plugins offer integration with popular email marketing software like MailChimp or AWeber. This can be useful if you want to collect email addresses from voters for future marketing campaigns.

Can I use a voting plugin on a mobile device?

Yes, most voting plugins are responsive and work well on mobile devices. However, you should always test the plugin on different devices and screen sizes to ensure it looks and works as expected.

Can I schedule when the voting starts and ends?

Yes, most voting plugins allow you to schedule when the voting starts and ends. This can be useful if you’re running a contest or poll with a specific timeframe.

Can I use a voting plugin for a multi-page poll or survey?

Yes, some voting plugins support multi-page polls or surveys. This can be useful if you have a lot of questions or options and don’t want to overwhelm your voters with a long page.

Abbas SuterwalaAbbas Suterwala
View Author

Abbas is a software engineer by profession and a passionate coder who lives every moment to the fullest. He loves open source projects and WordPress. When not chilling around with friends he's occupied with one of the following open source projects he's built: Choomantar, The Browser Counter WordPress plugin, and Google Buzz From Admin.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week