Es muy fácil crear un grupo de campos de ACF y luego utilizar sus formularios en el Backend para gestionar la información de una página web, pero ¿qué pasa si este formulario tenemos que mostrarlo en el Frontend para que los usuarios carguen datos?
A continuación voy a mostrarte los pasos para crear el formulario ACF en el Frontend utilizando la función acf_form()
y sus parámetros.
Caso de ejemplo
Vamos a suponer que un cliente nos pide tener una agenda con contactos que él mismo pueda cargar desde el backend del sitio web, pero también necesita que los visitantes puedan dejar sus datos en la página web (sin tener la necesidad de loguearse).
Posible solución:
- Creamos un Custom Post Type «Contacto»
- Creamos los campos personalizados con ACF para el Custom Post Type «Contacto».
- Creamos una página llamada «Déjame tus datos»
- Creamos una plantilla para esa página
page-dejame-tus-datos.php
donde desplegaremos el formulario con el siguiente código:
<?php
// Parámetros de la función acf_form().
$args = [
'new_post' => array(
'post_type' => 'contacto',
'post_status' => 'publish'
),
'post_id' => 'new_post',
'post_title' => true,
'submit_value' => 'Actualizar',
'updated_message' => 'Contacto actualizado',
];
// Llamamos a la función acf_form() de ACF pasando los parámetros definidos en el paso anterior.
acf_form( $args );</pre>
El código paso a paso
Una vez mostrado el código final vamos a ir desgranándolo paso a paso para entenderlo mejor y ver que otras posibilidades podemos implementar.
Creación del Custom Post Type Contacto
Primero vamos a crear el Custom Post Type «Contacto» para luego poder añadirle el conjunto de campos personalizados. También adjuntaremos al CPT una taxonomía «Intereses» para que los contactos puedan seleccionar sobre qué temas están interesados.
<?php
// Función para crear el CPT 'contacto' y la taxonomía 'intereses'.
function crear_custom_post_type_contacto() {
// Parámetros para la creación del CPT contacto.
$args = [
'has_archive' =>; false,
'labels' =>; [
'name' =>; 'Contactos',
],
'public' =>; 'true',
'show_ui' =>; true,
'show_in_menu' =>; true,
'show_in_rest' =>; true,
];
register_post_type( 'contacto', $args );
// Parámetros para la creación de la taxonomía 'intereses'.
$args = [
'labels' =>; [
'name' =>; 'Intereses',
'singular_name' =>; 'Interés',
'menu_name' =>; 'Intereses'
],
];
register_taxonomy( 'interes', 'contacto', $args );
}
add_action( 'init', 'crear_custom_post_type_contacto' );
Creación de los campos personalizados con ACF
Creamos los siguientes campos con el plugin de ACF:
- Email: la dirección de correo electrónico del contacto. El campo será del tipo Email para agregar los controles de validación.
- Dirección: Un simple campo de texto para que el contacto pueda cargar su dirección física.
- ¿Cómo nos has conocido?: Un campo del tipo selector con 3 posibles valores («A través de la página de Facebook», «A través de vuestro Newsletter» y «A través de un referido»).
- Intereses: Campo del tipo taxonomía, donde mostraremos los términos cargados en la taxonomía «Intereses».
Una vez cargados todos los campos solo debemos especificar la «Ubicación» del mismo, para ello seleccionaremos que el «Post Type es igual a Contactos».

Creación de la página «Déjame tus datos»
Vamos a crear una página de WordPress para luego poder asignarle una plantilla personalizada. Para ello basta con ir al menú Páginas » Añadir nueva y publicarla con el título «Déjame tus datos» (esto creará un slug dejame-tus-datos
que utilizaremos en el siguiente paso).
Creación de la plantilla personalizada
Vamos a agregar un nuevo fichero a nuestro tema (o tema hijo) para personalizar el HTML de la página «Déjame tus datos». Para ellos necesitamos crear un nuevo fichero llamado page-dejame-tus-datos.php
siguiendo la nomenclatura de la jerarquía de plantillas de WordPress.
En este fichero agregaremos el siguiente código:
<?php
// Debemos agregar esta función al principio de todo para que
// cargue las dependencias necesarias para renderizar el formulario.
acf_form_head();
get_header();
?>
<section>
<main role="main">
<?php
while ( have_posts() ) : the_post(); ?>
<h1><?php the_title(); ?></h1>
<?php
the_content();
$args = [
'new_post' => [
'post_type' => 'contacto',
'post_status' => 'publish'
],
'post_id' => 'new_post',
'post_title' => true,
'submit_value' => 'Actualizar',
'updated_message' => 'Contacto actualizado',
];
acf_form( $args );
endwhile;
?>
</main>
</section>

Detalles importantes del código
La función acf_form() tiene dos parámetros especiales llamados post_id
y new_post
que configurados correctamente nos permiten guardar la información en nuestra estructura de datos.
El parámetro post_id se utiliza para editar una entrada (o Custom Post Type) que ya existe, pero si le asignamos el valor 'new_post'
, creará una nuevo registro.
El parámetro new_post
tendrá un array con los datos del post a guardar. Los valores de este array son los mismos que utilizamos con la función estándar de WordPress wp_insert_post()
. En el CODEX podrás encontrar más detalles sobre los parámetros de esta función.
acf_form_head()
Hay que tener en cuenta que la función acf_form()
solamente creará el formulario para que los usuarios puedan carga información, la programación para guardar verdaderamente estos datos se encuentra en la función acf_form_head()
que debemos llamar al principio de nuestra plantilla antes de renderizar cualquier código HTML (inclusive antes de la función wp_head()
estándar de WordPress).
Otros parámetros de la función acf_form()
En mi ejemplo solo he utilizado algunos de los tantos parámetros que tiene esta opción. Aquí te dejo el resto para que puedas investigar un poco más y adaptar el formulario a tus necesidades.
<?php
$settings = array(
/* (string) Será el nombre del atributo ID del formulario. Por defecto 'acf-form' */
'id' => 'acf-form',
/* (int|string) El ID del post para cargar y guardar la información. Por defecto es el ID del post actual.
También se puede especificar el valor 'new_post' para crear un nuevo post con el envío de los datos.*/
'post_id' => false,
/* (array) Un array con información para crear el nuevo post. Puedes ver todos los parámetros disponibles en la función wp_insert_post de WordPress.
El parámetro 'post_id' debe tener el valor 'new_post'*/
'new_post' => false,
/* (array) Un array con los ID/Keys de los grupos de campos personalizados para sobrescribir los del formulario */
'field_groups' => false,
/* (array) Un array con los IDs/keys de los campos para sobrescribir los del formulario. */
'fields' => false,
/* (boolean) Si es true se muestra un campo de texto para cargar el título del post. Por defecto es false */
'post_title' => false,
/* (boolean) Si es true se muestra un textarea para cargar el contenido del post. Por defecto es false */
'post_content' => false,
/* (boolean) Si es true creará la etiqueta <form>. Útil cuando se agrega a un formulario que ya existe. Por defecto es true */
'form' => true,
/* (array) Un array de atributos para agregar a la etiqueta <form> */
'form_attributes' => array(),
/* (string) La URL a la que se redireccionará luego de haber enviado el formulario. Por defecto es la URL actual con un parámetro GET '?updated=true'.
Podemos utilizar el comodín '%post_url%' que se convertirá en el permalink.
Podemos utilizar el comodín '%post_od%' que se convertirá en el ID del post.*/
'return' => '',
/* (string) HTML extra que se añadirá antes de los campos. */
'html_before_fields' => '',
/* (string) HTML que se añadirá después de los campos. */
'html_after_fields' => '',
/* (string) El texto que se muestra en el botón. */
'submit_value' => __("Update", 'acf'),
/* (string) Un mensaje que se mostrará sobre el formulario una vez que se haya hecho la redirección. también se puede espeificar el valor false para que no haya mensajes. */
'updated_message' => __("Post updated", 'acf'),
/* (string) Determina dónde se ubicarán las etiquetas de los campos. Por defecto es 'top'.
Los valores posibles son: 'top' (arriba de los campos) o 'left' (a la izquierda de los campos). */
'label_placement' => 'top',
/* (string) Determina dónde se ubicarán las instrucciones de los campos. Por defecto es 'label'
Los posibles valores son: 'label' (debajo de las etiquetas) or 'field' (debajos de los campos) */
'instruction_placement' => 'label',
/* (string) Define la etiqueta que se utilizará para envolver el campo. Por defecto es 'div'
Los posibles valores son: 'div', 'tr', 'td', 'ul', 'ol', 'dl' */
'field_el' => 'div',
/* (string) Determina si utilizar el WP upload o un input básico para la carga de imágenes. Por defecto es 'wp'
Los posibles valores son:'wp' o 'basic'.*/
'uploader' => 'wp',
/* (boolean) Si es true se incluye un campo oculto para evitar los envíos que no hayan sido enviados por humanos. Por defecto es true. */
'honeypot' => true,
/* (string) HTML que se usa para renderizar el mensaje de actualización. */
'html_updated_message' => '<div id="message" class="updated"><p>%s</p></div>',
/* (string) HTML que se usa para renderizar el botón de envío. */
'html_submit_button' => '<input type="submit" class="acf-button button button-primary button-large" value="%s" />',
/* (string) HTML que se usa para renderizar la animación de cargando del botón de envío. */
'html_submit_spinner' => '<span class="acf-spinner"></span>',
/* (boolean) Si es true sanitiza todos los datos enviados en la variable $_POST con la función wp_kses_post(). Por defecto es true. */
'kses' => true
);
Agregar más funcionalidad
¿Qué pasa si queremos realizar más acciones cuando el usuario guarda los datos? Para ello podemos utilizar la acción acf/save_post
, el cual nos permite agregar cualquier otra lógica que necesitamos para el negocio tanto antes como después del guardado de los datos.
Agregar más funcionalidad ANTES
Para agregar más funcionalidad antes de que se guarden los datos, solamente debemos especificar una prioridad menor a 10 en la llamada a la acción acf/save_post
, por ejemplo:
<?php
// Esta función añade nuevas funcionalidades
// antes de guardar los datos enviados desde
// el Frontend.
function acf_guardar_antes( $post_id ) {
// Por ejemplo validar los datos con otro sistema.
ValidarDatosEnOtroSistema( $_POST );
// O bien registrar un log.
wp_insert_post( ['post_type' =>; 'log'], 'post_title' =>; 'Nuevo Contacto desde Frontend' ] );
}
add_action('acf/save_post', 'acf_guardar_antes', 1);
Agregar más funcionalidad DESPUÉS
Y como era de esperarse, para agregar más funcionalidades después de guardar los datos, solamente debemos cambiar la prioridad de la acción a un número mayor que 10, por ejemplo:
<?php
/*
Esta función añade nuevas funcionalidades
después de guardar los datos enviados desde
el Frontend.
*/
function acf_guardar_despues( $post_id ) {
// Enviar email al administrador notificando del nuevo contacto.
EmailDeNuevoContacto( $post_id );
// También podríamos enviar un email de agradecimiento al contacto.
EmailDeBienvenida( $post_id );
}
add_action('acf/save_post', 'acf_guardar_despues', 20);
Conclusión
Yo no soy muy fanático de crear formularios de Frontend con ACF, pero es verdad que puede ayudar a mucha gente a resolver algún que otro tipo de solicitud. Si ese es tu caso, espero que este artículo te haya valido.
Si tienes alguna duda/mejora sobre el funcionamiento de este código déjame un comentario y con gusto le echaré un ojo.
Happy coding!
Mauricio