Cómo construir un plugin sencillo para WordPress desde la idea al repo
1) Define la idea y el alcance
Elige un problema pequeño y útil: un shortcode, un ajuste en admin o una integración simple. Limita el alcance para lanzar rápido.
Objetivo: Añadir un shortcode con mensaje personalizable. Usuario: Administrador/Editor Acción principal: Insertar [mi_plugin mensaje="..."] No incluye: Bloques complejos, API externas Éxito: Shortcode visible y opción en Ajustes > Mi Plugin
2) Estructura mínima de un plugin
mi-plugin/ ├─ mi-plugin.php ├─ readme.txt ├─ includes/ │ ├─ class-mi-plugin.php │ └─ functions.php ├─ assets/ │ ├─ frontend.css │ └─ icon-256x256.png └─ languages/ └─ mi-plugin-es_ES.mo
3) Código base funcional
Copia estos fragmentos en tus archivos. Activa el plugin y prueba el shortcode [mi_plugin mensaje="¡Hola!"]Contenido.
Archivo principal: mi-plugin.php
<?php
/**
* Plugin Name: Mi Plugin Sencillo
* Description: Ejemplo con shortcode y página de ajustes.
* Version: 1.0.0
* Author: Tu Nombre
* License: GPL-2.0-or-later
* Text Domain: mi-plugin
* Domain Path: /languages
*/
if ( ! defined( 'ABSPATH' ) ) exit;
define( 'MI_PLUGIN_VERSION', '1.0.0' );
define( 'MI_PLUGIN_PATH', plugin_dir_path(__FILE__) );
define( 'MI_PLUGIN_URL', plugin_dir_url(__FILE__) );
add_action('plugins_loaded', function(){
load_plugin_textdomain('mi-plugin', false, dirname(plugin_basename(__FILE__)).'/languages');
});
register_activation_hook(__FILE__, function(){ add_option('mi_plugin_opcion','on'); });
require_once MI_PLUGIN_PATH.'includes/functions.php';
require_once MI_PLUGIN_PATH.'includes/class-mi-plugin.php';
add_shortcode('mi_plugin','mi_plugin_shortcode');
add_action('admin_menu', function(){
add_options_page(__('Ajustes de Mi Plugin','mi-plugin'),'Mi Plugin','manage_options','mi-plugin-ajustes','mi_plugin_pantalla_ajustes');
});
add_action('wp_enqueue_scripts', function(){
wp_enqueue_style('mi-plugin-frontend', MI_PLUGIN_URL.'assets/frontend.css', [], MI_PLUGIN_VERSION);
});
Funciones: includes/functions.php
<?php
if ( ! defined( 'ABSPATH' ) ) exit;
function mi_plugin_shortcode($atts = [], $content = '') {
$atts = shortcode_atts(['mensaje' => __('Hola desde Mi Plugin 👋','mi-plugin')], $atts, 'mi_plugin');
ob_start(); ?>
<div class="mi-plugin-box">
<strong><?php echo esc_html($atts['mensaje']); ?></strong>
<?php if ($content) : ?>
<div class="mi-plugin-content"><?php echo wp_kses_post($content); ?></div>
<?php endif; ?>
</div>
<?php return ob_get_clean();
}
function mi_plugin_pantalla_ajustes(){
if ( isset($_POST['mi_plugin_nonce']) && wp_verify_nonce($_POST['mi_plugin_nonce'],'mi_plugin_guardar') ) {
update_option('mi_plugin_opcion', sanitize_text_field($_POST['mi_plugin_opcion'] ?? 'off'));
echo '<div class="updated"><p>'.esc_html__('Ajustes guardados','mi-plugin').'</p></div>';
}
$valor = get_option('mi_plugin_opcion','on'); ?>
<div class="wrap">
<h1><?php esc_html_e('Ajustes de Mi Plugin','mi-plugin'); ?></h1>
<form method="post">
<?php wp_nonce_field('mi_plugin_guardar','mi_plugin_nonce'); ?>
<label>
<input type="checkbox" name="mi_plugin_opcion" value="on" <?php checked($valor,'on'); ?>>
<?php esc_html_e('Activar mensaje por defecto','mi-plugin'); ?>
</label>
<p><button class="button button-primary"><?php esc_html_e('Guardar cambios','mi-plugin'); ?></button></p>
</form>
</div>
<?php }
Clase (opcional): includes/class-mi-plugin.php
<?php
if ( ! defined( 'ABSPATH' ) ) exit;
class MI_Plugin {
public function __construct(){ add_action('init', [$this,'boot']); }
public function boot(){
add_shortcode('mi_plugin_time', function(){
return '<span class="mi-plugin-time">'.esc_html(date_i18n(get_option('time_format'))).'</span>';
});
}
}
new MI_Plugin();
CSS mínimo: assets/frontend.css
.mi-plugin-box{padding:12px;border:1px solid #e3e8ef;border-radius:10px;background:#f8fafc;font:500 16px/1.5 system-ui,-apple-system,Segoe UI,Roboto,Arial}
.mi-plugin-content{margin-top:6px;color:#334155}
4) README y assets del repositorio
Crea readme.txt y los banners para WordPress.org.
=== Mi Plugin Sencillo === Contributors: tuusuario Tags: shortcode, ajustes, ejemplo Requires at least: 5.8 Tested up to: 6.6 Stable tag: 1.0.0 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Plugin de ejemplo con shortcode y página de ajustes. == Description == - Shortcode: [mi_plugin] - Ajustes en Ajustes > Mi Plugin. - Seguro, ligero y traducible. == Installation == 1. Subir carpeta "mi-plugin" a /wp-content/plugins/. 2. Activar en "Plugins". 3. Usar el shortcode. == Changelog == = 1.0.0 = * Primera versión.
5) Publicar en WordPress.org (SVN) o GitHub
svn/ ├─ assets/ # banners/iconos del perfil del plugin ├─ trunk/ # código actual └─ tags/1.0.0/ # snapshot por versión
# Crear tag 1.0.0 desde trunk svn copy trunk tags/1.0.0 -m "Versión 1.0.0" svn commit -m "Publicación inicial"
6) Checklist de publicación
- Version y Stable tag coinciden (1.0.0).
- readme.txt válido y banners en
/assets(icon-256, banner-772×250). - Internacionalización activa (
load_plugin_textdomain). - Pruebas en PHP 7.4–8.3 y WP 6.x; sin avisos con
WP_DEBUG.
FAQ
¿Cómo uso el shortcode?
Escribe [mi_plugin mensaje="¡Plugin listo!"]Contenido opcional[/mi_plugin] en el editor.
¿Cómo limpio datos al desinstalar?
Añade un archivo uninstall.php con delete_option('mi_plugin_opcion').