Después de un par de años, mi post sobre cómo utilizar API REST externas en WordPress sigue siendo visitada. Sin embargo, algunas personas me han contactado para pedirme consejos sobre el manejo de los datos.
Problemas al usar API REST externas en WordPress
He detectado que algunos desarrolladores, después de implementar algunas API REST externas en WordPress, éste se ve afectado en cuanto a performance.
Otros no saben dónde poner su código, si en el archivo functions.php o en un plugin. ¿Cuál es mejor?
A continuación te daré un par de consejos al momento de desarrollar e integrar una API REST en WordPress.
Consejo #1. Cachea los resultados
Después de implementar tu API REST en WordPress, se ejecutará una petición cada vez que se recargue la página.
Quiere decir que tu página tendrá que esperar (o no muestre nada) hasta que la petición haya terminado, originando los siguientes problemas:
Un tiempo de carga muy lento. Tal vez afecte el SEO.
Más uso de recursos de tu servidor y posiblemente el servidor de la API REST.
La solución será cachear/guardar los resultados de la petición en nuestra base de datos, para que la próxima vez que se requieran no vuelva a ejecutarse otra petición remota.
Un diagrama de flujo puede ayudar a la explicación:
El código anterior guardará los personajes de la serie Rick & Morty en la base de datos de WordPress haciendo una petición a la API REST cuando la acción wp_loaded sea llamada. La segunda vez que se intente hacer la petición, ésta no se hará porque los datos ya existen.
Consejo #2. Usar una acción para actualizar los resultados
Imagina que los resultados de la API REST ya están guardados en tu base de datos, pero digamos que uno de los datos que guardaste ya cambió en todo este tiempo.
Sí puedes ir a borrar el campo que guarda los datos en tu base de datos, pero eso no es para nada óptimo, no harás esto cada vez que haya un cambio, ¿o si?
Lo más sano y seguro es agregar un botón o cualquier otro tipo de acción (acorde a tus requerimientos) para actualizar estos datos.
Una acción puede ser un click, un evento scroll e incluso un evento periódico (cron job). Cualquier acción que tú como administrador o simple usuario pueda ejecutar.
Por ejemplo, para actualizar los datos al momento de dar click en un botón usando AJAX, la lógica sería de la siguiente forma:
Hacemos uso de la acción wp_ajax_{action}, la cual ejecutará la acción AJAX desde un click o scroll, algo que ejecute el AJAX request. Después hacemos las validaciones necesarias y si todo está bien, hacemos una petición a la API REST y actualizamos los datos.
Lo anterior es algo complicado para desarrolladores nuevos, pero en la web hay mucha información sobre cómo trabajar con AJAX; aquí te dejo unos recursos:
Y de vez en cuando, el servicio REST podría no estar funcionando y tal vez retorne distintos errores como, 401, 500, etc. En este caso no podríamos procesar los datos que queremos.
Para verificar el código HTTP se hace de la siguiente manera:
Si alguna validación anterior ocurre, el código principal ya no se ejecutará, evitando así posibles errores.
También puedes agregar validaciones extras, acorde a tus requerimientos, por ejemplo, si el HTTP es 200 pero solo quieres guardar los datos si el primer resultado equivale a un cierto valor.
Consejo #4. No guardes datos que no necesitas
Ten en cuenta que algunas API REST devuelven algunos meta datos, como la página actual, fechas de actualización, etc.
Hay que ser inteligentes al momento de manejar datos, ¿necesitas almacenar esos meta datos?
El guardar datos que no necesitas solo incrementará innecesariamente la base de datos.
Si en realidad necesitas los datos del campo info, entonces guardalos, si no, no los guardes.
Con el código puedes acceder fácilmente a los datos usando arreglos (arrays):
Copy
$results =wp_remote_retrieve_body( $response );$results =json_decode( $results, true );$results = $results['results']; // Contiene la información que queremos.$info = $results['info']; // Contiene información no valiosa.update_option( 'rick_and_morty_cached_results', $results, 'no' );
Consejo #5. Desarrolla con plugins no con temas
Al inicio es muy común desarrollar dentro del archivo functions.php, el cual es el archivo principal de ejecución de funciones extras del tema activo.
Trabajar ahi está bien para funciones internas del tema activo, sin embargo, cuando uno va agregar una funcionalidad extra al sitio web del cliente, no debes trabajar directamente en él.
En el caso de una funcionalidad como integrar una API REST u otra funcionalidad debes trabajar en:
Temas hijos.
Plugins.
Los temas hijos son una opción, pero siguen siendo atenidos al tema activo padre. Esto está bien si el cliente nunca va cambiar el tema.
Por otra parte, lo que yo recomiendo es desarrollar un plugin, de esta manera el plugin siempre quedará activo a pesar de cambiar/desactivar el tema actual. Mantiene su funcionalidad.
Conclusión
Cada uno de los consejos trabajan en conjunto y separado, y en lo personal, deben aplicarse siempre que uno trabaje con API REST.
Quedará de ti y tus requerimientos el implementar uno de estos consejos u otros que se te ocurran.
¿Crees que me faltó algún consejo? ¿Cuál agregarías?
Tinkerwell es un editor de código para Laravel pero también funciona con WordPress. Ya no tendrás que adivinar el resultado de tus funciones en WordPress.
En ocasiones, un desarrollador quiere probar su código JavaScript o PHP antes de correrlo en el navegador. Este proceso es tedioso para PHP cuando queremos probar código complejo.
En JavaScript es fácil abrir la consola del navegador y hacer un par de pruebas de tu código. Sin embargo, en PHP las cosas se complican.
Una de las clásicas opciones para ver el resultado de un script en PHP son:
Crear un archivo PHP y ejecutarlo desde la terminal.
Abrir un sitio como implode.io y ejecutar tu código.
En mi opinión, las opciones anteriores funcionan para scripts sencillos. Pero ¿qué me dices cuando trabajas con un framework como WordPress? Incluyen más configuración y procesamiento para realizar una tarea.
El problema con WordPress
WordPress suele ser frustrante en cuanto a desarrollo. De vez en cuando tienes que probar el resultado de ciertas functiones internas de WP y no quieres hacer un var_dump() en tu archivo functions.php para saber ese resultado.
Por ejemplo, tenemos la función get_plugins() la cual nos permite ver los plugins instalados en nuestro WordPress. O incluso la función wp_nav_menu() para ver el HTML de nuestro menú.
Son de ese tipo de funciones que necesitas saber cómo se ve el resultado antes de poder manipularlos. Así que necesitamos hacer más fácil este proceso.
Tinkerwell, un editor de código mágico
La anterior problemática cambió con un programa llamado Tinkerwell, el cual es un editor de código donde solo lo abres, escribes tu código PHP, ejecutas y ves el resultado. Tanto en local como conexiones remotas.
Originalmente está creado para ser usado con Laravel pero han ido creando, a lo que ellos llaman, “drivers” para usarlo con otras plataformas como WordPress, Drupal y entre otras.
Puedes ver la lista completa de drivers en GitHub.
Configurando Tinkerwell con WordPress
Tinkerwell nos permite abrir un directorio con una instalación WordPress. El punto más importante es que ese directorio tenga, obligatoriamente, el archivo wp-load.php.
Yo ya tengo una instalación WordPress configurada con WAMP, así que todos esos archivos de configuración están en esta ruta de mi computadora:
Copy
D:\Programas\wamp64\www\wordpress
¡Ojo! Los servicios de PHP, MySQL y Apache (o tu stack preferido) ya deben estar encendidos.
Ahora si, en Tinkerwell damos click en el ícono de la carpeta o CTRL+O para seleccionar nuestro directorio WordPress.
La acción anterior debe de poner el entorno de trabajo en tu instalación WordPress.
Para confirmar, dentro del editor escribe la función home_url() y aprieta CTRL+R o click en el botón de play.
Si la configuración es correcta, deberías ver el enlace de tu sitio WordPress.
Probando funciones de WordPress
Este post pudo haber terminar en el párrafo anterior; sin embargo, quiero enseñarte unas funcionalides extras de Tinkerwell que pueden ser muy prácticas al momento de desarrollar en WordPress.
Caso 1: Obteniendo posts en específico
Imagina que estás desarrollando un plugin donde tienes que mostrar ciertos posts con las siguientes características:
Deben pertenecer a la categoría “Programación” (el ID de la categoría es 4).
Para lograrlo debemos usar la función get_posts() con ciertos argumentos:
Aquí es donde te preguntas, ¿será que el resultado de mi función sea el esperado? Usemos Tinkerwell para verificar.
Sabremos si el resultado es correcto si los posts dentro de la categoría “Programación” se asemejan con los resultados en Tinkerwell.
Te invito a probar la misma función pero con diferentes argumentos, por ejemplo, obtener posts de una fecha en particular.
Caso 2: Cambiando la URL usando filtros (hooks)
Por si fuera poco, también podemos ver con anticipación cómo se verán los resultados que son cambiados por los filtros (filter hooks).
Un cliente te ha pedido que debes cambiar el resultado de la función home_url() bajo la condición de que si la URL actual es HTTP, la URL cambie a otro dominio.
De entrada, el resultado de la función retorna el siguiente resultado:
Ahora agregamos el filtro con el siguiente código, donde decimos que si la URL no es HTTPS deberá cambiar el valor por https://roelmagdaleno.com.
¡Ojo! Debes llamar el filtro antes de llamar a la función principal para que este pueda ser aplicado antes de enviar el resultado final.
El resultado en Tinkerwell es aplicado correctamente.
Caso 3: Viendo resultados de shortcodes
Ahora estás trabajando con un shortcode, pero necesitas ver el resultado generado (comúnmente HTML). Digamos que el shortcode pertenece al plugin Contact Form 7.
do_shortcode( '[contact-form-7 id="50" title="Contact form 1"]' );
Y si lo ejecutas en Tinkerwell, obtienes el HTML generado por el shortcode. De esta forma puedes ver lo que tu página renderizará al momento de llamar el shortcode.
Dentro de este archivo tienes la constante DB_HOST que originalmente su valor es localhost; si ejecutas Tinkerwell, este lanzará un error de conexión a la base de datos.
Para solucionar esto, el valor correcto de la constante deberá ser localhost:<DB_PORT>, es decir, tenemos que especificar el puerto donde está escuchando la base de datos:
Copy
define( 'DB_HOST', 'localhost:10047' );
El puerto de la base de datos lo consigues dentro de la pestaña DATABASE del programa Local.
Después de agregar este cambio, reinicia el sitio, has una prueba en Tinkerwell y no deberá haber ningún error.
Dentro de tu carrito de compras tienes integrado preferencias de MercadoPago para el manejo de todas las compras de tus usuarios con cualquier método o tipo de pago.
Sin embargo, tú o tu jefe, deciden agregar un nuevo requerimiento al carrito de compras. Ahora necesitan excluir los métodos o tipos de pagos de todas las nuevas preferencias de MercadoPago.
Digamos que el requerimiento dice que los pagos en efectivo con OXXO y las transferencias SPEI sean excluidos de las nuevas preferencias de MercadoPago.
¿Es posible? Claro que sí.
En este tutorial te mostraré cómo excluir los métodos y tipos de pagos de las preferencias de MercadoPago.
Antes de empezar necesitamos claves de integración
Para seguir con las siguientes secciones, necesitas una Public Key y un Access Token, los cuales consigues creando una integración en MercadoPago.
Si te fijas bien, la URL acepta el parámetro public_key. Sirve para autenticar la petición. La public_key lo obtienes en tu panel de desarrollador de MercadoPago.
Cuando ejecutas la petición debes recibir un JSON de respuesta con múltiples valores.
Con el JSON anterior encontrarás información de los métodos de pago. Para México se muestran los siguientes:
Visa Débito – debvisa
Mastercard Débito – debmaster
American Express – amex
Visa – visa
Mastercard – master
Citibanamex – banamex
OXXO – oxxo
BBVA Bancomer – bancomer
Obtener los tipos de pago de MercadoPago
Los tipos de pago sirven para identificar si queremos hacer cobros con tarjeta de débito/crédito, efectivo, tarjeta de prepago, entre otros.
Estos tipos de pago son encontrados dentro de la misma respuesta JSON que obtuviste en la petición anterior. Específicamente, la propiedad payment_type_id.
Estos son los tipos de pago y sus ids encontrados en la petición:
ATM – atm
Tarjeta de crédito – credit_card
Tarjeta de débito – debit_card
Ticket – ticket
Transferencia bancaria – bank_transfer
Excluir métodos o tipos de pago de una preferencia de MercadoPago
La siguiente sección solo funciona con preferencias de MercadoPago.
Para crear una preferencia de MercadoPago usando su API, debemos seguir la documentación.
La petición que haremos será de tipo POST al siguiente enlace:
Copy
https://api.mercadopago.com/checkout/preferences
Debemos estar autenticados con nuestro Bearer Token pasándole un header de autenticación:
Y debemos pasar datos obligatorios para crear la preferencia.
Dentro de la documentación, busca la propiedad payment_methods, la cual es una propiedad para excluir métodos o tipos de pago y también para poner un método de pago por default.
La propiedad payment_methods acepta las propiedades excluded_payment_methods y excluded_payment_types. Estos son arreglos y dentro de estos irán objetos con los ids de los métodos y tipos de pago, respectivamente.
Si estamos creando una preferencia y estamos excluyendo los métodos de pago oxxo y bancomer y los tipos de pago bank_transfer. El JSON a pasar a la petición debe verse de esta forma:
Recuerda que los ids de los métodos y tipos de pago se consiguieron anteriormente.
El resultado del POST anterior será un JSON y te mostrará la información de la preferencia.
Métodos y tipos de pago excluidos de la preferencia de MercadoPago
Una vez creada la preferencia, la respuesta JSON tendrá las propiedades init_point y sandbox_init_point. Estos son los enlaces para enviar a tus clientes y puedan comprar.
La propiedad sandbox_init_point es para pruebas. Entonces, si vamos a este enlace:
Primero verás que no sale la opción “Transferencia SPEI”. Y si seleccionas “Efectivo”, en la siguiente ventana la opción para pagar con OXXO no estará.
Y así es como excluyes métodos y tipos de pago en MercadoPago.
Si tienes problemas o dudas, no dudes en comentar.
Hace un año empecé a leer sobre cómo desarrollar un Messenger Bot de Facebook; claro, sin ver nada de inteligencia artificial y esas cosas, algo sencillo.
Actualmente desarrollo plugins para WordPress, y recién me topé con algo que nunca había pensado: “Enviar peticiones AJAX antes de que el usuario cierre nuestra página web“.
Antes de empezar este post, dejemos claro dos cosas:
Lo que veremos a continuación será completamente JavaScript.
El problema anterior puede ser enfocado a cualquier tipo de aplicación web, no solo para WordPress.
Indagué por la web
La mayoría de las respuestas a mi problema provenían de StackOverflow, y mi sorpresa fue que, no soy el único buscando lo mismo.
Hasta hace unos años, varias personas recomendaban usar el siguiente método:
Realizar peticiones síncronas.
El problema es que esto provoca que el navegador o la pestaña tarden un poco en cerrar, debido a que la petición aún se sigue ejecutando.
Sin embargo, en años más recientes, hubo una persona que comentó dos palabras:
Beacon API
¡Ésta es la solución! Me dije.
¿Por qué? Pues, se veía sencillo de usar y su documentación decía lo que yo quería hacer en ese momento. Y lo logré.
La Beacon API es usada para realizar peticiones asíncronas y no bloqueables a un servidor web. Aborda las necesidades de ejecutar código que intenta enviar datos al servidor web antes de que el documento se cierre.
La documentación lo explica sencillo, y el código mucho más; pero antes de seguir, me gustaría explicar que es una petición AJAX.
¿Qué es una petición AJAX?
Al principio de mi carrera, el hacer uso de algo llamado AJAX en mis desarrollos, era algo tenebroso. Tal vez para ti, mi querido lector, también lo fue.
¡No le tengas miedo! De hecho, creo que fue una de las mejores cosas que pude haber conocido, y lo mejor que le pasó a la web.
AJAX significa JavaScript Asíncrono y XML, y nos sirve prácticamente para:
Obtener datos de un servidor web sin recargar la página.
Enviar datos a nuestro servidor sin que el usuario se vea interrumpido.
Hacer uso de AJAX hoy en día es totalmente normal, y lo puedes implementar con varias tecnologías, ya sea usando VanillaJS, jQuery u otros.
A continuación, te dejo un video de Platzi para una mejor comprensión del tema:
Compatibilidad
Antes de empezar a trabajar con la Beacon API, hay que tener en cuenta que, en este año 2018, esta API es compatible en la mayoría de los navegadores, a excepción de Internet Explorer y Opera Mini:
Usando la Beacon API
Pero volvemos al principio del problema:
Enviar peticiones AJAX antes de que el usuario cierre nuestra página web.
La Beacon API nos provee la siguiente función:
Copy
navigator.sendBeacon( url, data );
Esta función nos permite enviar los datos que queremos transmitir a nuestro servidor antes de cerrar nuestra página.
Acepta dos parámetros:
Parámetro
Descripción
url
Ésta será la URL a donde queremos transmitir los datos.
data
Este es una variable que contendrá los datos a enviar en la petición.
Cabe destacar que, el tipo de la variable a enviar debe ser:
Primero, tenemos que hacer una instancia de FormData, ó cualquier tipo de variable que mencionamos anteriormente, y agregar los datos que queremos enviar a nuestro servidor.
Puedes hacer cualquier operación antes de enviar los datos, por ejemplo, yo en el código digo que si mi variable currentTasks está vacío, no envíe nada al servidor.
Ya que la lógica esté lista, pasamos los respectivos parámetros a navigator.sendBeacon( url, data ) y manejamos esos datos en nuestro servidor.
Inconvenientes
El uso de la Beacon API es impresionante, cumple con nuestros objetivos al querer enviar datos al servidor cuando la página se haya cerrado; sin embargo, existe un inconveniente.
Si queremos implementar la Beacon API, dijimos que tenemos que ejecutarlo en el evento unload, ¿verdad?
Sin embargo, este evento se ejecuta no sólo cuando la página es cerrada, si no que también se ejecuta cuando el usuario recarga la página, o cuando el usuario cambia de página dentro del mismo dominio.
Tal vez sea un inconveniente o no, depende del tipo de proyecto que estés desarrollando.
Posible solución a los inconvenientes
Como dije, la Beacon API tendrá sus inconvenientes o no, dependiendo del tipo de proyecto que estés desarrollando, por ejemplo, si quieres enviar datos estadísticos de las partes donde navegan tus usuarios, éste método es perfecto.
Pero si andas buscando algo que únicamente se ejecute al cerrar la página, tal vez tengas que usar algo parecido al Heartbeat API de WordPress, para que tu servidor se comunique si el usuario sigue en tu página o no.
Conclusión
La verdad es que, el uso de la Beacon API me ha salvado de implementar demasiado código en el proyecto que estaba desarrollando, y espero que te pueda servir a ti también.
Sin embargo, el uso del evento unload, es algo que debe mejorarse para solucionar los inconvenientes que previamente mencionamos.
¿No te ha funcionado la implementación del código? Deja un comentario y con gusto te apoyo.
Estaba programando una función en JavaScript, y la tenía que mandar a llamar en otros archivos, sin embargo, me di cuenta que cada vez que llamaba a esa función, era difícil acordarme de los parámetros.
Empezamos a programar sin saber las buenas prácticas, y así lo hacemos durante mucho tiempo, pensando que nuestro código es de calidad.
Pero no te preocupes, es algo que le pasa hasta los programadores más avanzados.
¿Qué son los parámetros?
Los parámetros, o también conocidos como argumentos, son los que están a la espera de obtener un valor desde donde se llame la función que las contiene.
Sí, son esas palabras que van dentro de los paréntesis de una función:
Es difícil recordar el tipo de dato que espera cada parámetro.
También es complicado recordar el orden de los mismos.
Los puntos anteriores solo te quitarán tiempo, tiempo valioso que podrías usar para programar, y tu código no será de calidad.
¡No hagas lo que yo hice!
Sólo usa 3 o 4 parámetros
Un día estaba leyendo el libro JavaScript: The Good Parts, y encontré una buena práctica, ésta decía que usar más de 3 o 4 parámetros en una función era una mala práctica.
Y la solución que presentaba el autor, era que si necesitabas usar más de 3 o 4 parámetros, éstos los pasaras a través de un objeto; es decir:
Es más legible, ¿no crees? De 8 parámetros, ahora tenemos 2.
Pero, ¡Ojo!, no porque yo esté usando JavaScript aquí, no significa que no funcione en otros lenguajes de programación. 😉
¿Qué ventajas obtienes?
Darle este tipo de soluciones a tu código, representa un gran avance a tu código, estás escribiendo código de calidad.
Además, te está aportando lo siguiente:
Código más legible.
El código se vuelve más corto.
Y ya no tenemos que acordarnos del orden de los parámetros.
¡Esto es lo que deberías estar haciendo en cada uno de tus desarrollos!
Uno de tantos code smells
El problema anterior es clasificado como un “code smell” (hediondez del código), y éste termino se refiere a que una parte del código tiene alguna deficiencia y que a la larga, ralentizará el sistema que estás desarrollando.
¿Quieres ver la cantidad de code smells que existen? Los puedes encontrar en este enlace.
Si te pones a solucionar todos estos code smells, no solo estás “solucionando”, si no que estarás “refactorizando“, y te sentirás como el Refactor Man:
El término “refactorización” no significa agregar código nuevo, se refiere a mejorar tu código, convertir ese código revuelto a código simple.
Tras ver todo esto, ¿estás decidido a programar código de calidad?
Referencias
Douglas Crockford. (2008). Chapter 5: Inheritance. Object Specifiers. JavaScript: The Good Parts. (p. 50).
Cuando estás aprendiendo a programar, solo piensas en aprender las sintaxis del lenguaje de programación, funciones, propiedades, etc, pero creo que nadie nunca ha pensado en escoger la tipografía correcta desde un principio.
Y no digo que esté mal, si no que, nosotros los programadores, pasamos la mayor parte del tiempo leyendo código que escribiéndolo; por lo tanto, debemos tener una tipografía que sea completamente legible. Una tipografía que no nos canse la vista.
Otro factor a tomar en cuenta al momento de programar, es el nombramiento, el cual te lo explico en este post.
¿Qué es una tipografía?
También conocidas como las fuentes o tipos de letras que están instaladas dentro de nuestra computadora; claro, hablando a nivel de informática.
Sabemos de ellas gracias a las herramientas de ofimática, como Microsoft Office Word, Google Docs, etc; y por lo regular, éstas herramientas solo contienen las tipografías por default del sistema operativo donde estemos.
Sin embargo, podemos descargar e instalar tipografías de terceros en nuestra computadora, a continuación una lista de sitios web para descargar tipografías de cualquier tipo:
No cualquier tipografía debería utilizarse para programar. Las tipografías que deberías usar en tu editor de texto, deben:
Ser legibles.
Tener caracteres distinguibles. Por ejemplo: Que el 1 (uno) sea distinto que la l (ele). Tal vez aquí se vea igual, pero, ¿entiendes el punto, verdad?
Los caracteres deben tener buen espacio entre cada uno.
Tengan disponibles caracteres especiales, como “<>$&/?=”, etc. Esos caracteres que a veces necesitamos para realizar alguna comparación u operación.
Mi recomendación
He probado distintas tipografías a lo largo de mi carrera como programador, y las siguientes tipografías que les voy a mostrar me han ayudado mucho al momento de programar, y esas son:
Aparentemente se ven igual, pero no, hay ligeros cambios entre ciertas letras, por ejemplo, la letra “g”.
Tu vista no se cansará si usas al menos una de esas tres tipografías que he mencionado.
Conclusión
Como dije anteriormente, los comentarios que aquí he expresado son de mi humilde opinión, no te estoy obligando a usarlas.
Si tú programas con otro tipo de tipografía y te sientes a gusto con ella, quédate con ella; pero recuerda, el probar no cuesta nada.
Y dime, ¿usas alguna otra fuente que no haya mencionado y estás orgulloso de ella? Compártela en los comentarios para que los demás podamos probarla. 🙂
Probablemente seas nuevo en el mundo de la programación y estés leyendo un libro, tutorial o guía sobre programación; desde ese momento, ¿qué es lo que haces? Estás leyendo en vez de estar escribiendo. Por lo tanto, es muy importante que el nombramiento de las cosas que otros programadores y tú escriban, estén bien escritas.
Y cuando digo “cosas“, me refiero a tus variables, funciones, parámetros e incluso comentarios. Éstos deben ser legibles y dar a entender lo que está haciendo la variable o función, si no lo son, perderás mucho tiempo leyendo el código.
El problema del mal nombramiento de las cosas
Si el nombramiento de las cosas no son legibles y mucho menos entendibles, te podrás ver afectado a futuro. A continuación, te muestro los puntos que probablemente enfrentarás si no nombras bien las cosas.
Tu código no:
Será legible.
Podrá ser entendido ni por ti, ni por otros programadores.
Será escalable; es decir, se te dificultará agregar y/o actualizar el código.
Y la peor de todas, tal vez te tengas que ver obligado a cambiar todo el código.
Escribe tu código en inglés
¿Inglés? ¡Estás loco Roel, no me llevo con eso!
No estoy loco, solo que mayormente la documentación de las librerías y frameworks están escritas en inglés; pocas veces se encuentra en español.
Además, nunca sabes quién leerá tu código.
Por ejemplo: Estás en una empresa escribiendo tu código en español, pero el administrador del proyecto te dice que necesita que le envíes tu código a su amigo americano. ¡Huy, problemas!
Le comentas la situación al administrador del proyecto, y lamentablemente te dice que escribas tu código en inglés. ¡Tristeza! Tienes que volver a escribir el código.
¿Ya ves? Tu código lo podría leer alguien en la India, Estados Unidos, Dinamarca, etc.
No programes para ti, programa para los demás
Te pongo un ejemplo; tu has escrito el siguiente código:
Y lo tienes que enviar al administrador del proyecto para que revise tu código, él va leyendo las variables y se encuentra con la variable:
$stuff, la cual contiene una colección de frutas. Bueno, su primer pregunta es, ¿por qué la variable $stuff no se llama $fruits? No concuerda con su contenido.
Después se encuentra con la variable $x, la cual es igual a apple. ¿Es enserio? —Se pregunta. Él pensó que la variable $x contenía el valor de una coordenada en el eje X.
¿Ves que ahora es más fácil de entender a qué se refiere cada variable? Pero el chiste no es escribir de nuevo el código, eso solo te ha quitado tu valioso tiempo.
Tal vez estos ejemplos sean algo simples y muy ilógicos, pero creanme, me he encontrado con estos casos, y ustedes también lo harán y se frustrarán.
Tus palabras deben ser claras, no uses abreviaciones
Para que lo anterior funcione, debes evitar escribir abreviaciones y las palabras de las acciones de tus variables y métodos deben ser claras, legibles y entendibles.
¿A qué nos referimos con el código anterior? ¿Estamos hablando sobre obtener la información de una categoría, de un catálogo o de un gato (cat, en inglés)?
Lo anterior produce confusión y frustración. ¿Qué estás pidiendo en realidad?
Ahora si que, si tu variable contiene autos, tu variable debe llamarse $cars. Si tu variable contiene tipos de coches, entonces debes llamar a tu variable: $cars_types.
¿Entiendes mi punto?
Pero, tampoco te excedas en nombrar las cosas; es decir, trata de usar palabras cortas, siempre que puedas. Ejemplo:
Hemos usado una variable con una buena cantidad de caracteres; para ser sinceros, se hace un poco difícil de leer. La solución es usar alguna palabra corta:
El nombramiento de las funciones y la documentación
La documentación es odiada por todos, yo la odio, pero es buena práctica escribirla, obviamente, clara y simple de entender, como lo hemos visto anteriormente.
¿Por qué? Tú puedes escribir tu código bien escrito, siguiendo las recomendaciones anteriores, pero, ¿qué pasa si quieres leer el código un año después que lo escribiste?
¡Así es! Probablemente no comprendas de qué se trate el código que escribiste, sin embargo, hay algunos casos en los que la documentación no es tan necesaria.
Una documentación puede ser opcional siempre y cuando tu código explique por si solo lo que está haciendo; por ejemplo, y es aquí donde aplicamos el buen nombramiento de las funciones:
Tenemos la función is_plugin_active() de WordPress, la cual sí tiene su propia documentación:
Pero podría ser opcional, ya que el mismo nombre de la función explica lo que está haciendo.
Sin embargo, está la función get_plugin_data(), cuya documentación abarca muchas líneas de código:
¿Notas la gran diferencia? Mientras más hagas entendibles tus códigos, menos documentación tendrás que escribir.
Conclusión
La buena práctica de nombrar bien las cosas es algo muy importante que debes tomar en cuenta, te ayuda a ti mismo y ayuda a demás programadores a ser mejores programadores.
Conocemos las condiciones en PHP, pero ¿qué tan eficientes son las que tu escribes? Las condiciones pueden afectar la legibilidad de tu código e incluso afectar el rendimiento de tu aplicación.
Los problemas en las condiciones
He visto a desarrolladores nuevos en grupos de Facebook publicar su código, ¿y saben qué es lo que he notado? Problemas en sus condiciones:
No son para nada legibles ni eficientes, por lo tanto, son complejas.
Ejecutan condiciones de más, provocando el famoso callback hell.
No utilizan las condiciones Yoda (Esto puede ser opcional en cada desarrollador, pero yo lo recomiendo como buena práctica).
Yo sufrí lo mismo; y es que cuando estás empezando a desarrollar en PHP, como que te cuesta encontrar una guía de buenas prácticas al momento de estar desarrollando.
Tu código debe ser legible, no lo hagas más complejo
Hay una verdad en los programadores:
Por lo tanto, todo el código que nosotros escribamos, deberá ser legible para que tanto nosotros como otros programadores lo lean rápido y por ende, el código sea fácil de entender.
¿No queremos gastar nuestro tiempo tratando de adivinar lo que hace el código o si?
Lo siguiente pasa muy seguido en los desarrolladores nuevos:
¿Si notas cómo el código de arriba se hace un poco difícil de leer? Entre más tedioso sea de leer, más complejo se volverá tu código.
El código anterior es un ejemplo de condiciones anidadas. Ahora, ¿Qué ocurre cuando empiezas a anidar condición tras condición, función tras función?
Ocurre el famoso callback hell; la siguiente imagen no contiene código PHP, pero es un ejemplo muy claro de un callback hell, condiciones tras condiciones (abre la imagen en una pestaña para verla mejor, si es que te atreves):
¿Pudiste descifrar lo que hace el código? ¡Yo ni me tomé el tiempo de leerlo! Tan sólo mira esa complejidad. Eso es lo que tratamos de evitar.
La solución de nuestro código anterior sería usar los operadores lógicos, en este caso, el operador AND:
¿Notas la diferencia? Es más legible y menos complejo. Los operadores lógicos están aquí para ayudarnos, así que pon atención a tus clases de Matemáticas Discretas (bueno, al menos yo lo vi en esa materia).
Usa cláusulas de guardia
Éste método funciona como un guardia que protege tu código, para poder llegar a la siguiente sección del código debes pasar ese guardia, y así sucesivamente.
Gráficamente trabaja así:
¿Pero realmente de qué sirve? Nos aporta mayor legibilidad a nuestro código, nos ayuda a no ejecutar código de más y evita el callback hell.
El siguiente ejemplo no tiene cláusulas de guardia:
La función anterior nos dice que si el usuario está registrado, nos retorne los datos del usuario que está tratando de iniciar sesión, en caso contrario, mandemos un array vacío.
Ahora, mira la misma función pero usando las cláusulas de guardia:
¿Ves como hemos negado la función in_array()? Le estamos diciendo que si el usuario no existe, retorna un array vacío, en cambio, si existe, continúa con el código y obtiene los datos del usuario.
¡Así es como funcionan las cláusulas de guardia! Tienes que pasar cada guardia para proseguir ejecutando el código.
Otro ejemplo, pero ahora con condiciones anidadas:
La función anterior valida si el usuario actual que está tratando de iniciar sesión es un administrador o no. Pero, ¿si sientes que pierdes un poco de tiempo tratando de leer el código?
Bien, entonces, la función anterior sería de la siguiente forma usando cláusulas de guardia:
Copy
<?phpfunctionis_current_user_admin( $username ) { $usernames_list =array('roelmagdaleno','rokumetal','elbuenprogramador117', );if( !in_array( $username, $usernames_list ) ) {return'The user does not exists.'; } $user_data =get_user_data( $username );if( 'administrator'!== $user_data['role'] ) {returnfalse; }returntrue;}
¡Estupendo! Eliminamos la condición anidada y ahora es más fácil de leer el código, y un extra fue que evitamos un posible callback hell.
¿Tienes funciones que contengan condiciones anidadas? Trata de convertirlas usando cláusulas de guardia y pega tus resultados en los comentarios.
Evita usar “else” en tus condiciones
¿Enserio, no usar el else? Sí, hablo enserio.
¿No te ha pasado que cuando usas la palabra reservada else, se te dificulta leer más el código? Exacto.
Esta declaración lo que hace es agregarle más complejidad a nuestro código y por ende, más difícil de leer. Por ejemplo, sé que puedes leer el siguiente código, pero ¿cuánto te tardas en entender lo que realmente hace?:
Bueno, el código representa un inicio de sesión, pero volvemos a lo mismo: legibilidad y complejidad. Y todos hemos escrito código parecido al anterior, no me dejarán mentir.
¿Cómo podemos evitar el else? Aquí tenemos dos soluciones:
Usar funciones para validar los datos y cláusulas de guardia; por lo tanto, el código anterior quedaría de la siguiente manera:
Copy
<?php$username = $_POST['username'];$password = $_POST['password'];if ( empty( $username ) ||empty( $password ) ) {return'user-login.php';}if( !validate_password_and_user_data( $username, $password, $verification_code ) ) {return'Something is wrong with your data.';}return'All good! Go to dashboard.';functionvalidate_password_and_user_data( $username, $password, $verification_code ) {if( 'roelmagdaleno'!== $verification_code ) {returnfalse; } $sql ='My SQL query to get username data.';if( $password !== $sql['password'] ) {returnfalse; }returntrue;}
¿Es más código? Sí, pero ésta solución hace que nuestros ojos no sangren al momento de ver el código, y no, no hemos usado ni un else.
El operador ternario
Vamos a usar un código directo, ¿has escrito un código como el siguiente?
Copy
<?php$new_color ='';if( isset( $_POST['color'] ) ) { $new_color = $_POST['color'];} else { $new_color ='red';}echo'The current color is '. $new_color;
Lo que estamos haciendo en el código anterior es que si existe el valor de un color que es traído desde un formulario, lo asigne a la variable $new_color, pero, sino existe, asigna un color por default.
El operador ternario puede reducir este tipo de condiciones con la siguiente sintaxis:
Siguiendo la sintaxis anterior, nuestro código ahora sería:
Copy
<?php$new_color =isset( $_POST['color'] ) ? $_POST['color'] :'red';echo'The current color is '. $new_color;
¡Wow! Nos ahorramos 5 líneas de código.
Una buena práctica que siempre hago es hacer primero la condición sin el operador ternario, y después, ya que he analizado bien mi condición, aplico el operador ternario.
Si usas otro lenguaje de programación, busca en este enlace si es compatible, o puedes probar directo en tu código.
Operador de fusión de null
Y hay una característica mucho mejor, pero solo es a partir de PHP 7, y se llama: operador de fusión de null. Su sintaxis es:
Y nos sirve para verificar si una variable existe, y si existe y no es null, asigna ese valor a la variable, en caso contrario, asignará el valor por default. Por ejemplo:
Copy
<?php$username = $_GET['username'] ??'John Doe';
Si $_GET['username'] existe y no es null, entonces la variable $username será igual a $_GET['username'], en caso contrario, será igual a John Doe.
Realmente, este operador hace una operación ternaria por detrás. El código anterior equivale a esta operación ternaria:
Recuerda, sólo funciona a partir de PHP 7 para arriba.
Condiciones Yoda
No explicaré aquí lo que es una condición Yoda, ya que he escrito un post específico para ese tema, y lo puedes leer en éste enlace.
Aplica los conocimientos aprendidos
Me da mucho gusto que hayas llegado hasta aquí, y espero que hayas aprendido algo, pero si te ha quedado alguna duda, tienes algún comentario ó sientes que me faltó una buena práctica, me gustaría que la compartieras en la caja de comentarios.
También te invito a compartir esta guía de buenas prácticas para que más desarrolladores nuevos aprendan a desarrollar de manera legible y menos compleja.
Los datos están en su máximo esplendor en estos últimos años y algunas empresas han liberado sus datos usando su propia API REST y, de vez en cuando, queremos mostrar esos datos en nuestro WordPress.
Al hablar de datos, se nos viene a la mente infinidad de cosas, por ejemplo, datos de:
Libros.
Redes sociales.
Casas y/o terrenos.
Productos e-commerce.
Pagos por Internet.
Dinero y/o criptomonedas.
Los ejemplos anteriores son unos cuántos de la infinidad de datos que existen en el Internet. Pero, ¿cómo obtenemos esos datos y los mostramos en nuestro WordPress?
La solución es: API REST externas.
¿Qué es una API REST?
Una API REST es una interfaz entre sistemas que utilizan peticiones HTTP para obtener y/o modificar datos, y hasta ejecutar funcionalidades específicas de la API REST.
Las respuestas de estas peticiones HTTP serán en formato JSON o XML, y podrás hacer lo que quieras con ellas con tu lenguaje de programación favorito.
Si no sabes qué son las peticiones HTTP, sigue éste enlace para saber más al respecto (las peticiones más comunes son: GET y POST).
Gráficamente, así es como funciona una petición a una API REST:
La lógica de la imagen anterior se explica de la siguiente manera:
El cliente quiere conocer los estados del país México.
Hay que hacer una petición a la API REST de /servicios/estados/.
A la petición hay que adjuntarle un parámetro { "pais": "México" }.
El parámetro funciona como filtro para obtener los estados de nuestro país.
Al final, nosotros decidiremos qué hacer con los resultados de la petición.
La API REST de CoinMarketCap
Vamos a desarrollar un pequeño plugin que se conecte a la API de CoinMarketCap; es una web que te muestra los precios de todas las criptomonedas que hay en el mercado.
Lo que queremos hacer es obtener las últimas 5 criptomonedas más populares del mercado y mostrarlas en nuestra barra de administración de WordPress, justo así:
Deberás crear una cuenta en CointMarketCap siguiendo los pasos en su guía. Lo importante que necesitaremos será la API Key.
¿Qué límites tiene la API REST de CoinMarketCap?
Ten en cuenta que la cuenta básica de la API de CoinMarketCap tiene un límite de 333 créditos por día y hasta 10,000 llamadas al mes, cada crédito equivale a un request a la API.
La mayoría de APIs siguen este mismo método para evitar el abuso de peticiones por parte de bots automatizados.
WordPress contiene un conjunto de funciones que pertenecen a la HTTP API, y sirven para hacer peticiones HTTP a API REST ó cualquier otro servidor que retorne alguna respuesta. Así mismo, también contiene funciones para leer dichas respuestas.
Lo que aprendas a continuación, te servirá para tus plugins y temas WordPress que desarrolles en el futuro.
Y también debemos especificar la API KEY generada por CoinMarketCap dentro de un header llamado X-CMC_PRO_API_KEY. Todos los headers deben de estar dentro de un arreglo con índice headers (al mismo tiempo headers es un arreglo) así como se ve en el siguiente código:
Usaremos las tres variables anteriores para construir y hacer la llamada a la API:
$api_endpoint – Este es en endpoint donde se hará la petición.
$api_args – Un arreglo que contiene la API KEY dentro de las cabeceras (headers). Si no especificas este valor, la API retornará un error.
$queries – Son los query strings que serán usados en el endpoint para modificar la respuesta de la API.
Puedes cambiar los valores de la variable $queries, por ejemplo, si quieres convertir a EUR en vez de MXN, simplemente especificas EUR en el índice convert del arreglo.
Si quieres obtener 10 o más criptomonedas en vez de 5, solo cambia el valor del índice limit del arreglo.
Visita la documentación de la API de CoinMarketCap para más información de los parámetros que aceptan sus URLs.
Adjunta los argumentos a la petición
También dijimos que acepta un segundo parámetro, los argumentos:
$args = array(
'method' => 'GET',
);
¡Sorpresa! Tenemos que especificarle qué tipo de método HTTP usará nuestra petición, en este caso la documentación de la API nos dice que usemos GET para la petición.
Nota la función add_query_arg(), esta se dedica a adjuntar todos los valores existentes de la variable $queries como query strings al endpoint que nosotros especifiquemos. El resultado de esa función será:
Y listo, ya estamos haciendo una petición a la API REST de CoinMarketCap.
¿Cómo obtener el resultado de la petición API REST?
Podemos asignar el resultado de la petición a una variable, en este caso, se la asignamos a la variable $response; y aquí viene otra de las funciones de la HTTP API de WordPress, wp_remote_retrieve_body():
wp_remote_retrieve_body( array $response );
Y como ven, acepta un parámetro de tipo array, y ahí es justo donde vamos a poner nuestra variable $response, la cual contiene la respuesta de nuestra petición.
¡Sí funciona! Si mandamos a imprimir la variable $cryptoscon la función var_dump(), veríamos lo siguiente:
Convierte el resultado JSON a un arreglo (array)
Hasta aquí todo bien, pero ahora tenemos un problema, el resultado en sí está en formato JSON, y tenemos que convertirlo a un array para que PHP lo pueda leer correctamente; esto lo hacemos con la función json_decode():
json_decode( string $string, bool $assoc_array );
La cual acepta dos parámetros:
$string (string) – El JSON string a decodificar.
$assoc_array (bool) – Si queremos que la decodificación sea un array o no.
Y lo implementamos en nuestro código; nota que el segundo parámetro de la función json_decode() es true:
El código anterior nos indica que ejecutará la función wp_cmkcap_add_admin_bar_menu() en el momento que el hook admin_bar_menu sea ejecutado.
Crea el menú principal
Ten mucho en cuenta que la función acepta un parámetro ($wp_admin_bar) de tipo WP_Admin_Bar, éste será muy importante, porque nos permitirá agregar nuestro menú:
function wp_cmkcap_add_admin_bar_menu( $wp_admin_bar ) {
//
}
A continuación, agregamos nuestro título principal del menú:
Ten en cuenta el método add_node(), éste será el encargado de agregar nuestro menú a la barra de administración de WordPress. Y recuerda muy bien qué valor le estás poniendo al índice id de la variable $parent_node.
Agrega los títulos dentro del menú
¿Recuerdan que convertimos nuestra respuesta JSON a un array? Bien, pues ahora lo leemos con la función foreach de PHP:
La variable $cryptos con índice data contendrá toda la información de la criptomoneda, entonces si queremos solo el nombre de la criptomoneda, tendríamos que llamar a la variable de la siguiente forma:
$crypto_data['name'];
Puedes revisar qué información contiene $crypto_data en la imagen cuando hicimos el var_dump().
Y ahora, quiero que pongas atención en el valor del índice title dentro de la variable $child_node:
En el índice title es donde pondremos el nombre de la criptomoneda concatenado con su precio en pesos mexicanos, para este ejemplo.
Y el valor del índice parent tendrá que ser igual al valor del índice id que le pusiste en tu variable $parent_node. Esto para que cada título de la criptomoneda se vaya agregando abajo del menú Cryptocurrencies.
Con el código anterior unido, la función wp_cmkcap_add_admin_bar_menu() se vería de esta manera:
Es muy común que las API REST que estemos utilizando devuelvan varios tipos de errores. Un error tal vez ocurra porque:
Te faltó especificar la API KEY para autenticar tu sesión.
Un parámetro que mandaste a la API está mal escrito y no existe.
El endpoint no existe.
El servicio de la API REST está fuera de servicio (timeout).
Si uno de los errores anteriores u otros sucede, en este momento en que el código no tiene validaciones contra errores, te devolvería un error PHP. Y no queremos eso.
Validación del timeout
En el caso de un timeout por parte de la API REST, la función wp_remote_request() retornará una instancia de tipo WP_Error como respuesta y la validamos con la función is_wp_error():
El código anterior menciona que si la variable $response es una instancia de WP_Error entonces agrega un mensaje de error adentro de nuestro menú:
Validaciones al código HTTP de la petición API REST
Ahora podemos agregar las validaciones a otros tipos de errores. Por ejemplo, si hubiésemos especificado el endpoint a una ruta que no existe, la API devolverá el siguiente resultado:
Aquí tenemos respuestas diferentes en ambos casos, el primer resultado es un código HTTP 404 y el segundo es un 401. Significa que tenemos que agregar validaciones de acuerdo al código HTTP devuelto.
Para obtener el código HTTP actual de la petición tenemos que usar la función wp_remote_retrieve_response_code( $response ) para después usar la respuesta de esa función dentro de una condición:
El código anterior menciona que si el código HTTP es diferente al número 200 (equivalente a un resultado exitoso) entonces obtendrá los mensajes de error y los insertará dentro de nuestro menú.
¡Ojo! Aquí tenemos que agregar una validación ternaria (variable $message) para obtener el mensaje de error ya que el resultado del error 404 es muy diferente al del error 401. Ten en cuenta este tipo de situaciones para evitar futuros errores.
Con las validaciones integradas, el menú se verá así cuando algún error suceda:
Resultado final
¡Listo! Hemos terminado, descarga el código completo y ejecútalo en tu WordPress y verás cómo funciona a la perfección, así es como se debería ver el código:
Pero podríamos usar otra función para hacer nuestras peticiones en vez de wp_remote_request(), y sería la función wp_remote_get(), la cual acepta los mismos parámetros que la función que hemos usado anteriormente.
Solo que le pasamos únicamente el primer parámetro, que es la URL de la API REST; el código quedaría de ésta forma:
Nótese que hemos eliminado la variable $args, (donde le decíamos que íbamos a hacer una petición GET) ya que ésta función es solamente para hacer peticiones HTTP GET.
Si tu API te pide una petición HTTP POST, entonces usarías la función wp_remote_post().
Puntos a tomar en cuenta
Cada API REST es diferente, nos piden distintos parámetros y alguno de ellos nos podría pedir ciertos argumentos, como cabeceras HTTP, el tiempo de espera del servidor, si desea verificar el SSL, entre otros. Si llegases a usar un argumento, lo tendrías que especificar dentro de la variable $args, por ejemplo:
Otro punto a tomar en cuenta es que algunas API REST necesitarán una API KEY para poder realizar nuestras peticiones exitosamente; tienes que revisar en la documentación de la API REST que estés usando, si necesitas una API KEY para empezar a utilizar su recurso.
De vez en cuando, las API REST podrían alentar un poco tu sitio, todo depende de qué tan rápida sea la respuesta de la API REST que estés utilizando. La solución a esto es que sólo hagas una única petición al momento de activar tu plugin y guardes el resultado de la petición en un valor en tu base de datos, y de ahi vas leyendo su valor, así te ahorras las llamadas que podrían arruinar tu sitio.
Recursos para API REST y WordPress
¿Te interesa seguir trabajando con API REST y WordPress? Aquí te dejo algunos recursos:
Insomnia. Un programa para hacer peticiones HTTP a API REST.
Si has llegado hasta aquí, ¡te felicito!
Ahora, te invito a que en los comentarios me expongas tus dudas que surgieron a lo largo del post ó las ideas que tienes sobre cómo implementar esto en algún plugin.
Si con éste tutorial has hecho un plugin parecido al que acabamos de desarrollar, comenta con un screenshot los resultados y explícanos de que se trata. 🙂
Changelog
18/04/2021
El endpoint, de CoinMarketCap, de ejemplo inicial se cambió porque dejó de existir. Ahora se usa un nuevo endpoint que requiere API KEY. El lector debe registrarse y obtener una API KEY para continuar con la guía.
Ahora se usa la función add_query_arg() para adjuntar los query strings al endpoint final.
Se agregó la sección de manejo de errores donde se valida ciertos errores de la API.
El código final se almacena en Gist en vez de descargarlo en formato ZIP.