Contents
Introducción
Este tutorial explica de forma exhaustiva cómo enviar correos electrónicos desde WordPress usando la función wp_mail y plantillas HTML en PHP. Incluye ejemplos prácticos, configuración del tipo de contenido, carga de plantillas, seguridad, personalización del remitente y depuración. Los fragmentos de código están listados para copiar y pegar directamente en temas o plugins.
Qué es wp_mail y cómo funciona
wp_mail() es la envoltura de WordPress sobre PHPMailer. Permite enviar correo usando parámetros simples (to, subject, message, headers, attachments). Por defecto envía texto plano para enviar HTML hay que indicar el Content-Type adecuado o usar filtros. Además, hay filtros útiles como wp_mail_from, wp_mail_from_name y wp_mail_content_type para personalizar comportamiento.
Requisitos y buenas prácticas previas
- Asegúrate de que tu servidor puede enviar correo saliente. En muchos casos conviene configurar un SMTP real (por ejemplo mediante el plugin WP Mail SMTP) o usando phpmailer_init para ajustar credenciales.
- Sanitiza y valida las direcciones de correo con sanitize_email() y is_email() antes de pasarlas a wp_mail.
- Usa nonces y comprobaciones de permisos al enviar correos desde formularios públicos para evitar abuso y envío masivo no autorizado.
Contenido HTML: establecer el tipo correctamente
Para que los clientes de correo interpreten correctamente HTML, debes indicar el Content-Type. Lo habitual es añadir un filtro temporal que lo ponga en text/html charset=UTF-8:
add_filter(wp_mail_content_type, function() {
return text/html charset=UTF-8
})
Tras enviar el correo conviene restablecer el tipo por defecto (text/plain) para no romper otros envíos:
// Añadir antes de wp_mail
add_filter(wp_mail_content_type, my_html_content_type)
wp_mail(to, subject, message, headers, attachments)
remove_filter(wp_mail_content_type, my_html_content_type)
function my_html_content_type() {
return text/html charset=UTF-8
}
Carga de una plantilla HTML desde el tema o plugin
Lo ideal es mantener plantillas HTML separadas en archivos y cargarlas para evitar concatenar cadenas en el código. A continuación un patrón seguro para cargar una plantilla y pasarle variables.
Ejemplo de plantilla (archivo: email-templates/user-welcome.php) — contiene HTML completo y placeholders:
lt!doctype htmlgt
lthtml lang=esgt
ltheadgt
ltmeta charset=utf-8gt
ltmeta name=viewport content=width=device-widthgt
lttitlegtBienvenidolt/titlegt
ltstylegt
/ CSS mínimo inline recomendado para compatibilidad en clientes de correo /
body { font-family: Arial, sans-serif color: #333 }
.container { width: 100% max-width: 600px margin: 0 auto }
.btn { display:inline-block padding:10px 16px background:#0073aa color:#fff text-decoration:none border-radius:3px }
lt/stylegt
lt/headgt
ltbodygt
lttable role=presentation width=100% cellpadding=0 cellspacing=0gt
lttrgtlttd class=containergt
lth2gtHola, {{name}}!lt/h2gt
ltpgtGracias por registrarte en nuestro sitio. Para activar tu cuenta pulsa el siguiente botón:lt/pgt
ltpgtlta class=btn href={{activation_url}}gtActivar cuentalt/agtlt/pgt
ltpgtSi no has solicitado esto, ignora este correo.lt/pgt
lt/tdgtlt/trgt
lt/tablegt
lt/bodygt
lt/htmlgt
Función para renderizar y enviar usando la plantilla anterior:
function send_templated_email( to, subject, template_path, vars = array(), attachments = array() ) {
// Validaciones básicas
to = sanitize_email( to )
if ( ! is_email( to ) ) {
return false
}
// Localiza la plantilla en tema/child o en plugin
located = locate_template( template_path )
if ( ! located ) {
// Si estás en un plugin puedes usar plugin_dir_path(__FILE__) . templates/ . template_path
return false
}
// Cargar plantilla y capturar salida
ob_start()
load_template( located, false )
message = ob_get_clean()
// Reemplazar variables seguras (usar esc_html para valores simples)
foreach ( vars as key => value ) {
safe = esc_html( value )
message = str_replace( {{ . key . }}, safe, message )
}
// Cabeceras: indicar HTML
add_filter(wp_mail_content_type, function() { return text/html charset=UTF-8 })
// Enviar
sent = wp_mail( to, subject, message, array(), attachments )
// Restaurar filtros
remove_filter(wp_mail_content_type, wp_mail_content_type)
return sent
}
Ejemplo práctico: envío tras registro (procesamiento de formulario) con nonce y sanitización
if ( isset(_POST[my_register_form]) ) {
if ( ! isset(_POST[_wpnonce]) ! wp_verify_nonce( _POST[_wpnonce], my_register_action ) ) {
wp_die(Nonce no válido)
}
email = isset(_POST[email]) ? sanitize_email(_POST[email]) :
name = isset(_POST[name]) ? sanitize_text_field(_POST[name]) :
if ( ! is_email(email) ) {
wp_die(Email no válido)
}
activation_link = add_query_arg( array( key => wp_generate_uuid4(), email => rawurlencode(email) ), home_url(/activar/) )
vars = array(
name => name,
activation_url => activation_link,
)
sent = send_templated_email( email, Activa tu cuenta, email-templates/user-welcome.php, vars )
if ( sent ) {
// Redirigir o mostrar mensaje de éxito
} else {
// Gestionar error
}
}
Personalizar el remitente (From) de forma segura
Modificar From mediante cabeceras puede funcionar, pero lo recomendado es usar los filtros de WordPress para evitar problemas con múltiples envíos concurrentes. Ejemplo:
function my_mail_from( original_email_address ) {
return no-reply@tudominio.com
}
function my_mail_from_name( original_email_from ) {
return Tu Sitio
}
// Antes de enviar
add_filter(wp_mail_from, my_mail_from)
add_filter(wp_mail_from_name, my_mail_from_name)
wp_mail(to, subject, message)
// Después de enviar (restaurar)
remove_filter(wp_mail_from, my_mail_from)
remove_filter(wp_mail_from_name, my_mail_from_name)
Configurar SMTP mediante phpmailer_init (opción programática)
Si no quieres usar plugins, puedes configurar PHPMailer con el hook phpmailer_init. Útil para entornos donde el mail() está deshabilitado.
add_action(phpmailer_init, function(phpmailer) {
phpmailer->isSMTP()
phpmailer->Host = smtp.example.com
phpmailer->SMTPAuth = true
phpmailer->Port = 587
phpmailer->Username = usuario@smtp
phpmailer->Password = contraseña
phpmailer->SMTPSecure = tls // o ssl
phpmailer->From = no-reply@tudominio.com
phpmailer->FromName = Tu Sitio
})
Adjuntos y cabeceras adicionales
wp_mail acepta un array de cabeceras y un array de rutas de archivos como adjuntos. Ejemplo:
headers = array(
Reply-To: Soporte ,
X-Mailer: WordPress/ . get_bloginfo(version)
)
attachments = array( WP_CONTENT_DIR . /uploads/manual.pdf )
wp_mail( to, subject, message, headers, attachments )
Cómo depurar envíos que fallan
- Activa WP_DEBUG y revisa logs. A veces wp_mail devuelve false y no hay mensajes: habilita el log del servidor SMTP o depura PHPMailer con el hook phpmailer_init.
- Plugins como WP Mail SMTP ofrecen registros para ver errores SMTP.
- Comprueba que el servidor no esté bloqueando el puerto SMTP y revisa SPF/DKIM/DMARC si los correos llegan marcados como spam.
Seguridad y compatibilidad
- Sanitiza inputs antes de incluirlos en la plantilla para evitar inyección de HTML no deseada. Usa esc_html() para texto simple y wp_kses_post() si permites etiquetas HTML limitadas.
- No incluyas datos sensibles en correos no cifrados (contraseñas en texto claro, tokens permanentes, etc.).
- Para emails transaccionales críticos, usa proveedores SMTP/servicios dedicados (SendGrid, Mailgun, Amazon SES) para mayor entregabilidad y métricas.
- Para plantillas con CSS avanzado, aplica estilos inline o utiliza herramientas para inlinizar CSS antes de enviar (mejor compatibilidad con clientes de correo).
Pruebas y flujo recomendado
Prueba localmente con servicios de inspección de correo (MailHog, Mailtrap) o plugins que redirijan correos a logs durante desarrollo. Implementa primero la versión en texto plano y luego añade HTML para depurar de forma más sencilla.
Resumen
Enviar correos HTML en WordPress con wp_mail implica:
- Establecer el content-type a text/html.
- Organizar plantillas HTML separadas y cargarlas con locate_template/load_template o desde carpetas de plugin.
- Sanitizar datos, usar nonces en formularios y configurar el remitente de forma segura mediante filtros.
- Si el servidor no envía correctamente, configurar SMTP vía plugin o phpmailer_init.
Enlaces útiles
|
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |
