At the end of this tutorial you will know how to code:
- Functional WordPress widget.
- Functional WordPress plugin.
- Display some content on the home page through a widget.
- Make Ajax calls from the home page.
- Use jQuery with WordPress.
- Create your own custom database tables with a plugin.
I assume you have a functional WordPress site running, with you having access to the plugin folder. All the code below was tested on a site running WordPress mu, but it should work with a single user WordPress. If you find any discrepancies please let me know.
We will be building a WordPress widget/plugin which will display an empty text box in the home page were users can input some text. Once the input text is submitted, it will be stored in our custom table.
Time to get our hands dirty. Let us first start with the plugin part. First step towards writing a plugin, is to enable WordPress to display the plugin in it’s plugin configuration page, so that the admin can activate the plugin. Create a folder called my-plugin inside the WordPress plugin folder. Inside my-plugin create a file called my-plugin.php and add the following to the header.
<?php /* Plugin Name: My Plugin Plugin URI: {URI where you plan to host your plugin file} Description: A plugin built as part of WordPress plugin tutorial. Version: 1 Author: {Your name} Author URI: {Your home page} */ ?>
Now go to WordPress plugin configuration page and you should see “My Plugin” displayed as one of the plugins along with all other plugins that you have.
Now let us spice it up. This plugin once activated will create a custom table in WordPress DB to store the user text. Create a function that has to be run when an user activates the plugin.
Add the below to my-plugin.php
register_activation_hook( __FILE__, 'my_plugin_install' ); my_plugin_install() { }
Above, we have created a function called my_plugin_install which we have registered with WordPress. Now when an user activates “My Plugin”, my_plugin_install function will be run.
Now, let us add some code to create our table.
global $my_plugin_table; global $my_plugin_db_version; global $wpdb; $my_plugin_table = $wpdb->prefix . 'my_plugin'; $my_plugin_db_version = '1.0'; register_activation_hook( __FILE__, 'my_plugin_install' ); function my_plugin_install() { global $wpdb; global $my_plugin_table; global $my_plugin_db_version; if ( $wpdb->get_var( "show tables like '$my_plugin_table'" ) != $my_plugin_table ) { $sql = "CREATE TABLE $my_plugin_table (". "id int NOT NULL AUTO_INCREMENT, ". "user_text text NOT NULL, ". "UNIQUE KEY id (id) ". ")"; require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); dbDelta( $sql ); add_option( "my_plugin_db_version", $my_plugin_db_version ); } }
So, what does the above code do?
It checks as to whether there is a table by the name $my_plugin_table. If it is present, then does nothing. If not, creates the table and adds the table version to the options so that we can use it next time in case we want to modify the table in an upcoming release. For a detailed explanation of table creation, check this WordPress documentation. Make sure that all the variables that you have declared outside the install function are global. If they are not global, the function will not be able to read them. Check this out for the reason.
Now, activate the plugin. Once activated, see whether your new table is listed in WordPress DB.
Now for the widget creation part. Add the below code to my_plugin.php file.
class MyWidget extends WP_Widget { function MyWidget() { parent::WP_Widget( false, $name = 'My Widget' ); } function widget( $args, $instance ) { extract( $args ); $title = apply_filters( 'widget_title', $instance['title'] ); ?> <?php echo $before_widget; ?> <?php if ($title) { echo $before_title . $title . $after_title; } ?> <div class="my_textbox"> <input type='text' name='my_text' id='my_text_id'/> <input type='button' value='Submit' id='my_text_submit_id'/> </div> <?php echo $after_widget; ?> <?php } function update( $new_instance, $old_instance ) { return $new_instance; } function form( $instance ) { $title = esc_attr( $instance['title'] ); ?> <p> <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?> <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" /> </label> </p> <?php } } add_action( 'widgets_init', 'MyWidgetInit' ); function MyWidgetInit() { register_widget( 'MyWidget' ); }
I am not going to explain the above, as it is almost a copy past from this.
Now, when you go to your widget addition screen, you should see “My Widget” as one of the widgets. Drag and drop it to the right side bar, give it a title and save it. Go to your home page and you should see your widget in the right side bar.
As of now, our widget does nothing, other than display a text box to the end user. Now comes the part where you send the user input to the back end using AJAX and persist it in the database. This is not properly documented in WordPress and I had a pretty tough time figuring it out.
For AJAX, we will be using jQuery JavaScript framework. We do not have to do anything to include jQuery, as it is already enabled in WordPress. All we have to do is, use jQuery in no conflict mode.
Now we need two functions, one for the JavaScript custom code that has to be included in the home page, the other for the AJAX action.
Let us start off with the back end code.
function my_widget_action() { global $wpdb; global $my_plugin_table; $user_text = $wpdb->escape( $_POST['user_text'] ); $query = "INSERT INTO $my_plugin_table (user_text) VALUES ('$user_text')"; $wpdb->query( $query ); echo 'success'; }
The above code, takes the user input text from post and stores it in DB. Now we have to make WordPress aware of the fact that, the above function should be executed for the AJAX request. We do this by adding the below to my_plugin.php file.
add_action( 'wp_ajax_my_widget_action', 'my_widget_action' ); add_action( 'wp_ajax_nopriv_my_widget_action', 'my_widget_action' );
In the above, the part ‘wp_ajax_’ and ‘wp_ajax_nopriv’ have to be named as they. The part after that can be named whatever you want, but has to correspond with your AJAX action parameter. This will become more clear once you see the custom JavaScript code. We have two actions, ‘wp_ajax_’ and ‘wp_ajax_nopriv’, one for the logged in user and the other for the end user.
Now for the custom JavaScript code to be included in the home page.
add_action( 'wp_head', 'my_plugin_js_header' ); function my_plugin_js_header() { ?> <script type="text/javascript"> //<![CDATA[ jQuery(document).ready(function($) { jQuery('#my_text_submit_id').click(function(){ jQuery.post('<?php echo admin_url( 'admin-ajax.php' ); ?>', { 'action': 'my_widget_action', 'user_text': jQuery('#my_text_id').val() } ); }); }); //]]> </script> <?php }
In the above using the usual jQuery $ will not work.
The most interesting part in the above is this
jQuery.post(”, { ‘action’: ‘my_widget_action’, ‘user_text’: jQuery(‘#my_text’).val() });
The name admin-ajax.php is misleading, but this is the url you have to use for all AJAX actions, irrespective of whether they are admin actions or end user facing ones. Also, the action should correspond to the part following ‘wp_ajax_’ and ‘wp_ajax_nopriv’, that we saw above.
Now when you enter a text in the input box and press submit, it should get persisted in the database.
Download the full code from github.
I copied and pasted your code exactly and recieved the following error
register_activation_hook( __FILE__, ‘my_plugin_install’ ); my_plugin_install() { } global $my_plugin_table; global $my_plugin_db_version; global $wpdb; $my_plugin_table = $wpdb->prefix . ‘my_plugin’; $my_plugin_version = ‘1.0’; register_activation_hook( __FILE__, ‘my_plugin_install’ ); function my_plugin_install() { global $wpdb; global $my_plugin_table; global $my_plugin_db_version; if ( $wpdb->get_var( “show tables like ‘$my_plugin_table'” ) != $my_plugin_table ) { $sql = “CREATE TABLE $my_plugin_table (“. “id int NOT NULL AUTO_INCREMENT, “. “user_text text NOT NULL, “. “UNIQUE KEY id (id) “. “)”; require_once( ABSPATH . ‘wp-admin/includes/upgrade.php’ ); dbDelta( $sql ); add_option( “my_plugin_db_version”, $my_plugin_db_version ); } }
Where is the error?
This is working for me.
Thanks for nice tutorial.
You are welcome.
I activated the plugin and got the same error code which showed up above the plugin page header. Is there closing tags that need to be added to php files that aren’t shown in the steps above?
Can you please let me know what error you got?
Thank you so much for your well-written tutorial. I really like that you provided links to explain some reasons why things have to be done a certain way. I also struggled with the AJAX actions. While I was able to get my code working, you showed me a better way to structure my code so that it is more readable and organized. The other thing that I have struggled with is the admin section. Can you expand the tutorial to include adding admin options? The few tutorials that I have read show a lot of code but don’t explain why things are best done a certain way. Keep up the good work!
You are welcome :).
Could there be a small typo ?
One the one hand : $my_plugin_version = ‘1.0’;
One the other hand: global $my_plugin_db_version;
Or maybe it’s to make sure people actually read instead of just copy/paste 🙂
Thanks anyway for all the explanation !
Thanks for pointing out the mistake. Fixed it.
Hello,
“For AJAX, we will be using jQuery JavaScript framework. We do not have to do anything to include jQuery, as it is already enabled in WordPress.”
jQuery is not enabled by default so I get a javascript ‘jQuery is not defined’ error
Anyway, thanks for the tut
Hmm…Weird…I never explicitly included jQuery.
Hi abhirama – I am using your code from https://bitbucket.org/abhirama/wordpress-example-plugin/src/dfc74f0d282f/my-plugin.php, but when I hit Submit, nothing happens.
I think my issue may be the same as Tompouss’s, where jQuery is not enabled by default. When I look at my page source, there are no references to any .js files.
You mentioned that you “never explicitly included jQuery”. When you look at your own page source, do you have a reference to a jQuery .js file? If so, what does that line look like?
If you don’t have a reference to a jQuery .js file in your page source, how doe jQuery get used? Could you point me to the documentation where you saw that you do not have to include jQuery, that it is enabled in WP by default?
Thanks in advance for your help.
Sorry Alex. I do not have a working wordpress set up in my lap top now. But, I am sure that I did not explicitly add jQuery to my code.
Abhirama, thanks for writing this tutorial. I noticed that you created a class object for the widget, but not for the main function. Is there a reason for that? As far as I can tell by doing numerous hours of research — and I am still very much a programming newbie — object-oriented plugins are being presented as both more stable (less chance of namespace collision) and more flexible.
What’s your take?
Very useful. Thank you for sharing with us.
this is very useful , thanks for sharing this
great tute. thanks
Thanks :).
Hello!
I think this was the kind of code I was wanting so as to create a unique haiku widget.
I wanted to allow my users to write their own haiku and the plugin would store it in the database.
I then would want a random haiku from the database that a user submitted to be displayed, within the widget, at the top of the submission form. It would look like:
Coding with wordpress / You pull your hair out a lot / But it feels real good John from Spokane
Write your own Haiku below and submit to the database! (Include your name to be given credit)
Assuming this was the idea in the first place, being able to later use the database for displaying purposes, could someone suggest a way I could achieve this?
Thanks!
Finally, something coherent, and with a code sample, too! Big thanks for writing this out.
Great post. It was very helpful!
Great tutorial! Thanks very much. I needed to add this to make WP load jquery:
add_action(‘init’, ‘my_init’);
function my_init() {
if (!is_admin()) {
wp_enqueue_script(‘jquery’);
}
}
Great tutorial! Thanks very much!
Have you ever thought about publishing an e-book or guest authoring on other
blogs? I have a blog centered on the same subjects
you discuss and would really like to have you share some stories/information.
I know my subscribers would value your work. If you are even remotely interested,
feel free to shoot me an e-mail.
Thanks for this generous offer, but right now I am too tied up at work to do this.
nice Job …. Thanks for this post ….
Good way of telling, and nice article to obtain data concerning my presentation focus, which i am going to
present in academy.
May I simply say what a relief to uncover a person that actually understands what they’re discussing on the net. You certainly understand how to bring a problem to light and make it important. A lot more people really need to look at this and understand this side of the story. I can’t believe you aren’t more popular since you certainly possess the gift.
Hello very cool web site!! Man .. Excellent ..
Amazing .. I’ll bookmark your blog and take the feeds also? I’m happy to search out numerous useful information here in the put up, we need develop
more techniques in this regard, thanks for sharing.
. . . . .
This is my first time pay a quick visit at here
and i am actually pleassant to read all at one place.
I’m not sure where you are getting your information, but great topic.
I needs to spend some time learning more or understanding more.
Thanks for excellent information I was looking for this info
for my mission.
This is very knowledgeable and informative piece of writing.
http://www.businesssitedesigner.com/
Woah! I’m really loving the template/theme of this website.
It’s simple, yet effective. A lot of times it’s very hard to get that “perfect balance” between usability and visual appearance.
I must say that you’ve done a very good job with this. Additionally,
the blog loads super fast for me on Chrome.
Exceptional Blog!
Fantastic beat ! I would like to apprentice while you amend
your site, how could i subscribe for a blog web site? The account aided me a applicable deal.
I had been a little bit familiar of this your broadcast provided
vibrant transparent concept
great issues altogether, you simply received a emblem new reader.
What might you suggest about your put up that you made a few days in the past?
Any sure?
Excellent site you’ve got here.. It’s difficult to find high quality writing like yours these days.
I honestly appreciate people like you! Take care!!
Fastidious replies in return of this matter with genuine arguments and telling all
on the topic of that.
This design is spectacular! You obviously know how to keep a reader entertained.
Between your wit and your videos, I was almost moved to start my own blog (well, almost…HaHa!) Great job.
I really loved what you had to say, and more than that, how you
presented it. Too cool!
I do believe all of the ideas you’ve introduced for your post.
They are very convincing and will certainly work. Nonetheless,
the posts are too brief for novices. May you
please extend them a little from next time? Thanks for the post.
Great post. I used to be checking continuously this blog and I am inspired!
Very helpful information specially the final phase 🙂 I maintain such information a lot.
I used to be seeking this certain info for a long time. Thanks and
good luck.
Thanks for some other informative website. Where else may I get that type of info
written in such an ideal method? I have a undertaking
that I’m just now running on, and I’ve been at the glance out for such information.
Hey there! I know this is kinda off topic but I was wondering which blog platform are you
using for this website? I’m getting sick and tired of WordPress because I’ve had problems with hackers and I’m looking at options for another platform.
I would be fantastic if you could point me in the direction of a good platform.
Hi, yes this article is in fact pleasant and I have learned lot of things from it concerning blogging.
thanks.
Amazing blog! Is your theme custom made or did you download it from somewhere?
A design like yours with a few simple adjustements would really make my
blog jump out. Please let me know where you got your design. Many thanks
Amazing! Its genuinely awesome paragraph, I have got much clear idea about from this
article.
Hello it’s me, I am also visiting this web page regularly, this website is really nice and the users are truly sharing
good thoughts.
Hello! This is my first comment here so I just wanted to give a quick shout out and
tell you I genuinely enjoy reading through your blog posts.
Can you recommend any other blogs/websites/forums that cover the same
topics? Thanks!
I’m really enjoying the design and layout of your blog. It’s a very easy on the eyes
which makes it much more enjoyable for me to come here and visit more often. Did you hire out a designer to create your theme?
Excellent work!
Every weekend i used to visit this site, for the reason that i want enjoyment, since this
this site conations actually fastidious funny information too.
I don’t know if it’s just me or if everybody else encountering issues
with your site. It appears as though some of the written text
on your content are running off the screen. Can somebody else please comment and let me know if this is happening to them as well?
This may be a issue with my internet browser because I’ve had this happen previously.
Many thanks
Pretty section of content. I just stumbled upon your web site and in accession capital to assert that I acquire actually enjoyed account your blog posts.
Any way I’ll be subscribing to your feeds and even I achievement
you access consistently rapidly.
It’s very simple to find out any matter on web as compared to textbooks, as I found this article at this web page.
What a data of un-ambiguity and preserveness of valuable familiarity
regarding unpredicted emotions.
Very great post. I just stumbled upon your blog and wished to mention that I
have truly loved surfing around your weblog posts.
In any case I’ll be subscribing in your feed and I am hoping you write again very soon!
Hi, I do think your website could possibly be having browser compatibility
issues. When I look at your site in Safari,
it looks fine but when opening in I.E., it’s got some overlapping issues.
I simply wanted to provide you with a quick heads up! Apart from that,
fantastic website!