Views: 46
To create a WordPress plugin, you need to create a new folder inside the wp-content/plugins directory, add a main PHP file with a valid plugin header comment, and write your custom functionality inside that file. In this guide, you will build the Versana Companion plugin from scratch using this blog post step by step from scratch.
Introduction
Welcome to Episode 02! In Episode 01, we discussed why we’re building a companion plugin for Versana theme. Now it’s time to actually build it!
In this episode, you’ll learn how to create a WordPress plugin from absolute scratch. No complex programming patterns, no confusing object-oriented code – just simple, straightforward PHP that anyone can understand and follow.
By the end of this tutorial, you’ll have a working WordPress plugin that displays in your WordPress admin and can be activated/deactivated. This is the foundation we’ll build upon in future episodes.
What We’ll Cover
- Understanding WordPress plugin basics
- Creating your first plugin file
- Adding a plugin header
- Making the plugin appear in WordPress
- Adding activation and deactivation hooks
- Creating a simple admin notice
- Testing your plugin
- Understanding plugin security basics
Prerequisites
- WordPress 6.0+ installed locally or on a server
- Access to your WordPress files (via FTP or File Manager)
- Text editor (Notepad++, VS Code, or Sublime Text)
- Basic understanding of HTML and PHP (very basic)
- Completed Episodes 1-29 (helpful but not required)
Part 1: Understanding WordPress Plugins
What is a WordPress Plugin?
A WordPress plugin is simply a folder containing PHP files that add new features to WordPress. That’s it!
Real-World Analogy:
- WordPress = Your smartphone
- Plugin = An app you install
- Just like apps add features to your phone, plugins add features to WordPress
How WordPress Recognizes Plugins
WordPress looks in one specific folder for plugins:
wp-content/
└── plugins/
├── akismet/ ← Plugin folder
├── hello-dolly/ ← Plugin folder
└── your-plugin/ ← Your plugin folder (we'll create this)
Inside each plugin folder, WordPress looks for a main PHP file with a special “header” that tells WordPress:
- Plugin name
- What it does
- Who made it
- Version number
That’s all you need to create a basic WordPress plugin!
Part 2: Creating Your Plugin Folder
Step 1: Navigate to the Plugins Directory
Via File Manager (cPanel/hosting):
1. Log into your hosting control panel
2. Open File Manager
3. Navigate to: public_html/wp-content/plugins/
Via FTP (FileZilla):
1. Connect to your server
2. Navigate to: /wp-content/plugins/
Via Local Computer (Local WordPress):
1. Open your WordPress installation folder
2. Navigate to: wp-content/plugins/
Step 2: Create New Folder
Create a new folder called versana-companion
Important Naming Rules:
- All lowercase letters ✅
- Use hyphens (not spaces or underscores) ✅
- No special characters ✅
✅ GOOD: versana-companion
❌ BAD: Versana Companion (spaces)
❌ BAD: versana_companion (underscores)
❌ BAD: VersanaCompanion (capital letters)
Your folder structure should now look like:
wp-content/
└── plugins/
├── akismet/
└── versana-companion/ ← You created this!
Part 3: Creating Your First Plugin File
Step 3: Create the Main PHP File
Inside the versana-companion folder, create a new file called versana-companion.php
Creating the file:
- In File Manager: Click “New File” button
- In FTP: Create locally, then upload
- In text editor: File → New → Save as
versana-companion.php
Important: The file name should match the folder name (with .php extension).
versana-companion/ ← Folder name
└── versana-companion.php ← File name (matches folder)
Step 4: Add Opening PHP Tag
Open versana-companion.php in your text editor and add:
<?php
That’s it for now! Every PHP file must start with <?php
Important Notes:
- No closing
?>tag needed at the end - No spaces or text before
<?php - Save the file as UTF-8 encoding (most editors do this automatically)
Part 4: Adding the Plugin Header
Step 5: Add Plugin Information
Now add the plugin header. This tells WordPress about your plugin.
Complete code for versana-companion.php:
<?php
/**
* Plugin Name: Versana Companion
* Description: Adds demo import and advanced features to Versana theme
* Version: 1.0.0
* Author: Your Name
* Text Domain: versana-companion
*/
Let’s understand each line:
/**
* Plugin Name: Versana Companion
- This is what shows in the WordPress Plugins page
- Required: YES
- Users see this name
* Description: Adds demo import and advanced features to Versana theme
- Short explanation of what your plugin does
- Required: NO (but recommended)
- Shows under plugin name in WordPress
* Version: 1.0.0
- Current version of your plugin
- Required: YES
- Format: MAJOR.MINOR.PATCH (1.0.0, 1.2.3, etc.)
* Author: Your Name
- Who created the plugin
- Required: NO (but recommended)
- Replace “Your Name” with your actual name or company
* Text Domain: versana-companion
- Used for translations
- Required: YES (for translations)
- Must match your folder name exactly
Save the file!
Part 5: See Your Plugin in WordPress
Step 6: Check WordPress Admin
Now let’s see if WordPress recognizes your plugin!
- Log into your WordPress admin dashboard
- Go to Plugins → Installed Plugins
- Look for “Versana Companion”
You should see:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Versana Companion
Adds demo import and advanced features to Versana theme
Version 1.0.0 | By Your Name
[Activate] [Delete]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Congratulations! You just created your first WordPress plugin! 🎉
But it doesn’t do anything yet. Let’s fix that.
Part 6: Adding Your First Function
Step 7: Create a Simple Welcome Message
Let’s make the plugin do something visible when activated.
Add this code AFTER your plugin header:
<?php
/**
* Plugin Name: Versana Companion
* Description: Adds demo import and advanced features to Versana theme
* Version: 1.0.0
* Author: Your Name
* Text Domain: versana-companion
*/
// Prevent direct access to this file
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Display welcome message in admin
*/
function versana_companion_admin_notice() {
?>
<div class="notice notice-success is-dismissible">
<p><strong>Versana Companion is active!</strong> The plugin is now working.</p>
</div>
<?php
}
add_action( 'admin_notices', 'versana_companion_admin_notice' );
Understanding the code:
// Prevent direct access to this file
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
- Security check – prevents hackers from accessing this file directly
- ABSPATH is a WordPress constant that’s always defined
- If someone tries to access this file directly (not through WordPress), it stops
/**
* Display welcome message in admin
*/
function versana_companion_admin_notice() {
- This creates a function (a reusable block of code)
- Name it clearly so you know what it does
?>
<div class="notice notice-success is-dismissible">
<p><strong>Versana Companion is active!</strong> The plugin is now working.</p>
</div>
<?php
- This is the HTML that creates the green success box
notice= WordPress notice stylingnotice-success= green coloris-dismissible= adds X button to close
add_action( 'admin_notices', 'versana_companion_admin_notice' );
- This tells WordPress: “When showing admin notices, run my function”
admin_notices= WordPress hook (event)versana_companion_admin_notice= our function name
Save the file!
Step 8: Activate and Test
- Go to Plugins → Installed Plugins
- Click Activate under Versana Companion
- You should see a green box at the top:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✓ Versana Companion is active! The plugin is now working. ✕
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
It works! Your plugin is now doing something!
Part 7: Understanding Activation and Deactivation
What Are Activation Hooks?
When users activate/deactivate plugins, WordPress lets you run special code. This is useful for:
- Setting up initial options
- Creating database tables
- Cleaning up when deactivated
Step 9: Add Activation Hook
Add this code to your plugin file:
<?php
/**
* Plugin Name: Versana Companion
* Description: Adds demo import and advanced features to Versana theme
* Version: 1.0.0
* Author: Your Name
* Text Domain: versana-companion
*/
// Security check
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Runs when plugin is activated
*/
function versana_companion_activate() {
// Save the plugin version
add_option( 'versana_companion_version', '1.0.0' );
// Save activation date
add_option( 'versana_companion_activated', current_time( 'mysql' ) );
}
register_activation_hook( __FILE__, 'versana_companion_activate' );
/**
* Runs when plugin is deactivated
*/
function versana_companion_deactivate() {
// Clean up (optional)
// We'll leave options in database in case user reactivates
}
register_deactivation_hook( __FILE__, 'versana_companion_deactivate' );
/**
* Display admin notice
*/
function versana_companion_admin_notice() {
?>
<div class="notice notice-success is-dismissible">
<p><strong>Versana Companion is active!</strong> The plugin is now working.</p>
</div>
<?php
}
add_action( 'admin_notices', 'versana_companion_admin_notice' );
Understanding activation hooks:
function versana_companion_activate() {
add_option( 'versana_companion_version', '1.0.0' );
}
add_option()saves data to WordPress database- First parameter: option name (key)
- Second parameter: option value (what to save)
- This saves the version number when plugin activates
register_activation_hook( __FILE__, 'versana_companion_activate' );
- Tells WordPress: “When this plugin activates, run this function”
__FILE__= this current fileversana_companion_activate= function to run
Step 10: Test Activation
- Deactivate the plugin (click Deactivate)
- Activate it again (click Activate)
- Go to Settings → General (just to navigate somewhere)
- Your activation function ran in the background!
To verify it worked:
- The version was saved to database (you can’t see this yet, but it’s there)
- We’ll check this in a later episode when we add a settings page
Part 8: Adding Plugin Constants
What Are Constants?
Constants are like containers that hold values that never change. We use them to store:
- Plugin version
- File paths
- URLs
Step 11: Add Constants
Replace your entire file with this improved version:
<?php
/**
* Plugin Name: Versana Companion
* Description: Adds demo import and advanced features to Versana theme
* Version: 1.0.0
* Author: Your Name
* Text Domain: versana-companion
*/
// Security check
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Plugin constants
*/
define( 'VERSANA_COMPANION_VERSION', '1.0.0' );
define( 'VERSANA_COMPANION_PATH', plugin_dir_path( __FILE__ ) );
define( 'VERSANA_COMPANION_URL', plugin_dir_url( __FILE__ ) );
/**
* Activation hook
*/
function versana_companion_activate() {
add_option( 'versana_companion_version', VERSANA_COMPANION_VERSION );
add_option( 'versana_companion_activated', current_time( 'mysql' ) );
}
register_activation_hook( __FILE__, 'versana_companion_activate' );
/**
* Deactivation hook
*/
function versana_companion_deactivate() {
// Cleanup if needed
}
register_deactivation_hook( __FILE__, 'versana_companion_deactivate' );
/**
* Admin notice
*/
function versana_companion_admin_notice() {
?>
<div class="notice notice-success is-dismissible">
<p>
<strong>Versana Companion <?php echo VERSANA_COMPANION_VERSION; ?> is active!</strong>
The plugin is now working.
</p>
</div>
<?php
}
add_action( 'admin_notices', 'versana_companion_admin_notice' );
Understanding constants:
define( 'VERSANA_COMPANION_VERSION', '1.0.0' );
- Creates a constant named
VERSANA_COMPANION_VERSION - Value:
'1.0.0' - Can be used anywhere:
echo VERSANA_COMPANION_VERSION; - Never changes while plugin is running
define( 'VERSANA_COMPANION_PATH', plugin_dir_path( __FILE__ ) );
- Stores the full server path to plugin folder
- Example:
/var/www/html/wp-content/plugins/versana-companion/ - Use for including PHP files
define( 'VERSANA_COMPANION_URL', plugin_dir_url( __FILE__ ) );
- Stores the full URL to plugin folder
- Example:
https://yoursite.com/wp-content/plugins/versana-companion/ - Use for loading CSS, JS, images
Why use constants?
// ❌ BAD - Hardcoded
require_once '/var/www/html/wp-content/plugins/versana-companion/includes/file.php';
// Won't work on different servers
// ✅ GOOD - Using constant
require_once VERSANA_COMPANION_PATH . 'includes/file.php';
// Works on any server
Part 9: Creating Plugin File Structure
Step 12: Create Folders
Create this folder structure inside versana-companion/:
versana-companion/
├── versana-companion.php ← Already created
├── includes/ ← Create this folder
├── admin/ ← Create this folder
├── assets/ ← Create this folder
│ ├── css/ ← Create this folder
│ └── js/ ← Create this folder
└── languages/ ← Create this folder
How to create folders:
In File Manager:
- Navigate to
versana-companion/folder - Click “New Folder” button
- Name it (includes, admin, etc.)
- Repeat for each folder
In FTP:
- Right-click in
versana-companion/folder - Select “Create directory”
- Name it
- Repeat for each folder
What each folder is for:
includes/– PHP files with plugin functionsadmin/– Admin-specific codeassets/css/– Stylesheetsassets/js/– JavaScript fileslanguages/– Translation files
Part 10: Adding a README File
Step 13: Create readme.txt
Create a new file called readme.txt in the versana-companion/ folder.
Full readme.txt content:
=== Versana Companion ===
Contributors: yourname
Tags: demo import, starter templates, versana
Requires at least: 6.0
Tested up to: 6.5
Requires PHP: 7.4
Stable tag: 1.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Extends Versana theme with demo import and advanced features.
== Description ==
Versana Companion is a plugin designed specifically for the Versana WordPress theme. It adds:
* One-click demo import
* Starter site templates
* Additional block patterns
* Advanced theme features
This plugin requires the Versana theme to be installed and activated.
== Installation ==
1. Upload the plugin files to `/wp-content/plugins/versana-companion`
2. Activate the plugin through the 'Plugins' screen in WordPress
3. Make sure Versana theme is active
== Frequently Asked Questions ==
= Do I need the Versana theme? =
Yes, this plugin is designed to work only with Versana theme.
= Is this plugin free? =
Yes, completely free!
== Changelog ==
= 1.0.0 =
* Initial release
* Basic plugin structure
== Upgrade Notice ==
= 1.0.0 =
Initial release.
Why create readme.txt?
- Required if you want to submit plugin to WordPress.org
- Documents your plugin
- Helps users understand what it does
- Shows changelog of updates
Part 11: Complete Plugin Code
Your Complete versana-companion.php File
Here’s everything together in one clean file:
<?php
/**
* Plugin Name: Versana Companion
* Description: Adds demo import and advanced features to Versana theme
* Version: 1.0.0
* Author: Your Name
* Author URI: https://yourwebsite.com
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: versana-companion
* Domain Path: /languages
* Requires at least: 6.0
* Requires PHP: 7.4
*/
// If this file is called directly, abort
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Plugin constants
*/
define( 'VERSANA_COMPANION_VERSION', '1.0.0' );
define( 'VERSANA_COMPANION_PATH', plugin_dir_path( __FILE__ ) );
define( 'VERSANA_COMPANION_URL', plugin_dir_url( __FILE__ ) );
/**
* Plugin activation
* Runs once when plugin is activated
*/
function versana_companion_activate() {
// Save plugin version
add_option( 'versana_companion_version', VERSANA_COMPANION_VERSION );
// Save activation timestamp
add_option( 'versana_companion_activated', current_time( 'mysql' ) );
// Set default options
$default_options = array(
'demo_imported' => false,
'first_activation' => true,
);
add_option( 'versana_companion_options', $default_options );
}
register_activation_hook( __FILE__, 'versana_companion_activate' );
/**
* Plugin deactivation
* Runs once when plugin is deactivated
*/
function versana_companion_deactivate() {
// We keep options in database in case user reactivates
// If you want to delete everything, uncomment below:
// delete_option( 'versana_companion_version' );
// delete_option( 'versana_companion_activated' );
// delete_option( 'versana_companion_options' );
}
register_deactivation_hook( __FILE__, 'versana_companion_deactivate' );
/**
* Display admin notice when plugin is active
*/
function versana_companion_admin_notice() {
// Only show on admin pages
if ( ! is_admin() ) {
return;
}
// Get options to check if it's first activation
$options = get_option( 'versana_companion_options', array() );
// Show welcome notice on first activation
if ( isset( $options['first_activation'] ) && $options['first_activation'] ) {
?>
<div class="notice notice-success is-dismissible">
<p>
<strong>🎉 Versana Companion <?php echo esc_html( VERSANA_COMPANION_VERSION ); ?> Activated!</strong>
</p>
<p>
The plugin is now active and ready to use.
More features coming in future updates!
</p>
</div>
<?php
// Update option so notice doesn't show again
$options['first_activation'] = false;
update_option( 'versana_companion_options', $options );
}
}
add_action( 'admin_notices', 'versana_companion_admin_notice' );
/**
* Load plugin text domain for translations
*/
function versana_companion_load_textdomain() {
load_plugin_textdomain(
'versana-companion',
false,
dirname( plugin_basename( __FILE__ ) ) . '/languages'
);
}
add_action( 'plugins_loaded', 'versana_companion_load_textdomain' );
/**
* Add settings link on plugin page
*/
function versana_companion_settings_link( $links ) {
$settings_link = '<a href="admin.php?page=versana-companion">Settings</a>';
array_unshift( $links, $settings_link );
return $links;
}
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'versana_companion_settings_link' );
Part 12: Understanding What We Built
The Complete Structure
versana-companion/
├── versana-companion.php ← Main plugin file (170 lines)
├── readme.txt ← Plugin documentation
├── includes/ ← For future PHP files
├── admin/ ← For future admin files
├── assets/
│ ├── css/ ← For future stylesheets
│ └── js/ ← For future JavaScript
└── languages/ ← For future translations
What the Plugin Does Now
✅ Appears in WordPress Plugins page ✅ Can be activated/deactivated ✅ Shows welcome message on activation ✅ Saves version to database ✅ Saves activation date ✅ Stores default options ✅ Adds Settings link on plugins page ✅ Ready for translations ✅ Follows WordPress coding standards ✅ Has proper security checks
What We’ll Add in Future Episodes
Episode 3: Theme compatibility check Episode 4: Admin settings page Episode 5: Database tables for demos Episode 6: Demo import functionality Episode 7: Demo library UI Episode 8: First demo template …and more!
Part 13: Testing Your Plugin
Test Checklist
Go through each item:
1. Plugin Visibility
- [ ] Go to Plugins → Installed Plugins
- [ ] “Versana Companion” appears in list
- [ ] Description shows correctly
- [ ] Version number shows: 1.0.0
2. Activation
- [ ] Click “Activate”
- [ ] No errors appear
- [ ] Welcome notice shows (green box)
- [ ] “Settings” link appears under plugin name
3. Deactivation
- [ ] Click “Deactivate”
- [ ] No errors appear
- [ ] Plugin becomes inactive
4. Reactivation
- [ ] Activate again
- [ ] Welcome notice doesn’t show (first_activation = false)
- [ ] Everything works
5. Database Check (optional, for advanced users)
- [ ] Go to phpMyAdmin
- [ ] Select your WordPress database
- [ ] Open
wp_optionstable - [ ] Search for:
versana_companion_version - [ ] Should see version: 1.0.0
Part 14: Common Mistakes and How to Fix Them
Mistake #1: Plugin Doesn’t Appear
Problem: You created the plugin but it doesn’t show in WordPress.
Solution:
✓ Check file name: versana-companion.php
✓ Check folder name: versana-companion
✓ Check if file starts with: <?php
✓ Check if plugin header exists:
/**
* Plugin Name: Versana Companion
*/
✓ Refresh plugins page in WordPress
Mistake #2: White Screen After Activation
Problem: Site shows blank white page after activating plugin.
Solution:
1. Via FTP, rename plugin folder to: versana-companion-disabled
2. Site should work again
3. Check for syntax errors:
- Missing semicolons ;
- Unclosed brackets { }
- Missing quotes " or '
4. Fix errors
5. Rename folder back to: versana-companion
6. Try activating again
Mistake #3: PHP Errors Showing
Problem: Error messages appear when activating.
Common errors and fixes:
// Error: "Cannot redeclare function"
// Problem: Function name already exists
// Fix: Add unique prefix to function names
// ❌ BAD
function activate() { }
// ✅ GOOD
function versana_companion_activate() { }
// Error: "Undefined constant"
// Problem: Typo in constant name
// Fix: Check spelling
// ❌ BAD
echo VERSANA_VERSION; // Missing _COMPANION
// ✅ GOOD
echo VERSANA_COMPANION_VERSION;
Mistake #4: Welcome Notice Shows Every Time
Problem: Green success notice appears on every page load.
Solution:
// Check this part of code exists:
$options['first_activation'] = false;
update_option( 'versana_companion_options', $options );
// This should run after notice displays
// It sets first_activation to false so notice only shows once
Mistake #5: Settings Link Doesn’t Work
Problem: Clicking “Settings” shows “Page not found”
Expected: This is normal! We haven’t created the settings page yet. We’ll do that in Episode 32.
For now: The link won’t work, but it’s there ready for when we add the settings page.
Part 15: What Makes This Approach Beginner-Friendly
Why We Used Simple Functions (Not OOP)
Object-Oriented (Complex):
class Versana_Companion {
private static $instance = null;
public static function instance() {
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
// Complex stuff
}
}
Procedural (Simple):
function versana_companion_activate() {
// Simple stuff
}
register_activation_hook( __FILE__, 'versana_companion_activate' );
Procedural is easier because:
- ✅ Reads top to bottom
- ✅ No complex concepts needed
- ✅ Easy to understand
- ✅ Beginner-friendly
- ✅ Still professional
- ✅ WordPress core uses this too
No External Dependencies
We didn’t use:
- ❌ Composer
- ❌ npm/webpack
- ❌ Third-party libraries
- ❌ Build tools
Just plain PHP files you can edit with any text editor!
Conclusion
Congratulations! You’ve successfully learned how to create a WordPress plugin from scratch. You now have a working foundation that we’ll build upon in coming episodes.
What We Accomplished
✅ Created plugin folder and main file ✅ Added proper plugin header ✅ Implemented activation/deactivation hooks ✅ Created useful constants ✅ Added admin notice system ✅ Built proper file structure ✅ Added readme documentation ✅ Tested everything works ✅ Used simple, beginner-friendly code
Your Complete Plugin Structure
versana-companion/
├── versana-companion.php ✅ 170 lines of clean code
├── readme.txt ✅ Complete documentation
├── includes/ ✅ Ready for future features
├── admin/ ✅ Ready for admin pages
├── assets/
│ ├── css/ ✅ Ready for styles
│ └── js/ ✅ Ready for scripts
└── languages/ ✅ Ready for translations
Key Takeaways
When learning how to create a WordPress plugin:
- Start Simple – Don’t overcomplicate
- Use Clear Names – versana_companion_function_name
- Add Security – Always check ABSPATH
- Follow WordPress Standards – Use WordPress functions
- Test Frequently – Activate/deactivate often
- Document Everything – Comments and readme.txt
- Build Incrementally – Add features one at a time
Next Steps
In Episode 3, we’ll add:
- Theme compatibility checking
- Display notice if Versana theme not active
- Prevent plugin features from loading without correct theme
In Episode 4, we’ll create:
- Admin settings page
- Options to configure plugin
- Settings API integration
In Episode 5, we’ll build:
- Database tables for demos
- Demo library structure
- Data storage system
Final Testing Checklist
Before moving to Episode 3:
- [ ] Plugin appears in Plugins page
- [ ] Activation works without errors
- [ ] Welcome notice shows once
- [ ] Deactivation works
- [ ] Reactivation works
- [ ] Settings link appears (even if it doesn’t work yet)
- [ ] No PHP errors in error log
- [ ] File structure is complete
Frequently Asked Questions
Q: Do I need to know OOP (Object-Oriented Programming) to create a WordPress plugin? A: No! This tutorial uses simple functions that anyone can understand. OOP is optional and not required.
Q: Why did we use functions instead of classes? A: Functions are simpler and easier for beginners to understand. The code still works great and is easier to maintain when you’re learning.
Q: Can I change the plugin name later? A: Yes, but you’ll need to update it in multiple places (plugin header, folder name, file name, text domain). Better to choose the right name from the start.
Q: What if I want to add more features? A: Perfect! That’s what we’ll do in upcoming episodes. This is just the foundation.
Q: Is this approach professional enough for real plugins? A: Absolutely! Many successful WordPress plugins use this functional approach. It’s clean, simple, and maintainable.
Q: Do I need to understand everything to continue? A: No! It’s okay if some parts are unclear. We’ll reinforce concepts in future episodes as we use them.
Q: Can I skip the readme.txt file? A: For development, yes. But if you plan to publish your plugin on WordPress.org, readme.txt is required.
Q: Why save options to the database on activation? A: So the plugin remembers settings even after deactivation. When users reactivate, their settings are still there.
Troubleshooting Guide
Problem: Can’t see plugin in WordPress
Steps to debug:
1. Check file location:
Should be: wp-content/plugins/versana-companion/versana-companion.php
2. Check plugin header:
Must have: Plugin Name: at minimum
3. Check PHP opening tag:
First line must be: <?php
4. Check for syntax errors:
- Missing semicolons
- Unclosed brackets
- Look at line numbers in errors
5. Enable debugging:
In wp-config.php add:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
6. Check debug.log file:
Location: wp-content/debug.log
Problem: Plugin activates but nothing happens
This is expected at this stage! The plugin:
- ✅ Should show welcome notice once
- ✅ Should add Settings link (won’t work yet)
- ✅ Should save options to database (invisible)
We’ll add visible features in next episodes!
Problem: Errors when trying to access plugin files
Solution:
Check file permissions:
- Folders: 755
- Files: 644
In File Manager or FTP:
- Right-click folder/file
- Select "Permissions" or "File Permissions"
- Set to 755 (folders) or 644 (files)
Congratulations on completing Episode 2! You now know the fundamentals of how to create a WordPress plugin. In the next episode, we’ll make it smarter by adding theme compatibility checking.
Series: WordPress Block Theme Development – Building Versana Companion
Episode: 2 of ongoing series (Companion Plugin Development Begins)

Leave a Reply