Crear un plugin desde cero es una de las mejores formas de entender cómo funciona WordPress internamente y demostrar tu estilo de desarrollo. Pero hacerlo bien —con PHP moderno, namespaces, POO y seguridad— es lo que realmente marca la diferencia entre un plugin amateur y uno profesional.
En esta guía te enseño paso a paso cómo crear un plugin limpio, modular y seguro, siguiendo las buenas prácticas que utilizo en mis propios proyectos.
🧩 1. Estructura básica del plugin
Primero, crea una carpeta dentro de wp-content > plugins llamada por ejemplo mi-plugin, y dentro de ella estos archivos:
mi-plugin/
│
├── mi-plugin.php
├── includes/
│ ├── class-activator.php
│ ├── class-deactivator.php
│ └── class-main.php
└── assets/
├── js/
└── css/
La estructura modular ayuda a mantener el código limpio y escalable. Evita poner toda la lógica en un único archivo.
⚙️ 2. Archivo principal del plugin
Este es el punto de entrada del plugin. Define el encabezado y carga las clases.
<?php
/**
* Plugin Name: Mi Plugin
* Description: Ejemplo de plugin con buenas prácticas, namespaces y OOP.
* Version: 1.0.0
* Author: Tu Nombre
* Text Domain: mi-plugin
*/
if (!defined('ABSPATH')) {
exit; // Evita acceso directo
}
// Autocarga manual (o con composer si lo prefieres)
require_once plugin_dir_path(__FILE__) . 'includes/class-main.php';
// Inicia el plugin
add_action('plugins_loaded', function () {
$plugin = new \MiPlugin\Main();
$plugin->init();
});
Este archivo debe ser lo más ligero posible. Solo carga lo necesario e inicia el flujo principal.
🏗️ 3. Uso de Namespaces y OOP (Programación Orientada a Objetos)
Para evitar colisiones de funciones entre plugins, usa namespaces. Esto asegura que tu código no interfiera con otros.
En el archivo includes > class-main.php:
<?php
namespace MiPlugin;
if (!defined('ABSPATH')) {
exit;
}
class Main {
public function init() {
add_action('admin_menu', [$this, 'register_admin_page']);
add_action('wp_enqueue_scripts', [$this, 'enqueue_assets']);
}
public function register_admin_page() {
add_menu_page(
'Mi Plugin',
'Mi Plugin',
'manage_options',
'mi-plugin',
[$this, 'render_admin_page'],
'dashicons-admin-generic'
);
}
public function render_admin_page() {
echo '<div class="wrap"><h1>Bienvenido a Mi Plugin</h1></div>';
}
public function enqueue_assets() {
wp_enqueue_style('mi-plugin-css', plugins_url('../assets/css/style.css', __FILE__), [], '1.0.0');
wp_enqueue_script('mi-plugin-js', plugins_url('../assets/js/script.js', __FILE__), ['jquery'], '1.0.0', true);
}
}
Con esta clase estás aplicando tres buenas prácticas:
- Encapsulación: Toda la lógica está dentro de una clase.
- Namespacing: Evita conflictos con otros plugins.
- Hooks bien organizados: Acciones y funciones claramente separadas.
🔐 4. Seguridad en el desarrollo de plugins
WordPress expone muchas funciones útiles, pero también requiere precaución. Aquí van las reglas básicas que todo desarrollador debe seguir:
✅ Evita acceso directo a archivos
En cada archivo PHP dentro de includes añade:
if (!defined('ABSPATH')) {
exit;
}
✅ Escapa y sanitiza datos
Usa las funciones nativas de WordPress para evitar inyecciones y XSS:
- sanitize_text_field() → limpia entradas de texto.
- esc_html() → escapa contenido al mostrarlo.
- wp_kses_post() → permite HTML seguro en el contenido.
$nombre = sanitize_text_field($_POST['nombre']);
echo esc_html($nombre);
✅ Usa Nonces para formularios
Los nonces previenen ataques CSRF. Ejemplo básico:
<form method="post">
<?php wp_nonce_field('guardar_datos', 'mi_plugin_nonce'); ?>
<input type="text" name="nombre">
<input type="submit" value="Guardar">
</form>
<?php
if (isset($_POST['mi_plugin_nonce']) && wp_verify_nonce($_POST['mi_plugin_nonce'], 'guardar_datos')) {
// Acción segura
}
?>
✅ Controla capacidades y roles
Antes de ejecutar acciones en el panel, asegúrate de que el usuario tenga permisos:
if (!current_user_can('manage_options')) {
wp_die('No tienes permiso para acceder a esta sección.');
}
🧱 5. Activación y desactivación del plugin
Crea dos clases en includes > class-activator.php y includes > class-deactivator.php para manejar estas acciones.
<?php
namespace MiPlugin;
class Activator {
public static function activate() {
// Código al activar (crear tablas, opciones, etc.)
}
}
class Deactivator {
public static function deactivate() {
// Código al desactivar (limpiar opciones temporales)
}
}
Y vincúlalas en tu archivo principal:
register_activation_hook(__FILE__, ['\\MiPlugin\\Activator', 'activate']);
register_deactivation_hook(__FILE__, ['\\MiPlugin\\Deactivator', 'deactivate']);
🧠 6. Buenas prácticas de arquitectura
- ✅ Usa nombres de clases y archivos coherentes (prefijo + funcionalidad).
- ✅ Agrupa por módulos si el plugin crece (por ejemplo: admin/, frontend/, api/).
- ✅ Evita variables globales, usa propiedades de clase.
- ✅ Documenta con PHPDoc para mejorar la mantenibilidad.
/**
* Clase principal del plugin.
*
* @package MiPlugin
* @since 1.0.0
*/
También puedes usar Composer para cargar automáticamente clases y dependencias, lo que mejora la escalabilidad.
📦 7. Publica y mantén tu plugin
Antes de subirlo o compartirlo:
- Verifica que todos los textos pasen por funciones de traducción (__() o _e()).
- Usa wp_enqueue_script() y wp_enqueue_style() correctamente (nunca enlaces directos).
- Prueba en entornos distintos (PHP 8+, multisite, modo debug).
- Si lo publicarás, añade un readme.txt con formato estándar.
🎯 Conclusión
Crear un plugin desde cero no se trata solo de hacerlo funcionar, sino de hacerlo bien estructurado, seguro y mantenible. Aplicar namespaces, OOP y funciones nativas de seguridad de WordPress te permitirá ofrecer productos más profesionales, escalables y confiables.
Con estas bases, podrás desarrollar desde pequeños módulos internos hasta plugins premium listos para producción o para publicar en el repositorio oficial.
👉 Próximo artículo: cómo crear un sistema de autoload con Composer y PSR-4 para tus plugins WordPress.


Comentarios recientes