Blog personal de IT, viajes y otros hobbies

Etiqueta: acf

Crear formularios en frontend con ACF

Crear formularios en Frontend con ACF

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».

Resultado final de la carga de campos en ACF.

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>
Renderizado del formulario ACF en el Frontend de WordPress

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

Crear bloques de gutenberg con ACF

Crear bloques de Gutenberg con ACF

Seamos sinceros, Gutenberg ha venido para resolver muchos problemas técnicos y modernizar la forma en la que creamos contenido, pero para los desarrolladores ha sido un baldazo de agua fría por la cantidad de nuevas tecnologías que debíamos incorporar a nuestro ya sobrecargado kit de lenguajes de programación.

Pero que no cunda el pánico porque Elliot Condon y su equipo de desarrollo de ACF (Advanced Custom Fields) han implementado una nueva funcionalidad en su plugin que nos permite asignar un conjunto de campos a los nuevísimos bloques de Gutenberg.

Básicamente estos son los pasos que vamos a seguir para crear bloques personalizados de Gutenberg con ACF:

  • Registrar el bloque de Gutenberg
  • Crear los campos personalizados con el plugin ACF
  • Exportar los campos a JSON y PHP (opcional)
  • Crear el mockup del bloque (HTML y CSS)
  • Encolar los estilos en el administrador de WordPress

⚠️Disclaimer: Para seguir estos pasos vamos a necesitar descargar la versión ACF PRO 5.8.0 del plugin de pago de ACF. Tengo ya dos webs en producción y la versión Beta funciona de maravillas.


Bloque a desarrollar

A modo de ejemplo vamos a desarrollar un bloque que nos permita crear un conjunto de charlas, con sus respectivos ponentes, títulos, descripciones, etc. Más o menos algo así (no me critiquéis el diseño que como podéis ver soy pésimo):

Diseño bloque personalizado de Gutenberg con ACF
Diseño del bloque personalizado de Gutenberg con ACF

Primer paso: registrar el bloque de Gutenberg

En primer lugar tendremos que registrar el bloque de Gutenberg con los parámetros tal como lo haríamos con un bloque nativo. Para más opciones se puede consultar los pasos del Handbook.

<?php
/**
 * Registramos el bloque de Gutenberg para las charlas.
 */
function wcz_create_talk_gb_block() {
		// register a testimonial block
		acf_register_block( [
			'name'				=> 'talk',
			'title'				=> __( 'Talk', DOMAIN_NAME ),
			'description'		=> __('Block with basic info of the talk.', DOMAIN_NAME),
			'render_callback'	=> 'talk_block_render_callback',
			'mode'				=> 'auto',
			'icon'				=> 'image-filter',
			'keywords'			=> [ 'talk', 'quote' ],
			'enqueue_style'		=> get_template_directory_uri() . 'blocks/testimonial/testimonial.css',
		] );
}
add_action('acf/init', 'wcz_create_talk_gb_block');

Vamos a registrar el bloque utilizando la función acf_register_block() cuando se ejecuta el hook propio del plugin ACF llamado acf/init. Estos son los parámetros más importantes:

  • name: el bloque necesita un nombre sin mayúscula, acentos o caracteres especiales.
  • title: asignaremos un título que mostrará en el selector de bloques.
  • render_callback: nombre de la función que se encargará de renderizar el HTML.
  • icon: podemos elegir un icono del propio Dashicon de WordPress o bien pegar el código de un fichero svg.
  • mode: Con la opción auto el bloque se renderiza automáticamente cada vez que pierde el foco.
  • keywords: palabras claves para el filtro en el selector de bloques.
  • enqueue_style: podemos encolar un CSS con los estilos específicos para el bloque.

Crear campos personalizados en ACF

Una vez que tenemos el bloque de Gutenberg creado es hora de armar la estructura de datos. Para ellos vamos a crear un grupo de campos personalizados como siempre lo hemos hecho con ACF.

campos personalizados acf para bloque de gutenberg

Vamos a utilizar el campo «Title» para el encabezado de la sección y luego tenemos un campo «Repeater» que tiene otro conjunto de campo personalizados para cada «Ponencia»:

detalles de campo repeater acf para bloque gutenberg
  • Speaker avatar: campo para dar de alta la imagen del ponente.
  • Speaker name: campo de texto para el nombre del ponente.
  • Talk title: campo de texto para el título de la ponencia.
  • Talk description: campo textarea para la descripción de la ponencia.
  • Twitter account: campo de texto para el nombre de usuario de Twitter del ponente.

👉🏻Prestad atención a la estructura de nombres que asigno tanto al repetidor como a los campos hijos. De esta manera tenemos una nomenclatura simple y clara que agradeceremos cuando tengamos que implementar el frontend.


Una vez que tenemos todos los campos solo nos resta definir dónde queremos que se muestren dentro de todo el ecosistema de WordPress. Para ello elegiremos desde la sección «Ubicación» el tipo «Bloque» y luego seleccionamos el bloque «Talk» que hemos creado en el punto anterior.

Exportar los campos a JSON y PHP

Este es un paso opcional ya que no afecta al desarrollo como tal del bloque, pero lo aconsejo ya que nos permite:

  • tener la estructura de los campos en control de versiones (como GIT o BitBucket).
  • evitar consultas extras a base de datos.
  • facilitar el desarrollo web entre un equipo de programadores.

Para exportar los campos debemos seguis los siguientes pasos:

  1. Ir al menu Campos Personalizados » Herramientas
  2. Marcar el checkbox del campo que queremos exportar
  3. Hacer click en «Export File» (que nos descargará un fichero .json)
  4. Hacer click en «Generate PHP«. Nos redireccionará a una nueva página con el código PHP.
  5. El código PHP debemos incluirlo en alguna carpeta de nuestro proyecto y llamarlo desde el tema o plugin que estemos desarrolando.
  6. El fichero .json también debemos incluirlo en alguna carpeta del proyecto para posibles cambios a futuro.

Crear el mockup para el bloque (HTML & CSS)

Con el bloque y el conjunto de campos personalizados creados es hora de que pasemos al Frontend para «pintar» toda esta solución.

Solo debemos crear el HTML y el CSS en conjunto con las funciones habituales de ACF para mostrar los campos (get_field, the_field, get_sub_field, the_sub_field, etc).

Resumo parte del HTML para que el ejemplo no se haga muy engorroso, aunque sigue siendo igual de válido para explicar la idea:

<?php
/**
* Esta es la función que renderiza el bloque.
* Es la misma que declaramos cuando registramos el bloque de Gutenberg
* en el primer paso.
*/
function talks_block_render_callback( $block ) {
	// Recorrro en bucle todas las charlas dadas de alta en el backend.
	while ( have_rows('wcz_gb_talks') ) : the_row(); ?>
		<div class="talk">
			<div class="talk__meta">
				<h3 class="talk__h"><?php the_sub_field( 'wcz_gb_talk_title' ); ?></h3>
				<p class="talk__b"><?php the_sub_field( 'wcz_gb_talk_description' ); ?></p>
				<div class="talk__speaker">
					<p class="talk__speaker__h">Speaker:</p> <span><?php the_sub_field( 'wcz_gb_talk_speaker' ); ?></span><br>
				</div>
			</div><!-- END .talk__meta -->
		</div><!-- END .talk -->
	<?php endwhile; ?>
}

Resultado final

Si todo ha salido bien tendremos un nuevo bloque de Gutenberg en el editor al cual podemos asignar valores con campos personalizados y con estructura y estilos propios ¿Ha sido fácil, no?


Bola extra

Si lo prefieres puedes ver el vídeo con mi ponencia en la WordCamp Zaragoza 2019 donde explico el mismo proceso detallado en el artículo.

ACF Custom Database Tables – Tablas personalizadas para ACF

ACF Custom Database Tables – Tablas personalizadas para ACF

ACF Custom Database Tables es un plugin de pago (99,00$AUD) de la empresa Hookturn, que extiende ACF (Advanced Custom Fields) y que gestiona automáticamente los datos en tablas personalizadas. Con esta herramienta cada campo de ACF se transforma en una columna de una tabla. Sin dudas es una opción más que interesante para proyectos que tengan una gran carga de consulta de base de datos. Me puse en contacto con Aaron Rutley (co-creador del plugin) quien amablemente me cedió una licencia para que pudiera trastear y escribir esta review donde os detallaré por qué, cómo y cuándo se debe utilizar este plugin.

Hookturn
Hookturn es la empresa que está detrás de este plugin.

¿Por qué crear nuevas tablas?

Son varios los motivos por los que podríamos optar por guardar nuestros datos de WordPress en nuevas tablas, vamos a ver algunos de ellos en detalle:

Mayor seguridad

Al día de la fecha existen 55,214 plugins, donde muchos de ellos guardan sus configuraciones o datos en tablas como wp_options o wp_postmeta ¿Compartirías la información valiosa de tu negocio junto a la de otros plugins con posibles fallos de seguridad? En el caso de información muy sensible yo crearía una nueva tabla personalizada dónde con un nombre totalmente ajeno a la estructura por defecto de WordPress ya estaríamos más protegidos.

Estructura horizontal

WordPress debe su éxito a la estructura de crecimiento vertical conocida como key => value, aunque esta estructura dificulta muchas tareas como la creación de consultas complejas o extracción de datos. Este plugin crea tablas personalizadas de crecimiento horizontal (cada campo es una columna) permitiendo una mejor legibilidad, facilidad de exportación y búsquedas mucho más rápidas.

ejemplo crecimiento vertical y horizontal base de datos
Ejemplo de crecimiento horizontal y vertical en tablas de base de datos.

Operaciones más rápidas

Al guardar la información en tablas personalizadas hará que la escritura, recuperación y borrado de las mismas sean mucho más rápida. No es lo mismo buscar un registro único en una tabla personaliza a buscar entre cientos, miles o millones de registros compartidos con otras entidades (otros custom post types, menús, adjuntos, etc).

Mayor escalabilidad

Al tener la información separada permitirá que la escalabilidad de nuestro proyecto sea más optima. Si sabemos de antemano que un tipo de entidad puede tener millones de registros y/o que debemos realizar consultas SQL muy complejas sobre ellas, lo ideal es separarlo en una tabla personalizada para consumir la menor cantidad de recursos posibles del servidor (procesador, memoria, etc).

Ejemplo de uso

Obviamete que para probar el plugin he creado una pequeña estructura de información que me permitió ver y trastear el comportamiento en la base de datos. Para ello diseñé una estructura muy básica de Libros => Autores que podemos ver en el siguiente diagrama.

diagrama libro autor
Diagrama de Libro / Autor. Donde un libro puede tener uno o más autores.

Implementación:

  • Primero he creado los Custom Post Types «Libros» y «Autores».
  • He dado de alta los grupos de campos personalizados con ACF para cada Custom Post Type.
  • El plugin añade una nueva opción al formulario de ACF, dando la posibilidad a los desarrolladores de crear una tabla personalizada para cada grupo de campos.
acf custom datatables nueva opcion
Nueva opción para indicar la creación de una tabla personalizada. En la segunda opción podemos especificar el nombre.
  • Cuando guardamos los cambios de los campos personalizados aparecerá un nuevo mensaje como el siguiente:
nuevo mensaje custom datatables acf

El plugin generará un fichero JSON que se guardará en la carpeta de uploads. Este fichero contienen toda la información necesaria para crear la(s) tabla(s) en la base de datos. Este último proceso debe ser manual, ya que el usuario debe indicar explícitamente que es consciente que esta acción conlleva una modificación en la base de datos.

  • Al pinchar sobre el botón «Manage Database Tables» (Administrar las tablas de base de datos) nos llevará a una página de configuración con los siguientes datos:
cuadro de dialogo para crear modificar base de datos acf custom datatables
Cuadro de diálogo para aceptar la creación o modificación de la base de datos de nuestro WordPress.

El sistema nos indica que ha encontrado un JSON (el de libros en este caso) y que está listo para crear o modificar la base de datos. Para ello nos piden una verificación que he marcado con lineas punteadas en azul. En inglés indica «Entiendo que este proceso modificará mi base de datos y que he realizado una copia de seguridad en caso que tenga que deshacer los cambios«.

En cristiano lo que te están diciendo es que al modificar la base de datos se puede liar (aunque no debería) y que obviamente no se harán cargo ante cualquier problema que surja. Por ello mismo te recomiendo que siempre hagas pruebas en local y/o que realices una copia de seguridad de todo tu contenido.

  • Repetimos los pasos para la entidad «Autores» y ya tenemos las tablas personalizadas en nuestra base de datos.
custom datatables acf base de datos final
Estructura final de una de las tablas personalizadas.

Ahora ya podemos dar de alta nuestros dos registros. Primero el autor, ya que lo necesitaremos luego para seleccionarlo en la relación de la entidad «Libro».

alta de custom post types con acf
Alta de registros para ambos Custom Post Types con sus respectivos campos personalizados.

Y este es el resultado final en la tabla wp_libros.

resultado fila libro
Registro en la tabla wp_libros.

¿Qué hay de la compatibilidad?

No os preocupéis porque el plugin sigue generando un registro en la tabla wp_posts como así también las relaciones con su tabla wp_postmeta. Sí, el plugin duplica el contenido con el único fin de mantener la compatibilidad con el resto de los plugins que no saben absolutamente nada de la existencia de tablas personalizadas.

Pero hay buenas noticias, podemos desactivar la creación de los registros duplicados, mediante el uso de los filtros:

<?php
/*
 * Deshabilita la creación de valores meta en las tabla wp_postmeta
 */
add_filter( 'acfcdt/settings/store_acf_values_in_core_meta', '__return_false' );

Tablas de Relaciones

Se pueden crear tablas de relaciones a partir de campos específicos de ACF. Estos son los tipos de campos ACF de los cuales podemos crear tablas relacionadas:

  • Relación
  • Objeto Post
  • Taxonomía
  • Link de página
  • Usuario

Una vez seleccionado el campo de relación debemos agregar un pequeño filtro para que el plugin cree las nuevas tablas:

<?php
/*
 * Este código crea las tablas de relación para los campos del tipo relación en forma global. 
 */
add_filter( 'acfcdt/settings/enable_join_tables_globally', '__return_true' );

Al guardar los campos personalizados, podemos ver cómo aparece una nueva línea en el mensaje indicando la creación de la nueva tabla para la Relación entre ambas entidades:

tabla de relacion acf custom datatables

Y ahora sí podemos ver cómo queda finalmente el registro del libro en su nueva tabla de relación.

tabla relacion custom datatables acf

El post_id 50, el libro «Don Quijote de la Mancha» tiene como autor al autor 48 «Miguel de Cervantes». La columna _sort_order es utilizada por el propio plugin.

Limitaciones del plugin

El plugin de momento tiene limitaciones para implementar los campos:

  • Repetidor
  • Grupo
  • Contenido flexible
  • Clon

Estos son campos más complejos que estarán representados en sub-tablas en versiones posteriores del plugin.

Conclusión

Como aclaré al principio del artículo, este plugin es específico para proyectos que requieran de búsquedas complejas a base de datos. El hecho de realizarlas sobre tablas horizontales permitirá consultas SQL menos complejas y por ende un mejor tiempo de respuesta y un uso más efectivo de los recursos del servidor. El plugin permite muchas más configuraciones mediante código las cuales están muy bien documentadas.

Me resta aún aprender cómo abstraer toda esta configuración para incluirlo en plugins independientes. Si bien ACF tiene una funcionalidad local-JSON que crea ficheros JSON «on the fly», este lo realiza en una carpeta del tema activo, algo que no termina de agradarme del todo.

No uses el título para programar

¡No uses el título de tus páginas para programar!

Bendita profesión que día a día nos enseña a base de palos en la frente. Hoy me llama un cliente diciéndome que no veía cierta funcionalidad en su web. Luego de investigar un poco me doy cuenta que había cambiado el título y el slug de una de las páginas de WordPress, y ¡Zas! toda la programación de varios días que se va por el drenaje con un simple «actualizar página».

Plantilla page-slug de la jerarquía de plantillas

El decirle a nuestro cliente – La página debe llamarse «Atención al cliente», caso contrario el formulario no funcionará – no parece muy elegante. Utilizar este tipo de programación es limitar la libertad de carga de contenido de la web y un posible dolor de cabeza a futuro.

En mi día a día son pocos los elementos que puedo a atar a este tipo de información, entre ellos:

  • Conjuntos de campos de ACF y
  • Plantillas de temas de WordPress.

Posible solución

La única solución que se me viene a la mente es ofrecer distintas plantillas de páginas. De esta forma, el usuario podrá modificar el título y slug de las distintas páginas como así lo desee sin perder la relación con posibles campos de ACF o plantillas de WordPress.

Campos de ACF

Cuando des de alta campos de ACF solo debes cambiar la ubicación  por «Plantilla de página» y luego seleccionar el valor correspondiente.

acf ubicacion plantilla pagina

Plantillas de WordPress

No utilices la jerarquía de plantillas con el formato page-$slug.php o te verás envuelto en posibles problemas a futuro. En su lugar crea plantillas para utilizar con las páginas. Es relativamente simple: Solo debes crear un fichero en la carpeta de tu tema de WordPress con el nombre que desees (aunque es conveniente que utilices un nombre que facilite su comprensión como por ejemplo page-tpl-atencion-al-cliente.php) y luego poner este código en las primeras líneas.

<?php
/**
 * Template Name: Atención al cliente
 */

Con estas recomendaciones puedes quedarte tranquilo que tu funcionalidad no se verá afectado por la carga de datos de tus clientes.

agregar acf en archives

¿Cómo agregar campos personalizados ACF a las plantillas archives?

Es habitual que algunos proyectos tengan diseños muy específicos para las plantillas de archives para los que necesitaremos a veces crear campos personalizados. Pero ¿Dónde mostramos los campos en el administrador de WordPress para estos valores? Después de darle al coco un tiempo he llegado a una solución que considero bastante «elegante» y consiste en:

  1. Crear una subpágina en el menú administrador de WordPress.
  2. Identificar dicha subpágina como «página de opciones» de ACF.
  3. Crear los campos en ACF y especificar la página de opciones del punto 2.

Ejemplo

Para mostrar el código de los 3 pasos detallados anteriormente vamos a crear una solicitud de un proyecto de ejemplo:

  • Tenemos una web y una de sus páginas muestra el listado (archive) de empleados.
  • El cliente nos solicita agregar un texto descriptivo al listado de empleados.
  • Nos solicita también la posibilidad de cargar una imagen que irá cambiando año tras año.
archive custom post type campos personalizados acf
Diseño (muy básico credo por mí) para mostrar el ejemplo que nos solicita el cliente.

Solución

Si bien ACF nos permite crear páginas de opciones, las mismas las agrega al nivel cero del menú del administrador de WordPress. Es una opción válida aunque sería más interesante que dicha página esté bajo el menú del propio Custom Post Type, tal vez con el título de «Opciones». Vamos a ver paso a paso el código para implementar esta funcionalidad.

Crear la subpágina en el menú del Custom Post Type

ACF proporciona una función llamada acf_add_options_sub_page que nos permite crear una subpágina que podremos utilizar para agregarlos los campos utilizando este plugin.

<?php
// Create a submenu for the Archive Employee Options
if( function_exists('acf_add_options_sub_page') ) {
	acf_add_options_sub_page(array(
		'title'      => __('Opciones'),
		'parent'     => 'edit.php?post_type=employee',
		'capability' => 'manage_options'
	));
}

Esto nos dará como resultado el siguiente submenú y a su vez estará disponible en el plugin de ACF como una nueva página de opciones para agregar campos.

archive custom post type acf página de opciones

Crear los campos con ACF

Una vez que ya tenemos creada la subpágina ya podremos dar de alta los campos y asignarlos a la página de opciones 'opciones'.

supagina opciones acf custom post type

Resultado final

Como resultado final tendremos una página de opciones propiamente para este Custom Post Type. De esta manera el usuario no tendrá que estar saltando entre distintas secciones del administrador de WordPress para cargar los valores de una misma entidad ¿A que mola?

pagina opciones custom post type acf

Mostrar los campos en el Frontend

Un punto muy importante a saber es que estos valores van a guardarse en la tabla wp_options de WordPress. Podemos recuperarlos utilizando la función propia de WordPress get_option() o bien utilizando la función de ACF get_field() / the_field().

<php
// ALTERNATIVAS PARA RECUPERAR LOS VALORES
// Opción por defecto de WordPress
echo get_option('texto_descriptivo');
// Con la función get_field de ACF
$variable = get_field('texto_descriptivo', 'option'); 
/* 	Es obligatorio especificar el segundo parámetro
	con el valor 'option'. De esta manera estamos especificando
	a ACF que debe buscar ese valor en la tabla wp_options.
*/

// Con la función the_field de ACF (que hace un echo del valor)
the_field('texto_descriptivo', 'option')
/* 	Es obligatorio especificar el segundo parámetro
	con el valor 'option'. De esta manera estamos especificando
	a ACF que debe buscar ese valor en la tabla wp_options.
*/
WordCamp Madrid 2017 Mauricio Gelves Ponencia ACF

WordCamp Madrid 2017 – Mi ponencia sobre ACF (Advanced Custom Fields)

A pesar de haber estado en la organización de la WordCamp Madrid 2017, me hice un tiempo para prepararme una charla y de uno de los temas que más me apasiona: Campos Personalizados y con ACF (Advanced Custom Fields).

WordCamp: WordCamp Madrid 2017
Título: Boxeo de Campos personalizados: Metaboxes Vs ACF
Descripción: En la esquina azul con muchas líneas de código: el desarrollador de metaboxes de WordPress. Y en la esquina roja luchando bajo el lema “No reinventes la rueda”: el desarrollador que usa el plugin ACF.
Ven a este encuentro pugilístico para ver las habilidades y debilidades de cada uno de los contrincantes y decide tú mismo quién será el ganador para tu proyecto web.
Presentaciónhttps://maugelves.com/wp-content/uploads/2017/04/mauricio-gelves-boxeo-de-campos-personalizados.pdf

acf active custom fields

Campos personalizados en WordPress con ACF

Una de las cosas que más me gusta de ser informático es interiorizarme y captar conocimientos de los distintos tipos de negocios de mis clientes. Ellos me contactan y, como si estuvieran en un consultorio de psicología, me van detallando cómo funciona su circuito de información, lo que necesitan para acrecentar sus ventas, cómo buscan agilizar sus procesos o simplemente cómo quieren tener presencia en internet. Mientras los escucho voy generando una posible solución en mi cabeza: entidades, campos, relaciones y desde hace algunos años cómo implementar todo esto con WordPress.  En la mayoría de los casos los campos que ofrece WordPress por defecto en su tabla wp_post (título, descripción, fecha de alta, estado, etc) no son suficientes para brindar una buena solución. Es por eso que necesitamos extender la tabla wp_posts con nuevos campos personalizados y para ello utilizaremos un plugin llamado «ACF» (Advanced Custom Fields) el cual explicaré a continuación.

Logo de ACF Advanced Custom Fields
Al 19/03/2016 ACF tiene más de 1.000.000 de descargas activas.

Este plugin fue creado por el australiano Elliot Condon y en su versión PRO (unos €17)  nos permite agregar una gran variedad de campos que nos facilita enormemente el desarrollo de cualquier solución WordPress:

  • Campos básicos:
    • Texto, textarea, número, email, password.
  • Campos de contenido:
    • Editor WYSIWYG, imagen, archivo.
  • Campos Selectores:
    • Select, checkbox, true / false, radio.
  • Campos relacionales:
    • Link de página, post object, relación, taxonomy, user.
  • Campos jQuery:
    • Google Map, selector de fecha, selector de color.
  • Campos de Layout:
    • Mensaje, tab.
  • Campos PRO:
    • Repeater, gallery, options page, flexible content.

¿Cómo aplicar estos campos en un caso real?

Para mostrar la utilización de este plugin vamos a desarrollar un tema para una supuesta concesionaria de coches.

El dueño de la concesionaria nos pide una web en la que necesita mostrar sus datos institucionales, un formulario de contacto y un listado de los coches actuales en venta.

Indago un poco más sobre este listado para saber qué campos necesitamos agregar a esta nueva entidad «coche». El cliente nos cuenta que quiere indicar la marca, el modelo, el año de fabricación, una fotografía, una descripción de sus características y una casilla para indicar si se vendió y en qué fecha.

Luego de hacer el análisis de lo que necesita el cliente podemos esbozar un diagrama para plasmar una solución con WordPress:

Diagrama con campos ACF

Una vez encontrada la solución es hora de marcar prioridades  y desarrollar el código necesario:

  1. Generamos el Custom Post Type «Coche» tal como hemos visto en el artículo wp_post el corazón de WordPress.
  2. Registraremos para la entidad «coche» un taxonomía a la que llamaremos «modelos» utilizando la función register_taxonomy. Esta taxonomía tendrá como padre las marcas y como hijos los modelos propiamente.
  3. Generamos los campos personalizados con ACF los cuales veremos cómo implementar a continuación.

Creando los campos del Custom Post Type «Coche»

Para los campos «titulo» y «descripcion» utilizaremos las columnas post_title y post_content de la tabla wp_post. Para la fotografía usaremos la funcionalidad Post Thumbnails propia de los posts. Para el resto generaremos los campos con el plugin ACF. En primer lugar debemos generar un nuevo conjunto de campos al que llamaremos «CPT Coche».

Formulario para generar un nuevo grupo de campos ACF.

Luego damos de alta los campos con sus respectivos atributos:

  • Año de fabricación:
    • Field Label: Año de fabricación
    • Field Name: anio_de_fabricacion (atentos a no dejar ‘ñ’ ni acentos en este campo)
    • Field Type: number
    • Field Instructions: Indique el año de fabricación del coche
    • Required: Yes
    • Step Size: 1
  • ¿Está vendido?:
    • Field Label: ¿Está vendido?
    • Field Name: esta_vendido
    • Field Type: True / False
    • Field Instructions: ¿Se ha vendido el coche?
  • Fecha de Venta:
    • Field Label: Fecha de venta
    • Field Name: fecha_de_venta
    • Field Type: Date Picker
    • Field Instructions: Indique la fecha de venta del coche
    • Conditional Logic: Yes – ¿Está vendido? – is equal to – checked
      • Este campo solo se mostrará si el campo ¿Está vendido? está marcado como verdadero.
ACF Coche grupo de campos
Resultado final de la configuración de los campos personalizados.

Una vez generado los campos debemos indicar quién va a hacer uso de los mismos. El plugin nos permite asociarlo a un gran conjunto de entidades de WordPress: tipo de post, rol de usuario logueado, categoría de post, una determinada página, etc.
En nuestro caso debemos asociar el conjunto de campos al post type «Coche».

ACF Location fields

Eso es todo, al hacer click en «Publicar» tendremos nuestros grupo de campos asociado a nuestra entidad «Coche».

Vale aclarar que estas configuraciones se guardan en nuestra base de datos, en artículos posteriores explicaré cómo podemos utilizar la herramienta de exportación para generar el código PHP e incluirlo en el versionado del proyecto.

Podemos comprobar los campos generados dando de alta un nuevo coche en el administrador de WordPress.

ford mustang coche admin

Como podemos ver, aparte de los campos título y descripción propios de un post de WordPress tenemos los otros dos campos de ACF: «Año de Fabricación» y «¿Está vendido?». Y si seleccionamos el campo «¿Está vendido?» aparecerá el campo «Fecha de venta» tal como hemos especificado en sus condiciones lógicas.

campo esta vendido acf
campo jquery datepicker
Al seleccionar el campo «Fecha de venta» se despliega el DatePicker de jQuery para que podamos ingresar el valor.

Aplicando código para el Frontend

Ya tenemos nuestro primer «Coche» publicado con todos sus datos, ahora debemos escribir algo de código PHP para mostrar esta información en el frontend. En la plantilla single-coche.php usaremos las funciones get_field y the_field del plugin ACF.

<?php 
the_field('<nombre del campo>'); // Esta función imprime el valor del campo 
$variable = get_field('<nombre del campo>'); // Esta función obtiene el valor del campo 
?>
<?php get_header(); ?>
<?php if(have_posts()){ the_post(); ?>
	<p>Título del post: <?php the_title(); ?></p>
	<p><?php the_post_thumbnail('medium'); ?></p>
	Descripción del coche: <?php the_content(); ?>
	<?php
		$anioFabricacion = get_field('anio_de_fabricacion'); // Obtengo el campo y lo guardo en una variable
		if($anioFabricacion): // Si existe el campo y tiene un valor asignado...
	?>
	<p>Año de Fabricación: <?php echo $anioFabricacion; ?></p>
	<?php endif; ?>
	<?php
		$estaVendido = get_field('esta_vendido'); // Obtengo el campo y lo guardo en una variable
		if($estaVendido): // Si el campo es true entonces el coche está vendido.
			$fechaVendido = date_create_from_format('Ymd',get_field('fecha_de_venta')); // Obtengo el campo de fecha de venta y lo asigno a una variable.
	?>
	Estado: <span style="color:red">Vendido el día <?php echo $fechaVendido->format('d/m/Y'); ?></span> <!-- Doy formato a la fecha -->
	<?php }; //endif ?>
<?php endif; ?>
<?php get_footer(); ?>

Resultado

Y en el frontend obtenemos el siguiente resultado:

ACF coches frontend

Conclusión

Como pueden ver el proceso para crear campos personalizados es muy simple. Basta con tener bien claro las necesidades del proyecto, plasmarlo en un diagrama, configurar los campos y aplicar las funciones PHP en la maqueta del tema que estemos desarrollando. Este fue un ejemplo con campos muy simples pero como hemos visto la lista de posibilidades es muy amplia. Por fortuna su página web tiene una documentación muy completa de cada uno de ellos y en la que a veces se acompaña con videotutoriales. En artículos posteriores veremos cómo implementar estos y algunos campos más complejos pero en lugar de configurarlos en base de datos los desarrollaremos usando código PHP.

Imagen de cabecera: Emilio Küffer

Funciona con WordPress & Tema de Anders Norén