A Complete Guide to Building a Proper WordPress Plugin from Scratch
Home / Blog / A Complete Guide to Building a Proper WordPress Plugin from Scratch
A Complete Guide to Building a Proper WordPress Plugin from Scratch
Blog | June 17, 2025

1. Understand what a WordPress Plugin is?

In WordPress, plugins are like “small applications” attached to the system to add or change functionality. Instead of editing the source code (core) directly, plugins allow you to develop independently and easily maintain. This is important because every time WordPress is updated, the code you edit manually will be overwritten. **Plugins** are packages of code installed in WordPress to add features. WordPress provides a system of hooks (actions and filters) that allow you to “hook” into the core’s processing parts to extend without editing the original code.

2. Standard folder structure of a plugin

```plaintext
my-awesome-plugin/
├── my-awesome-plugin.php
├── readme.txt
├── includes/
│ └── class-main.php
├── assets/
│ ├── js/
│ └── css/
├── languages/
│ └── my-awesome-plugin.pot
```

Explanation:

`my-awesome-plugin.php`: The main file where WordPress boots the plugin.
`includes/`: Contains classes, functions, and main logic.
`assets/`: Contains JS, CSS.
`languages/`: Used for multilingual translation.

3. Create the main plugin file

The main file is where WordPress starts reading the plugin. It needs to have a comment at the top so it can be displayed in the admin screen. It’s also where you load the initial classes and hooks.

```php
<?php
/**
* Plugin Name: My Awesome Plugin
* Plugin URI: https://example.com/my-awesome-plugin
* Description: A great plugin that extends WordPress functionality.
* Version: 1.0.0
* Author: Your Name
* Author URI: https://yourwebsite.com
* License: GPL2
* Text Domain: my-awesome-plugin
*/

defined('ABSPATH') || exit;

// Autoload or require necessary files
require_once plugin_dir_path(__FILE__) . 'includes/class-main.php';

function map_init_plugin() {
$plugin = new MAP_Main();
$plugin->run();
}
add_action('plugins_loaded', 'map_init_plugin');
```

4. Use Classes to Structure Your Code

Using OOP (Object-Oriented Programming) makes it easier to scale your plugin, especially as it grows. Split admin logic, frontend logic, AJAX handlers, etc. into dedicated classes for better separation of concerns.

Create the main class in the file `includes/class-main.php`:

```php
<?php

class MAP_Main {

public function __construct() {
// initialization
}

public function run() {
add_action('init', [$this, 'load_textdomain']);
add_action('admin_menu', [$this, 'add_admin_menu']);
}

public function load_textdomain() {
load_plugin_textdomain('my-awesome-plugin', false, dirname(plugin_basename(__FILE__)) . '/../languages');
}

public function add_admin_menu() {
add_menu_page(
__('My Plugin', 'my-awesome-plugin'),
__('My Plugin', 'my-awesome-plugin'),
'manage_options',
'my-awesome-plugin',
[$this, 'render_admin_page'],
'dashicons-admin-plugins'
);
}

public function render_admin_page() {
echo '

' . esc_html__('Welcome to Plugin!', 'my-awesome-plugin') . '
';
}
}
```

5. Create API Endpoint:

API Endpoint helps your plugin communicate with frontend applications (JS, mobile apps...).

1. Rest API:

WordPress REST API allows your plugin to expose data or perform actions via HTTP requests. This is essential when building JS-heavy interfaces or mobile integrations.

Example: Create endpoint `/wp-json/my-plugin/v1/hello`

```php
add_action('rest_api_init', function () {
register_rest_route('my-plugin/v1', '/hello', [
'methods' => 'GET',
'callback' => function () {
return ['message' => 'Hello from plugin!'];
},
'permission_callback' => '__return_true'
]);
});
```

2. Handle AJAX Requests:

AJAX allows your plugin to perform background server-side tasks without refreshing the page. WordPress has built-in support for AJAX for both logged-in and guest users.

### a. AJAX for logged in users:

```php
add_action('wp_ajax_my_plugin_action', 'my_plugin_ajax_callback');

function my_plugin_ajax_callback() {
wp_send_json_success(['message' => 'Xử lý thành công']);
}
```

### b. AJAX for both guest and admin:

```php
add_action('wp_ajax_nopriv_my_plugin_action', 'my_plugin_ajax_callback');
```

---

### c. Frontend js

```js
jQuery.post(ajaxurl, {
action: 'my_plugin_action'
}, function(response) {
console.log(response.data.message);
});
```

6. Create Shortcodes

Shortcodes allow non-technical users to insert dynamic content into posts or pages using simple tags like [your_shortcode]. This is ideal for reusable UI blocks.

```php
add_shortcode('my_plugin_hello', function ($atts) {
return '

Simple html from shortcode!
';
});

```

When used in an article:

```plaintext
[my_plugin_hello]

7. Build a Frontend Template

Instead of echoing HTML inside class methods or shortcodes, it's best practice to separate presentation logic into template files. This makes the UI layer customizable and easier to maintain.

Place the template file in the `templates/hello.php` folder, for example:

**templates/hello.php**

```php

```

Call template file in plugin:

```php
function my_plugin_render_template($template_name, $args = []) {
extract($args);
include plugin_dir_path(__FILE__) . '../templates/' . $template_name . '.php';
}

// Call where to display
my_plugin_render_template('hello', [
'title' => 'Title Plugin',
'content' => 'Sample content'
]);
```

8. Testing and Packaging

  • Before releasing your plugin, run it through code quality tools like the Plugin Check or WP-CLI commands to ensure it meets security and code quality standards.
  • Compress the plugin into `.zip` for test installation.

## 💡 Some notes for a "standard" plugin

✅ Use hooks instead of overriding core code
✅ Write code that follows WordPress Coding Standards
✅ Optimize security: use `nonce`, check permissions `current_user_can()`, `sanitize_*()` and `esc_*()`
✅ Compatible with Multisite and popular themes/plugins
✅ No PHP/JS errors when enabling `WP_DEBUG`

Final Thoughts

Congrats! You've now walked through the full workflow of building a proper WordPress plugin—from structure and setup to REST API, AJAX, shortcodes, and frontend templating. With this foundation, you can confidently build professional-grade plugins that are robust, user-friendly, and maintainable.