Create your own Custom WordPress Plugin

A plugin adds functionality without changing files in the WordPress core. Although there is plenty of information on the basics of creating a custom WordPress plugin, I want to consolidate some of the most useful information below. Furthermore, the final plugin project files may be downloaded below.

File Structure and Organization

At minimum, a WordPress plugin is a single file; however, most instances will require multiple files and folders. Organizing your plugin from the start will help with maintaining or expanding your plugin in the future. 


For instance, the folder structure to the left includes the main file, plugin-name.php, along with an uninstall.php file that is executed when a user removes a plugin. The admin folder separates admin functions from the public functions, so the admin code can be loaded for users with the appropriate role. The layout of your folder structure should be clear, however, you may require fewer folders depending on the complexity of your plugin.

Extra Reading

Check out these resources for additional information on creating a custom WordPress plugin.
Most importantly, the Plugin Handbook contains all sorts of information on the topic.
Learn about Hooks, Filters, and Actions with the WordPress Plugin API.
For a brief overview, read how to create a custom plugin from the WordPress Codex.

WordPress Plugin Header Requirements

The header of your main file should, at the very least, contain the Plugin Name. However, I recommend filling out the description and version lines as well. The commented section should appear at the top of your main plugin file.

  • Plugin Name: (required) The name of your plugin.
  • Plugin URI: The website for your plugin.
  • Description: A description of the plugin (less than 140 characters).
  • Version: The current plugin version.
  • Author: The plugin author or authors name(s).
  • Author URI: The author's website.
  • License: The plugin's license.
  • License URI: The license URL.
ל,๨>[sZ娭z(>[u"m{Wo"ڲ',7r*'"qj+t޲zgW*'Mzuaz(.+Q!l+{Woˉǧ/bqyDHi'Xz{)m!iS{Cf h虨=aVzr^

A Quick Example of a Custom WordPress Plugin

To start, let's create a quick plugin that retrieves the most recent post and displays it using a WordPress shortcode.

What is a Shortcode?

A shortcode is a small code snippet that can be used on a post or a page. In addition, shortcodes can have attributes to further enhance their functionality.

Shortcode Tips

  • Shortcode names are all lowercase and may include numbers and underscores. Do not use dashes.
  • Shortcodes should not produce content and should use return to output to the browser. Using echo may produce unexpected results.
  • Shortcodes will not attempt automatically wrap any HTML in <p> tags. Include the tags if you want them to be included in the output.
  • Finally, shortcode attributes may use single or double quotes, or you may omit them if there are no spaces.
,)ޞzל,๨>[sZ䦺b&Z>n)ϖ"DHioܺh +v޲e{W)Cz+bt^azj,z{iZbZ^wfz"}t ҚhDHi &(>z{]+ZqǬ'yyHbκ!\׭pYkzzyǧ,bzq-qmjweym&֬('uں[oj[mh(u歶ƫhիmyǧ,b+Z%hj,j{ml),

Line 1-9

Initially, the first set of comments is the required header for all WordPress plugins. While only the plugin name is required, the other data will be displayed in the dashboard on the plugins page.

Line 12

The constant ABSPATH is defined by WordPress. Checking if this variable exists can tell us whether the file is being accessed directly, and as a result, will terminate the script. Unless the PHP file is handling AJAX requests for instance, direct access should be terminated.

Line 18-20

The function shortcode_atts() merges the values sent to the function definition, $atts, with the values in the array. If the function parameter does not define a value for the attribute, a default value set in the array is assigned.

Line 24-29

Sets the arguments that determine which posts are returned from the get_posts() WordPress function. For a full list of get_posts() arguments, visit parse_query().

Line 32-47

Loop through any posts found and append the HTML to the $html variable. We do not echo the HTML directly, but return it at the end of the shortcode.

Line 34 and 48

By using setup_postdata() we alter the global $post variable which contains the current post information. This allows us to use the get_the_ID(), get_the_title(), get_the_permalink(), and get_the_date() functions. On line 48 we reset the $post variable back to the original values.

Line 49

Loop through any posts found and append the HTML to the $html variable. We do not echo the HTML directly, but return it at the end of the shortcode.

Line 54

Finally, we add the hook and identify the shortcode name and the function that will be called. In our example, we use the shortcode [smugbits_recent_posts] which calls recent_posts_func().

Shortcode Results

[smugbits_recent_posts limit='1']
[smugbits_recent_posts limit='1']

Custom WordPress Plugin Conclusion

In conclusion, WordPress allows us to expand functionality and tailor web content to fit our needs by creating your own custom WordPress plugin. In the next article, we will take a look at wp_enqueue_script() and wp_enqueue_style(). If you have any comments or suggestions, leave a comment below!