Si llevas un tiempo trabajando con WordPress y Advanced Custom Fields, sabrás que ACF no es solo una herramienta para añadir campos personalizados en el backend: también permite crear custom post types y taxonomías personalizadas.
Sin embargo, poca gente sabe que ACF permite también crear formularios completamente funcionales en el front-end de la web, para añadir contenido al CPT que hayas programado y con los mismos campos personalizados que has creado en el back-end, sin que el usuario tenga que acceder al panel de administración.
Hace un tiempo tuvimos que crear exactamente este sistema para un cliente, y la documentación oficial de ACF nos pareció un poco parca en palabras y poco detallada, así que hemos decidido publicar este tutorial para otros desarrolladores que necesiten hacer lo mismo.
Nota importante: este tutorial está pensado para desarrolladores ya familiarizados con WordPress, los Custom Post Types (CPT) y el funcionamiento básico de ACF. No vamos a explicar cómo instalar el plugin y crear los campos necesarios ni cómo crear un CPT desde cero, asumimos que eso ya lo tienes claro.
Lo que sí vamos a ver, paso a paso, es:
- Cómo montar un formulario de envío desde el front-end que guarde los registros como borradores
- WordPress te avisa por email cada vez que alguien envía un registro
- Opcionalmente, se redirije al usuario a una landing de confirmación de «Registro Recibido» o similar
El escenario
Imagina que gestionas DirectorioEmpresasACME.com, un directorio online donde las empresas pueden aparecer listadas con toda su información.
Hasta ahora, las fichas las añadías tú a mano desde el admin de WordPress, pero quieres que las propias empresas puedan enviar su información mediante un formulario público, y tú simplemente revisas y publicas cada envío.
Para ello tienes creado en WordPress:
- Un Custom Post Type llamado «Empresas», cuyo slug interno es /empresa/
- Un grupo de campos ACF asociado a ese Custom Post Type, con los siguientes campos:
| Dato | Nombre del campo | Tipo |
|---|---|---|
| Denominación legal | nombre_legal_empresa | Texto |
| Sector | sector_empresa | Selección |
| Número de trabajadores | numero_trabajadores | Selección |
| Página web | web_empresa | URL |
| Teléfono | telefono_empresa | Texto |
| Facturación anual | facturacion_anual_empresa | Selección |
| Provincia | provincia_empresa | Selección |
| Ciudad | ciudad_empresa | Texto |
Además:
- El campo de título del post (el nativo de WordPress) se usará como el nombre común de la empresa
- El campo de contenido del post (también nativo de WordPress) permitirá pegar una descripción de la empresa
Lo que necesitas saber antes de empezar
ACF ofrece dos funciones para construir formularios front-end:
acf_form_head()> Se coloca antes deget_header()- Esta función registra los assets necesarios (CSS y JS), procesa los datos enviados y gestiona la redirección
- Es obligatoria y debe ejecutarse en ese orden
acf_form()> Se coloca dentro de la plantilla, donde quieras que aparezca el formulario- Como verás en el snippet de código, acepta un array de parámetros para configurar su comportamiento
La clave para crear un post nuevo (en lugar de editar uno existente) es el parámetro 'post_id' => 'new_post', combinado con 'empresa' y 'draft'para especificar el tipo de contenido y el estado del post.
Para que el formulario funcione correctamente necesitamos crear 2 cosas:
- Una plantilla dentro de nuestro theme donde se cargará el formulario de ACF
- Una función dentro del archivo functions.php que nos enviará el email de aviso cada vez que alguien envíe un formulario
Pasos para poner en marcha tu formulario ACF
Vamos a ver los pasos necesarios para poner esto en marcha.
Paso 1: crear la plantilla de página y la página de formulario
Crea el archivo form-enviar-empresa.php en la carpeta de tu tema hijo. Puedes hacerlo por FTP o mediante el navegador de archivos del servidor o hosting.
Recuerda usar un tema hijo o perderás el archivo con la siguiente actualización de tu tema de WordPress
Este archivo actuará como plantilla de página de WordPress y contendrá toda la lógica del formulario.
Este es el código que usaremos para la plantilla (el nombre de la plantilla y su contenido está en español):
<?php
/**
* Template Name: ACF Form Enviar Empresa
*/
// IMPORTANT: acf_form_head() must go before get_header()
acf_form_head();
get_header();
?>
<div id="formulario-empresa" style="max-width: 900px; margin: 60px auto; padding: 0 20px;">
<h1>Añade tu empresa al directorio</h1>
<p>Rellena el formulario con los datos de tu empresa. Revisaremos la información antes de publicarla en el directorio.</p>
<?php
acf_form(array(
'post_id' => 'new_post',
'post_title' => true,
'post_content' => true,
'new_post' => array(
'post_type' => 'empresa',
'post_status' => 'draft',
),
'submit_value' => 'Enviar empresa',
'updated_message' => '¡Gracias! Tu empresa ha sido recibida y la revisaremos pronto.',
));
?>
</div>
<?php get_footer(); ?>Con esta configuración, tras el envío el formulario el usuario se queda en la misma página y se le muestra el mensaje de confirmación ¡Gracias! Tu empresa ha sido recibida y la revisaremos pronto.
Si prefieres redirigir al usuario a una landing page específica, ve a la sección alternativa más abajo.
Paso 2 — Crear la página en WordPress
Con el archivo de plantilla ya subido a tu tema hijo:
- Ve a Páginas > Añadir nueva
- Ponle un título descriptivo, tipo «Formulario de envío de empresas» o algo similar
- En Atributos de página, selecciona la plantilla php que hemos creado antes, en nuestro caso
form-enviar-empresa.php - Añade metatítulo y metadescripción mediante el plugin SEO que uses
- Publica la página
WordPress usará tu plantilla PHP en lugar del editor visual, así que no hace falta añadir nada en el editor de la página.
Paso 3: crear un aviso por email en el functions.php
Cada vez que alguien envíe el formulario, puedes recibir una notificación para saber que tienes una nueva empresa añadida que está en borrador pendiente de que la revises y publiques.
Para conseguir eso, añade esto al functions.php de tu tema hijo:
/**
* ACF Form email notification
*/
add_action('acf/save_post', 'notificar_nueva_empresa', 20);
function notificar_nueva_empresa( $post_id ) {
if ( get_post_type($post_id) !== 'empresa' ) {
return;
}
if ( is_admin() ) {
return;
}
if ( get_post_status($post_id) !== 'draft' ) {
return;
}
$nombre = get_the_title($post_id);
$sector = get_field('sector_empresa', $post_id);
$trabajadores = get_field('num_trabajadores', $post_id);
$web = get_field('web_empresa', $post_id);
$telefono = get_field('telefono_empresa', $post_id);
$provincia = get_field('provincia_empresa', $post_id);
$ciudad = get_field('ciudad_empresa', $post_id);
$enlace_admin = admin_url('post.php?post=' . $post_id . '&action=edit');
$to = 'info@directorioEmpresasACME.com';
$subject = '[DirectorioEmpresas] Nueva empresa pendiente: ' . $nombre;
$body = "Se ha recibido una nueva empresa para revisar.\n\n";
$body .= "──────────────────────────\n";
$body .= "Empresa: {$nombre}\n";
$body .= "Sector: {$sector}\n";
$body .= "Trabajadores: {$trabajadores}\n";
$body .= "Web: {$web}\n";
$body .= "Teléfono: {$telefono}\n";
$body .= "Provincia: {$provincia}\n";
$body .= "Ciudad: {$ciudad}\n";
$body .= "──────────────────────────\n\n";
$body .= "Revisar y publicar:\n{$enlace_admin}\n";
wp_mail($to, $subject, $body);
}Notas:
El hook acf/save_post se dispara cada vez que ACF guarda datos, tanto desde el admin como desde el front-end, por tanto recibiríamos un email cada vez que un post en borrador fuese creado, incluso por nosotros mismo desde el escritorio de WordPress.
Como no tiene mucho sentido enviar emails constantemente, las comprobaciones de is_admin() y get_post_type() garantizan que el email solo se envíe cuando corresponde.
Alternativa: redirigir a una landing de confirmación una vez enviado el formulario
El snippet php anterior solamente muestra un mensaje tras el envío el formulario tipo ¡Gracias! Tu empresa ha sido recibida y la revisaremos pronto. El usuario se queda en la misma página y no ocurre nada más.
Si lo prefieres, puedes redirigir al usuario a una URL específica tras el envío.
Crea una landing page a donde llevar al usuario
Crea una landing page a donde llevar al usuario una vez haya enviado el formulario, en nuestro ejemplo hemos creado esta página:
https://DirectorioEmpresasACME.com/empresa-recibida/
En la landing page informa al usuario que el formulario se ha enviado correctamente. También puedes aprovechar la página para vender subscripciones o servicios relacionados con tu web. ¡Se elegante y profesional!
Modifica la plantilla php de tu theme
Luego, debes modificar la plantilla para tu theme que has creado previamente, en nuestro caso form-enviar-empresa.php
Simplemente deberás substituir el parámetro 'updated_message' por 'return' en la funciónacf_form() y apuntar a la landing page que previamente hayas creado, así:
acf_form(array(
'post_id' => 'new_post',
'post_title' => true,
'post_content' => true,
'new_post' => array(
'post_type' => 'empresa',
'post_status' => 'draft',
),
'submit_value' => 'Enviar empresa',
'return' => 'https://DirectorioEmpresasACME.com/empresa-recibida/',
));Notas y resolución de problemas
Información complementaria para que tu formulario ACF funcione perfectamente.
Si el formulario aparece vacío
Para que acf_form() muestre los campos, el grupo de campos de ACF debe estar configurado para mostrarse en el lugar correcto.
Si el formulario aparece vacío y al crear una nueva empresa en el escritorio de WordPress tampoco aparece ningún campo, seguramente hayas asignado el grupo de campos al post type erróneo (por defecto ACF asigna un grupo de campos nuevo a ‘Posts’).
Ve a ACF > Grupos de campos y edita tu grupo. La regla de ubicación debe mostrar el grupo de campos en el lugar correcto, en nuestro ejemplo ficticio: Tipo de contenido > es igual a > Empresas
Los campos no son responsive en móvil
Los campos del formulario heredan los estilos visuales que hayas configurado en ACF.
Es decir, si has configurado 3 campos para que se muestren al 33% de ancho en ACF > Presentación > Atributos del contenedor, porque quieres crear 3 columnas (o una fila con 3 campos) así es como mostrarán en el formulario.
Esos anchos se aplican como estilos inline en el HTML y puede ser que no respondan automáticamente en móvil.
Si eso te ocurre, para solucionarlo, añade esto en el functions.php:
/**
* CSS responsive para el formulario de empresas
*/
add_action('wp_head', 'formulario_empresa_css_responsive');
function formulario_empresa_css_responsive() {
if ( ! is_page('añade-tu-empresa') ) {
return;
}
?>
<style>
@media (max-width: 768px) {
#formulario-empresa .acf-field[style] {
width: 100% !important;
float: none !important;
}
}
</style>
<?php
}El selector [style] apunta específicamente a los elementos con estilos inline, que son los que ACF genera para los anchos de campo y que de otro modo ignorarían una regla CSS normal.
El flujo completo de trabajo
- Usuario rellena el formulario en la página que hayamos creado
- El post se crea como borrador en el apartado del Custom Post Type ‘empresa’
- Opción A: se muestra al usuario un mensaje de confirmación en la misma página al enviar el formulario correctamente
- Opción B: se le dirige a otra página, por ejemplo DirectorioEmpresasACME.com/empresa-recibida/
- Recibes un aviso por email en info@DirectorioEmpresasACME.com con un resumen de la información enviada y un enlace directo al borrador
- Entras a tu escritorio de WordPress, revisas y publicas
Consideraciones finales
Algunos puntos a tener en cuenta antes de poner esto en producción:
- El formulario funciona para todo el mundo, también para usuarios no logueados
- La función
acf_form()funciona para todo el mundo por defecto, sin necesidad de estar registrado. - Si quieres restringir el uso del formulario a usuarios logueados, añade una comprobación con
is_user_logged_in()antes deacf_form_head().
- La función
- La lógica condicional que hayas programado en ACF, funcionará también en el formulario.
- Si tienes campos con lógica condicional configurada en ACF (por ejemplo, mostrar el campo «ciudad» solo si la «provincia» es whatever), esa lógica que hayas programado es la misma que se cargará en el formulario, porque ACF carga su propio JavaScript para gestionarlo.
- Vacia la caché si los estilos no cargan correctamente (sí, casi siempre es problema de la caché)
- Si usas un plugin de caché o un page builder con generación de CSS estático (como Divi), puede que los estilos y scripts no se carguen correctamente para usuarios no logueados hasta que la caché se vacíe por completo.
- Si ves que el formulario funciona logueado pero no en incógnito, ese es el primer sitio donde mirar.
- Limpia cachés de plugins, servidor y navegador y vuelve a comprobar los estilos.
- Nota: no hemos instalado ningún sistema anti-spam.
- Este formulario no incluye ningún sistema antispam. Si lo pones en producción y ves que recibes envíos spam, considera añadir un sistema de honeypot o integrar de Captcha mediante alguno de los plugins disponibles en el repositorio de WordPress
Esperamos que este tutorial te haya sido útil
Si tienes experiencia con ACF y CPT en WordPress, esperamos que este tutorial expanda tus conocimientos sobre este poderoso plugin para WordPress. ¡Un saludo y hasta pronto!



