Blog personal de IT, viajes y otros hobbies

Etiqueta: WordPress Página 1 de 6

Quitar las etiquetas y categorías por defecto de las entradas

WordPress por defecto asigna dos taxonomías a nuestras entradas: las clásicas categorías y etiquetas. El tema es que no siempre las necesitamos y mi filosofía de trabajo es que si algo no es necesario para el cliente mejor quitarlo para evitar posibles dolores de cabeza.

Remover estas taxonomías de las entradas es muy sencillo, basta con agregar el siguiente código al functions.php de nuestro tema o bien a un fichero de configuración de un plugin.

/**
 * Esta función quita las etiquetas de las entradas.
 */
function mgwp_unregister_tags() {
   unregister_taxonomy_for_object_type( 'post_tag', 'post' );
}
add_action( 'init', 'mgwp_unregister_tags' );
/**
 * Esta función quita las categorías de las entradas.
 */
function mgwp_unregister_categories() {
   unregister_taxonomy_for_object_type( 'category', 'post' );
}
add_action( 'init', 'mgwp_unregister_categories' );

Como puedes ver la función unregister_taxonomy_for_object_type nos permite quitar cualquier taxonomía de cualquier tipo de post.

En caso de que necesites quitar las dos taxonomías a la vez, une las dos líneas en el mismo action ⬇️ :

/**
 * Esta función quita las categorías y las etiquetas de las entradas.
 */
function mgwp_unregister_categories() {
   unregister_taxonomy_for_object_type( 'post_tag', 'post' );
   unregister_taxonomy_for_object_type( 'category', 'post' );
}
add_action( 'init', 'mgwp_unregister_categories' );

Cómo desactivar el «Modo a pantalla completa» por defecto de Gutenberg

Una de los cambios que introdujo la versión 5.4 de WordPress, es que Gutenberg se muestra por defecto en «Modo a pantalla completa», es decir, ocupando la totalidad de la pantalla y ocultando el valiosísimo menú lateral con los enlaces a las entradas, páginas, plugins, etc.

Pero estoy seguro que a no todo el mundo le agrada esta idea y estarán buscando alguna posible solución.

Pues bien, aquí tienes 2 formas de poder desactivarlo sin ningún riesgo para tu Web.

Desactívalo en forma manual

La forma más simple tal vez es desactivándolo de forma manual siguiendo estos pasos:

  1. Haz clic en los 3 puntos de configuración de Gutenberg.
  2. Selecciona la opción «Barra de herramientas superior»
  3. Deselecciona la opción «Modo a pantalla completa»

Ten en cuenta que este método se guarda en las configuraciones locales del navegador con lo cual, si abres el Administrador de WordPress en modo incógnito o en otro ordenador tendrás que repetir la operación.

De todas formas, está previsto en próximas versiones guardar esta configuración en base de datos.

Desactívalo con código

Si bien el código para desactivarlo es Javascript, podemos apañarnos pegando este trozo de código en el functions.php de nuestro tema o bien en un plugin.

/**
 * La siguiente función desactiva la opción de «Modo a pantalla completa»
 * por default del editor de Gutenberg.
 */
function mg_desactivar_editor_gb_pantalla_completa_por_default() {
	$script = "window.onload = function() { const isFullscreenMode = wp.data.select( 'core/edit-post' ).isFeatureActive( 'fullscreenMode' ); if ( isFullscreenMode ) { wp.data.dispatch( 'core/edit-post' ).toggleFeature( 'fullscreenMode' ); } }";
	wp_add_inline_script( 'wp-blocks', $script );
}
add_action( 'enqueue_block_editor_assets', 'mg_desactivar_editor_gb_pantalla_completa_por_default' );

Eso es todo, fácil solución a un cambio que generó alguna que otra polémica en la Comunidad de WordPress.

Si quieres indagar un poco más sobre este cambio, te dejo el artículo que se escribió en el blog del Make WordPress Core. ⬇️

Happy coding!

La Pantalla Blanca de la muerte WordPress solución

¿La pantalla de WordPress está en BLANCO? → [SOLUCIONADO]

Venga, que levante la mano quien nunca tuvo que lidiar con «la pantalla blanca de la muerte» de WordPress. Ese error que a todos nos desespera porque no nos da ningún indicio de posible solución. Hasta hoy, porque les traigo una herramienta que puede darnos algo de luz al final del túnel.

Pantalla Blanca de la Muerte de WordPress

MG Whitescreen Plugin Checker

Ejemplo de resultado del plugin MG WhiteScreen Plugin Checker.

El plugin MG Whitescreen Plugin Checker chequea el correcto funcionamiento de todos los plugins instalados y activos en tu página web. Si alguno de ellos falla, nos mostrará un mensaje con el nombre del plugin y el tipo de error devuelto.

Verifica plugin por plugin individualmente

Una de las modalidades del plugin es verificar tu web activando un plugin por vez. De esta manera es muy simple detectar si solo uno (o varios) de todos ellos son los causantes del problema.

Ej: Pruebo la Web solo con el Akismet, ¿Va bien? sigo con el siguiente plugin.
Pruebo la Web solo con Contact Form 7, ¿Da error? muestro el mensaje y sigo con el siguiente.
Y así hasta terminar con toda la lista de plugins.

En la imagen anterior podemos ver como en un ejemplo el plugin «Contact Form 7» está devolviendo un error 500.

Verifica todas las combinaciones posibles de plugins

Otra posibilidad es que el sistema falle debido a la combinación específica de un grupo de plugins ¿Cuánto tardaríamos hasta dar con esa combinación?

Este plugin crea todas las combinaciones posibles de plugins y realiza los testeos para detectar cuál de todas ellas es la que está fallando ¡A que mola!

Ejemplo: Si tenemos los plugins A, B y C el sistema generará testeos para: [A], [A, B], [B], [B, C], [C], [A, C] y [A, B, C]

No afecta al resto de tu web

Puedes ejecutar este plugin sin temor a afectar el normal funcionamiento del resto del sitio ya que el plugin está preparado para actuar con unos parámetros determinados que solamente el administrador del sitio web conocerá (y que detallaré más adelante en la sintaxis).


Instalación

Para instalarlo solo tienes que descargar el fichero mg-whitescreen-plugin-checker.php que puedes encontrar en mi repositorio de GIT.

Una vez descargado tienes que subirlo por FTP a la carpeta tu-wordpress/wp-content/mu-plugins de tu sitio web.

Presta mucha atención que el nombre de la carpeta es mu-plugins y no plugins. Este punto es importante ya que este fichero tiene que actuar antes de que WordPress cargue el resto de los plugins (y surja el error).

Sintaxis

Prueba básica (plugin por plugin)

Recomiendo que en primer lugar se haga una prueba básica (plugin por plugin) para descartar que sea solamente un plugin el que esté generando el problema. Es la prueba más rápida y la que seguramente nos dé la luz necesaria para saber dónde puede estar el problema.

Para realizar esta prueba solo tienes que:

  • Ir a la dirección Web que esté generando la pantalla blanca.
  • Añade los siguientes parámetros ?wpc=individually a la dirección y volver a ejecutarla.
    Ej: http://mi-wordpress.com/contacto?wpc=individually

Como expliqué anteriormente, este método activará y desactivará plugin por plugin para detectar cuál puede estar fallando.

Prueba combinada (combinación de plugins)

Esta prueba tardará un poco más dependiendo del número de plugins que tenga el sitio web activado.

Para realizar esta prueba solo tienes que:

  • Ir a la dirección de tu Web que está generando la pantalla blanca.
  • Añade los siguientes parámetros ?wpc=complete y vuelve a ejecutarla.
    Ej: http://mi-wordpress.com/contacto?wpc=complete

Lo dicho, esta prueba tardará un poco más por la cantidad de combinaciones posibles, pero dará un resultado detallado de los errores.

¿Qué hacer una vez detectado el problema?

Una vez detectado el plugin que da el problema, puedes desactivarlo modificando el nombre de su carpeta o borrándolo (si sabes bien qué es lo que estás haciendo).

Una vez desactivado el plugin verifica lo siguiente:

  • Que la página vuelva a funcionar: Normalmente sí, pero también es posible que el plugin que acabamos de desactivar sea necesario para el correcto funcionamiento de otros plugins (a veces esto es una reacción en cadena).
  • Si el plugin que fallaba es del repositorio de WordPress: Lo más probable es que no se haya descargado correctamente, puede estar faltando algún fichero o bien algunos de ellos estar corrupto. La solución sería borrar el plugin y volver a descargarlo.
  • Si el plugin que fallaba era uno creado por ti o instalado de otro lugar que no sea el repositorio de WordPress: Pues lo más probable es que haya errores de PHP en su código. Aquí te tocará trabajar un poco más para descubrir dónde está el problema. Posible solución: hazte una copia local de la web y activa la constante define ( WP_DEBUG, true ); en el fichero wp-config.php para dónde está ocurriendo el error específicamente.
Una vez activado la constante WP_DEBUG podemos ver que el problema está en el fichero wp-contact-form-7.php en la línea 13

¿No podríamos haber hecho esto desde un principio?

Como poder se puede, pero NUNCA debemos dejar la constante WP_DEBUG activada en el servidor de producción, porque:

  • Podríamos estar dando indicios a ciberdelincuentes.
  • No es muy profesional navegar por la Web y encontrarte estos tipos de desgloses de errores.
  • Según cómo esté configurado el servidor, es probable que aparezcan más mensajes de este tipo en el resto de la Web con simples «Warnings» o «Notice» que son notificaciones de menor grado pero igual de molestos para el visitante.

Agradecimiento

Tengo que agradecer a Fernando Puente por habernos enseñado esta maravillosa técnica utilizando el filtro option_active_plugins que abre las puertas a un sinfín de posibilidades. Les recomiendo que vean su charla sobre el tema que dio en la WordCamp Zaragoza 2019.


Nuevas ideas y colaboraciones

Con el tiempo iré mejorando el plugin y agregando nuevas funcionalidades para que la pantalla blanca nos dé cada vez menos y menos problemas.

¿Se te ocurre alguna mejora? ¿Te animas a hacer un Pull Request? Cualquier ayuda será bienvenida y compartida en el artículos.

Happy Coding! 💻

Patrones con expresiones regulares en php y WordPress

Expresiones Regulares en PHP – La Guía definitiva

Tal como lo indica el título del artículo estamos buscando patrones pero de caracteres y dentro de un texto o cadena (string). Para ello usamos las expresiones regulares, tecnología presente en varios lenguajes de programación (PHP, Javascript, Phyton, Perl) que mediante una concatenación estructurada de caracteres nos permite moldear una fórmula o patrón para aplicar a un texto determinado y encontrar así las secuencias.

Cada vez que tengo que trabajar con ellos me veo con sentimientos encontrados. Por un parte  sufro un poco ya que su sintaxis es muy compleja y difícil de memorizar, pero por otra parte me maravillo por todo lo que podemos hacer con un par de líneas de código.

Por ejemplo: Muchas plataformas no permiten que los usuarios envíen sus direcciones de correo electrónico en los mensajes que intercambian. Para ello cada mensaje pasa por un filtro de expresiones regulares. Aplicando el regexp (acrónimo de Regular Expressions) /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b/ podemos detectar estos caracteres tal como lo muestra la siguiente imagen:

ejemplo de expresiones regulares
Ejemplo visual que iremos viendo a lo largo del artículo

Sintaxis

A modo de ejemplo, y para que luego lo podamos utilizar en nuestro WordPress, vamos a utilizar la nomenclatura y funciones propias de PHP. Verán en cada sintaxis, en la última columna, un enlace a la web regex101 donde podrán testear los ejemplos en vivo.

Caracteres

RegexpDescripciónResultadoregex101
.Cualquier caracterTengo 36 años y mido 1,80m de altura.🔗
\sCualquier caracter de espacio en blancoTengo 36 años y mido 1,80m de altura.🔗
\SCualquier caracter que NO sea un espacio en blancoTengo 36 años y mido 1,80m de altura.🔗
\dCualquier caracter que sea un dígito entre 0 y 9Tengo 36 años y mido 1,80m de altura.🔗
\DCualquier caracter que NO sea un dígito entre 0 y 9Tengo 36 años y mido 1,80m de altura.🔗
\wCualquier caracter que sea una letraTengo 36 años y mido 1,80m de altura.🔗
\WCualquier caracter que NO sea una letraTengo 36 años y mido 1,80m de altura.🔗

Cuantificadores

RegexpDescripciónEjemploExplicaciónValores válidosregex101
*Cero o más/v\d(\.\d)*/g– Una «v»
– un dígito
– Cero o más de (
– un «.»
– un dígito
)
WordPress v4.8.
WordPress v4.8.3.
WordPress 4.8 ❌
🔗
?Uno o ninguno/Star Wars\s?\d?/g– Las palabras «Star Wars»
– Uno o ningún espacio
– Uno o ningún dígito
La película Star Wars
La película Star Wars 4
La película Star Wars 5
La película StarWars ❌
🔗
+ Uno o más/v\d[.]\d+/g– Una «v»
– un dígito
– un «.»
– Uno o más dígitos
WordPress v4.8.
WordPress v5.10.
WordPress v5 ❌
🔗
 {n}Exactamente n veces/w{3}/g– Exactamente tres letras «w»www.maugelves.com
www.ayudawp.com
desarrollowp.com ❌
🔗
{n,m}Entre n y m veces/\d{3,5}/g– Entre 3 y 5 dígitosPeugeot 306
Año 2017
20000 leguas de viaje submarino
12 monos ❌
🔗
{n,}n o más veces/\d{3,}/g – Mínimo 3 dígitosPeugeot 306
Año 2017
20000 leguas de viaje submarino
1000000 de años luz
12 monos ❌
 🔗

Lógica

Sí, también se pueden agregar cierta lógica dentro de la misma expresión. Echa un ojo a los siguientes ejemplo:

RegexpDescripciónEjemploExplicaciónValores válidosregex101
|Operador OR (ó)/Batman|Superman/g– La palabra «Batman» ó «Superman»Batman
Superman
Robin ❌
🔗
( … )Agrupador
Este grupo puede luego ser reutilizado.
/Mar(cos|tín)/g– Los caracteres «Mar» seguidos de
– «cos» ó «tín»
Marcos
Martín
Mauricio ❌
🔗
(?(1)yes|no)Condicional
Si el grupo 1 entonces «yes»
Sino «no»
/(Esta condición)?(?(1) es verdadera| es falsa)/g – Uno o ninguna aparición de los caracteres «Esta condición»
– Si existe concatena la búsqueda de los caracteres «es verdadera»
– Caso contrario concatena la búsqueda de los caracteres «es falsa»
Esta condición es verdadera
Esta otra es falsa
Aquí no se debe seleccionar nada ❌
🔗
(?=…)Futuro positivo (Positive Lookahead)

 

Solo encuentra patrones si existe una condición futura.

/para(?=psicología|normal)/g – Seleccionará los caracteres «para» solo si:
– los siguientes caracteres son «psicología» ó «normal»
La parapsicología.
Fenómeno paranormal.
El parapente. ❌
 🔗
(?!…)Futuro negativo (Negative Lookahead)

 

Solo encuentra patrones si no existe una condición futura.

/para(?!psicología|normal)/gSelecciona los caracteres «para» solo si:
– los siguientes caracteres no son «psicología» ó «normal»
El parapente
El paraíso fiscal
Fenómeno paranormal ❌
🔗
 (?<=…)Pasado positivo (Positive Lookbehind)

 

Solo encuentra patrones si existe una condición pasada.

/(?<=solu|informa)ción/gSelecciona los caracteres «ción» solo si:
– los caracteres anteriores son «solu» ó «informa»
Tengo la solución,
con la información
de la ecuación. ❌
🔗
(?<!…)Pasado negativo (Negative Lookbehind)

 

Solo encuentra patrones si no existe una condición pasada.

/(?<!informa)ción/gSelecciona los caracteres «ción» solo si:
– los caracteres anteriores no son «informa»
La desilución
y manipulación
de la información
🔗

Clases de caracteres

Limita los caracteres que estás buscando con las siguientes sintaxis:

RegexpDescripciónEjemploExplicaciónValores válidosregex101
[…]Delimitador de caracteres/[aeiouáéíóú]/g– Encuentra cualquiera de los caracteres especificados.murclago
aburriendo
bcdfghjklm ❌
🔗
[^…]
 Excepción de caracteres /[^aeiouáéíóú]/g– Encuentra todos los caracteres excepto los especificados.murclago
aburriendo
bcdfghjklm
🔗
[[:alnum:]]
Letras y dígitos/[[:alnum:]]/g– Encuentra todas letras y números comprendidos entre [A-Za-z0-9]¡¡¡Texto, 12345!!!🔗
[[:lower:]]
Caracteres en minúsculas /[[:lower:]]/g– Encuentra todos los caracteres en minúsculasabcDEF🔗
[[:upper:]]
 Caracteres en mayúsculas /[[:upper:]]/g – Encuentra todos los caracteres en mayúsculas abcDEF 🔗

Anclas

Las anclas sirven para indicar en qué parte del texto queremos aplicar el patrón de búsqueda. Veamos a continuación las sintaxis más utilizadas:

RegexpDescripciónEjemploExplicaciónValores válidosregex101
^Busca el patrón de caracteres al comienzo de la cadena o al comienzo de cada línea, según el modificador global.

 

Recuerda que cuando se encuentra entre llaves significa lo contrario: [^entre llaves]

Sin modificador multilínea
/^\w+/gCon modificador multilínea
/^\w+/gm
– Busca el patrón al comienzo del texto.Sin modificador multilínea:
Soy un texto multilínea
sin el modificador global «m»Con modificador multilínea:
Soy un texto multilínea
con el modificador global «m»
🔗
 $Busca el patrón de caracteres al final de la cadena o al final de cada línea, según el modificador global.Sin modificador multilínea
/\w+$/gCon modificador multilínea/Unicode
/\w+$/gum
 – Buscal el patrón al final del texto.Este es el fin
de la historia
🔗
/ABusca el patrón de caracteres siempre al comienzo del texto. No se ve afectado por el modificador global «m»./\A\w+/gm– A pesar de indicar el modificador «m» solo devolverá el conjunto de letras al principio del texto.Solo afecta al comienzo
aún con el modificador multilínea
🔗
/ZBusca el patrón de caracteres siempre al final del texto. No se ve afectado por el modificador global «m». /\w+\Z/gm– A pesar de indicar el modificador «m» solo devolverá el conjunto de letras al final del texto.Siempre seleccionaré
la última palabra
 🔗

Modificadores globales

Como verán en los ejemplos anteriores, todas las expresiones regulares las hemos encerrado con barras y una letra g al final (/…/g). Esta sintaxis permite que podamos englobar la expresión y modificarla con distintos valores que veremos a continuación:

ModificadorDescripciónEjemploExplicaciónValores válidosregex101
/…/gGlobal: busca todas las posibles coincidencias en el texto (no se detiene ante el primer hallazgo)./(je|jé)/g– Encuentra todos los caracteres «je» o «jé» en la cadena.Asere, ja deje tejebe tude jebere
Sebiunouba majabi an de bugui an de buididipí
Asere, ja deje tejebe tude je.
🔗
/…/mMultilínea: busca el patrón en cada línea del texto./Fin de la cita.$/gm– Encuentra la frase exacta «Fin de la cita.» al final de cada línea.Yo presido. Fin de la cita.
Y lo digo. Fin de la cita.
🔗
/…/iInsensitivo: busca el patrón en minúsculas o mayúsculas./a/gi– Encuentra la letra «a» sea minúscula o mayúscula.A de accesibilidad🔗
/…/u Unicode: busca el patrón incluyendo caracteres de UTF-16./voc\w/gu – Encuentra la frase «voc» seguida de cualquier caracter comprendido en  UTF-16.Assim você me mata 🔗

Funciones PHP

Una vez que tengamos el patrón de caracteres a buscar, podremos especificar una serie de funciones de PHP:

preg_replace:

Esta función de PHP busca un patrón de caracteres en un texto y lo reemplaza por otro que le especifiquemos.

<?php
/** 
* Mensaje que quiere evadir la política
* de comisiones de la plataforma.
*/
$mensaje = "Hola Juan: mi nombre es Mauricio y te dejo mi email para que 
			contactemos fuera de esta aplicación que cobra comisiones muy caras, 
			toma nota: mg@maugelves.com. Un saludo, Mauricio.";
/**
* Pero aquí viene la función justiciera.
* 
* En PHP existe una función mejor para validar emails, pero 
* usaremos funciones de expresiones regulares con 
* fines didácticos.
* http://php.net/manual/en/filter.filters.php
*/
// Patrón para encontrar direcciones de email
$patron = "/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b/";
// Reemplazo cualquier email por el texto "correo eliminado"
$mensaje = preg_replace( $patron, "(correo eliminado)", $mensaje );
echo $mensaje;
/*
* Esto devuelve:
*
* Hola Juan: mi nombre es Mauricio y te dejo mi email para que 
* contactemos fuera de esta aplicación que cobra comisiones muy caras, 
* toma nota: (correo eliminado). Un saludo, Mauricio.
*
*/

preg_split:

Función ideal si queremos dividir un texto en un array por un patrón de texto. Veamos el siguiente ejemplo donde separamos un texto por espacios o comas.

<?php
/** 
* Fragmento del Quijote de la Mancha
*/
$texto = 	"Y, viéndole don Quijote de aquella manera, con muestras de tanta 
			tristeza, le dijo: Sábete, Sancho, que no es un hombre más que 
			otro si no hace más que otro.";
// Patrón para encontrar espacios y comas (,).
$patron = "/[\s,]+/";
// Guardo en un array todas las palabras separadas por comas o espacios.
$array = preg_split( $patron, $texto );
var_dump( $array );
/*
* Esto devuelve:
*
* array(30) { [0]=> string(1) "Y" [1]=> string(9) "viéndole" [2]=> string(3) "don" 
* [3]=> string(7) "Quijote" [4]=> string(2) "de" [5]=> string(7) "aquella" 
* [6]=> string(6) "manera" [7]=> string(3) "con" [8]=> string(8) "muestras" 
* [9]=> string(2) "de" [10]=> string(5) "tanta" [11]=> string(8) "tristeza" 
* [12]=> string(2) "le" [13]=> string(5) "dijo:" [14]=> string(7) "Sábete" 
* [15]=> string(6) "Sancho" [16]=> string(3) "que" [17]=> string(2) "no" 
* [18]=> string(2) "es" [19]=> string(2) "un" [20]=> string(6) "hombre" 
* [21]=> string(4) "más" [22]=> string(3) "que" [23]=> string(4) "otro" 
* [24]=> string(2) "si" [25]=> string(2) "no" [26]=> string(4) "hace" 
* [27]=> string(4) "más" [28]=> string(3) "que" [29]=> string(5) "otro." }
*
*/

preg_match:

Esta es tal vez la función más simple ya que devuelve un 1 si encuentra al menos un patrón de caracteres y un 0 en caso negativo o error. Vamos a definir un patrón para detectar si alguien escribe mal la palabra WordPress en un texto cualquiera (recuerden que lleva la letra W y P en mayúsculas).

<php
/** 
* Un fragmento de texto con la palabra WordPress mal escrita
*/
$texto = 	"Hola, tengo un problema con mi página web. Está hecha
			en wordpress y quería que alguien me eche una mano.
			¿Qué debo hacer?"; // Parece gracioso pero suelo recibir emails de este tipo.
// Patrón para encontrar WordPress mal escritos.
$patron = "/(wordpress|wordPress)+/";
// Guardo en un array todas las palabras separadas por comas o espacios.
$hay_error = preg_match( $patron, $texto );
var_dump( $hay_error );
/*
* Esto devuelve:
*
* int(1)
*
*/

¿Cómo usarlo en WordPress? Plugin Moderdonizer

Moderdonizer WordPress Plugin

Luego de la chapa que solté con tanto tecnicismo es hora de ver cómo podemos implementar estas expresiones regulares en WordPress. Solo cambiará el entorno ya que seguiremos utilizando las mismas funciones nativas de PHP.

Voy a detallar un ejemplo con una linda locura que se nos ocurrió junto a Álvaro Gómez (AKA @Mrfoxtalbot).

Ambos somos fieles seguidores del programa de radio «La vida moderna«, una show humorístico donde a lo largo del tiempo han desarrollado un lenguaje propio. Por ejemplo, en lugar de decir «comedia» dicen «commedia» para identificar el tipo de humor que ellos realizan (que a veces roza límites muy arriesgados) y también reemplazan las terminaciones «ción/sión» por «ció/sió», haciedo alusión (y un poco de burla) al idioma catalán.

Con el juego de palabras se nos ocurrió que podíamos hacer un plugin (el cual está en fase de aprobación 😝) y subirlo al repositorio. La finalidad del mismo es simplemente reemplazar el título y contenido de cualquier entrada o página con las palabras típicas del programa. Para ello debíamos definir en primer lugar las reglas gramaticales, dos de ellas resultaron simples pero la doble «m» tenía un poco más de chicha: Este es el detalle de cada regla:

  1. Reemplazar palabras que acaben en «ción» por «ció» cuando después venga un espacio, punto, coma, interrogación o exclamación.
  2. Reemplazar palabras que acaben en «sión» por «sió» cuando después venga un espacio, punto, coma, interrogación o exclamación.
  3. Reemplazar la letra «m» por doble «mm» cuando la consonante se encuentre entre vocales.

Con las reglas definidas me puse manos a la obra y luego de varias correcciones di con las expresiones regulares correctas. Las mismas las utilizo con la función preg_replace() de PHP cuando se ejecutan los filtros the_content y the_title.

El plugin, que de momento pueden encontrar en mi repositorio de Github, luce más o menos así:

<?php
/**
 * Esta función reemplaza el contenido Godo con palabras de la República Dictatorial de Moderdonia.
 * Estas son las reglas que se aplican:
 *
 * @author  Mauricio Gelves
 * @params  $content    string  El contenido del post
 * @returns             string  El contenido del post con las nuevas palabras moderdonizadas.
 */
function fn_modernonize( $content ) {
	// Regla 1: "ción" por "ció" (ver comentarios en función)
	$content = preg_replace('/ción(?=[ .!,?])/', 'ció', $content );
	// Regla 2: "sión" por "sió" (ver comentarios en función)
	$content = preg_replace('/sión(?=[ .!,?])/', 'sió', $content );
	// Regla 3: "m" por "mm" (ver comentarios en función)
	$content = preg_replace('/(?<=[aeiouáéíóú])m(?=[aeiouáéíóú])/', 'mm', $content );
	return $content;
}

Conclusión

No me sorprenderé ni me avergonzaré cuando vuelva a mi propio artículo para saber cómo funcionan las expresiones regulares. Espero que vosotros también la dejéis apuntada como favorita para consultar en cualquier momento. Lo que sí puedo contarles es que escribiendo este artículo, que llevó muchas horas de desarrollo, me ha hecho conocer mucho más esta potente tecnología y sentirme más seguro de cara a futuras implementaciones. Es lo bueno de tener un blog.

wordpress poop life thumb

Instala un WordPress de 💩 para tus pruebas

Un nuevo plugin, un tema que quieres probar o una nueva funcionalidad de WordPress que quieres trastear. Para todos estos casos necesitarás una instalación de WordPress de prueba. Puedes crear una instancia local con tu propia configuración de Apache, ejecutarlo con un MAMP/WAMP/XAMPP o bien instalar un WordPress de prueba en algún servidor de hosting, pero ¿qué me dirías si te digo que puedes instalar instancias de WordPress de prueba con tan solo hacer un click y sin tener que lidiar con largas configuraciones? Esto es lo que ofrece el sitio web Poopy.life.

página principal de poopy life

Instalaciones a 1 click

Basta con pinchar en el enlace poopy.life/create (debajo del emoji 💩) para que la empresa wpsandbox.io te cree una instalación de WordPress en sus servidores, en forma gratuita y sin que tengas que preocuparte por configuraciones, base de datos, etcétera. Podrás hacer con ella lo que quieras: instalar cualquier tema, plugins, modificar su configuración, cargar contenido, utilizarla para realizar demos, etc. Vamos, un WordPress de 💩 para que pueda usarlo y destrozarlo a piacere.

7 días para exprimir tu instalación

Una vez que has instalado tu WordPress verás tus credenciales junto a una URL personalizada de login para que puedas utilizar o bien compartir. La web tendrá una semana de vida que podrás extender con un simple click

Panel de administración de Poopy Life

Panel de Poopy Life en el administrador de WordPress

Otras de las funcionalidades que ofrecen es la posibilidad de crear instancias a partir de una plantilla de prueba. Una vez que hayas configurado tu WordPress, instalado plugins, temas o lo cualquier otra modificación que hayas realizado, puedes pinchar en el botón «Create Sandbox Template» (crear plantilla de prueba) para crear algo así como un molde del que podrán crearse múltiples copias.

Como habrás visto el proceso es muy simple y nos ahorra muchísimo tiempo para esas ocasiones en las que necesitamos una instancia limpia de WordPress. Anda, prueba crear una instancia de WordPress, modifica sus configuraciones y déjame tu comentario sobre qué te ha parecido este servicio.

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.
*/
¿Cómo cambiar rápidamente perfiles de usuarios?

Revisión de plugin – View Admin As

Hay funcionalidades de plugins o temas que deben estar limitados a ciertos perfiles de usuarios de WordPress (Administrador, Editor, Autor, Colaborador o Suscriptor) o, peor aún, a un limitado grupo de capacidades (recordad que cada perfil de usuario de WordPress es en realidad un conjunto de capacidades). Para probar dichas funcionalidades solíamos crear nuevos usuarios con otros perfiles y perdíamos un tiempo valioso saliendo y loguéandonos nuevamente para comprobar que todo funcionaba correctamente. Hoy podemos quitarnos este dolor de cabeza con el plugin View Admin As el cual nos permite cambiar de perfiles o capacidades al vuelo sin necesidad de crear nuevos usuarios.

Header del plugin View Admin As

Header del plugin View Admin As

Video Tutorial

Interfaz gráfica

Una vez instalado y activado el plugin veremos a la derecha de nuestra barra de administrador una nueva opción con el título «Default view (Off)». Al posicionarnos con el ratón veremos que se despliegan las siguientes opciones:

  • Info
  • Settings
  • Capabilities
  • Roles

View Admin As barra de adminsitrador

Nueva opción en la barra de adminsitrador de WordPress

¿Cómo cambiar de rol sin crear un nuevo usuario?

Basta solamente con que elijamos uno de los 5 roles disponibles (o un rol personalizado que creemos) en el selector bajo el nombre de Roles para que la magia suceda. Si el rol seleccionado tiene acceso al administrador de WordPress se refrescará la pantalla con la nueva configuración caso contrario nos llevará al Frontend del sitio web. Una vez seleccionado el nuevo perfil veremos en la barra de administrador un mensaje del tipo «Visualizando con el rol: editor»,  «Visualizando con el rol: contributor», etc. Con pinchar el botón «Resetear a los valores por defecto» volveremos a nuestro usuario habitual.

View Admin As cambiar roles

¿Cómo cambiar roles con View Admin As?

¿Cómo modificar las capacidades del perfil al vuelo?

Otra de las grandes funcionalidades que tiene este plugin es la posibilidad de poder modificar al vuelo las capacidades, partiendo o no de cualquier perfil. También incluye la opción de asignar todas las capacidades «que no sean de este perfil».

Para ello deberemos seguir los siguientes pasos:

  1. Ir a la barra de administrador.
  2. Posicionarnos en el submenú «Capacidades». Este desplegará un formulario con todas las capacidades disponibles.
  3. Seleccionar las capacidadades que deseemos o bien partir de los valores por defecto dentro del desplegable.
  4. Pinchar el botón «Aplicar» para asignar las nuevas capacidades al usuario actual.

View Admin As cambiar capacidades

Cambiando las capacidades a partir de cualquier perfil.

Al igual que con los roles, una vez que hayamos terminado las pruebas podremos pinchar nuevamente en «Resetear los valores por defecto» para volver a nuestro usuario habitual.

Conclusión

Este plugin, junto a otros tantos, es otra herramienta indispensable que utilizo en el desarrollo de mis proyectos para validar que ciertas funcionalidades de perfiles funcionan correctamente. No tiene mucho sentido tenerlo instalado en un sitio web en producción aunque podría utilizarse para una verificación puntual.

Enlaces: View Admin As en el repositorio de WordPress.org.
Traducción: En poco tiempo estará disponible la versión en español que me tomé el trabajo de traducir.

Actualización 30/07/2017: Las traducción al español fue aprobada 🙂

Cómo crear formularios sin plugins

¿Cómo crear formularios y capturar los valores con WordPress y sin plugins?

Ya no me sorprende encontrar plugins como Contact Form 7, Gravity Forms o Ninja Forms para dar solución a simples formularios en el frontend: ya sea una suscripción a un newsletter, un formulario de contacto o una verificación de edad. Los plugins están muy bien, no lo voy a negar, pero agregan una carga al servidor, en la mayoría de los casos, innecesaria. Además, el tiempo que consume aprender a utilizarlos es a veces mayor al de aprender por única vez cómo funcionan las propias peticiones POST y GET del protocolo HTTP. Luego de leer este artículo tendrás los conocimientos necesarios para hacer lo que desees con los valores que cargan nuestros usuarios en los formularios de nuestras webs.

Videotutorial

¿Cómo crear un formulario en el frontend?

No hace falta saber programación para crear un formulario en el frontend, solo algunos conocimientos básicos de HTML y que son los mismos conceptos que se utilizan desde hace muchos años.

Para el ejemplo vamos a crear un formulario de contacto en el que pedimos al usuario su nombre y un mensaje.

<form action="<?php echo esc_url( admin_url('admin-post.php') ); ?>" method="post">
    <label for="txtnombre">Nombre:</label>
    <input type="text" id="txtnombre" name="txtnombre">
    <label for="txtmensaje">Mensaje:</label>
    <textarea name="txtmensaje" id="txtmensaje" cols="15" rows="4"></textarea>
    <input type="hidden" name="action" value="contacto">
    <input type="submit" value="Enviar">
</form>

Puntos importantes del código:

  1. En esta línea abrimos la etiqueta form y todo los inputs que estén dentro de esta etiqueta se enviarán al servidor, puntualmente al fichero ‘admin-post.php’ a través de una petición POST de HTTP.
  2. Para que WordPress capture el formulario debemos indicar un nombre de acción, el cual guardaremos en un input del tipo oculto (hidden)
Ejemplo de formulario de contacto
Formulario de contacto de ejemplo

¿Cómo capturar correctamente los valores desde WordPress?

El fichero admin-post.php de WordPress define unas acciones muy fáciles de utilizar y que nos permite capturar los valores de las peticiones POST o GET de nuestro formulario. El nombre de los mismos se definen con un prefijo estándar más el nombre de la acción que hemos definido en nuestro formulario. Veamos el siguiente ejemplo en el fichero functions.php de nuestro tema:

<?php
/**
 * Funcion que captura los valores de una 
 * petición POST o GET de HTTP.
 */
function nombre_de_la_funcion(){
	
	// Nuestro código de manipulación de los datos
	
}
add_action('admin_post_nopriv_accion', 'nombre_de_la_funcion'); // Para usuarios no logueados
add_action('admin_post_accion', 'nombre_de_la_funcion'); // Para usuarios logueados

¿Por qué hay dos acciones para la misma funcionalidad? ¿Qué es eso de «admin_post_nopriv»?

Si te has fijado bien en el código estamos utilizando dos acciones para capturar los valores del formulario. Y es que WordPress nos permite tener el control sobre usuarios logueados y no logueados. Para el ejemplo que estamos trabajando nos da lo mismo si el usuario está logueado o no, y es por eso que debemos llamar a las dos acciones.

Una vez que nuestro formulario es enviado al servidor es capturado por la función donde tendremos 6 variables del tipo array con distintos valores para trabajar:

  • $_COOKIE: Un array con las cookies que genera WordPress y aquella que definamos nosotros para un determinado proyecto.
  • $_POST: Un array con los distintos valores del formulario (esta variable solo estará presente si se envía un formulario con el método POST).
    $_GET: Un array con valores pasados al servidor a través de variables GET (esta variable solo estará presente si se envían valores con el método GET).
  • $_REQUEST: Un array con los valores de $_POST, $_GET y $_COOKIE.
  • $_SERVER: Un array con todos los valores referentes a la petición HTTP (HTTP_REFERER, HTTP_USER_AGENT, REQUEST_TIME, etc).
  • $GLOBALS: Un array con todas las variables globales de WordPress (table_prefix, wp_query, wp_rewrite, etc).

Teniendo en cuenta la sintaxis de la acción y todas las variables con las que podemos trabajar tenemos las herramientas necesarias para definir el código final de nuestro ejemplo del formulario de contacto.

<?php
/**
 * Función para capturar los valores del
 * formulario de contacto del website.
 *
 * Los datos son enviados por email a mg@maugelves.com
 */
function enviar_formulario_por_email(){
	// Verificamos que los 2 campos tengan valores
	if( empty( $_POST['txtnombre'] ) || empty( $_POST['txtmensaje'] ) ):
		// Enviamos al usuario a la misma página con una variable GET de error.
		wp_redirect( add_query_arg( array( 'errormsg' => "Campos incompletos" ), get_home_url() . '/contacto') );
		exit;
	endif;

	// SIEMPRE SE DEBEN SANITIZAR LOS VALORES
	$nombre     = sanitize_text_field( $_POST['txtnombre'] );
	$mensaje    = sanitize_text_field( $_POST['txtmensaje'] );

	/*
	Una vez que tenemos los datos del formulario podemos
	hacer con ellos lo que nuestro proyecto web necesite, ej:
	a)  Enviar un email con esta información
	b)  Guardar los valores en base de datos
	c)  Hacer una nueva llamada POST a otro servicio que necesita
		esta información.
	En nuestro caso vamos a mandar un email con el nombre y el mensaje del usuario.
	*/
	wp_mail( "mg@maugelves.com", "Formulario de contacto", $nombre . " envió este mensaje => " . $mensaje  );

	/* Una vez que hayamos trabajado con los datos debemos
	redireccionar al usuario a la misma u a otra nueva página.
	En nuestro ejemplo, vamos a redirigirlo a la misma página
	de contacto con una variable de éxito.*/
	wp_redirect( get_home_url() . '/contacto?exito=1'); exit;

}
add_action('admin_post_nopriv_contacto', 'enviar_formulario_por_email');
add_action('admin_post_contacto', 'enviar_formulario_por_email');

Conclusión

Como han podido ver la captura de los datos es muy simple, una vez que podemos acceder a los valores podremos hacer con ellos cualquier requerimiento que se nos pida. Recuerda agregar seguridad a todos los formulario ya que son puertas de acceso a nuestro servidor. Para ello valida los datos desde el cliente con javascript y también en el servidor como hemos detallado en el ejemplo.

Ya no hay vuelta atrás, la próxima vez que te pidan un formulario piensa dos veces si realmente necesitas instalar un plugin para realizarlo.

¿Cómo incluir campos personalizados de ACF en plugins y temas?

Quien haya tenido la desgracia suerte de hablar un poco conmigo sobre informática sabrá que utilizo el plugin de campos personalizados ACF (Advanced Custom Fields) a menudo para el desarrollo de mis proyectos. Uno de los principales motivos es la velocidad con la que puedo generar la estructura de información en mis temas o plugins versus las mínimas complicaciones que este plugin pueda generar (duplicación de post_metas, sobrecarga en el administrador de WordPress).

Pero ahora bien, tanto los plugins como los temas que desarrollemos deben ser totalmente independientes ¿Qué quiero decir con esto? Que nuestros proyectos deben funcionar en cualquier instalación de WordPress, sin tener que estar nosotros instalando los plugins necesarios, migrando bases de datos o retocando configuraciones para que todo funcione normalmente. Entonces ¿Cómo podemos incluir los campos personalizados ACF en los plugins o temas que desarrolllamos? Muy simple:

  1. Incluyendo el plugin directamente dentro de nuestro tema o el mismo plugin.
  2. Creando una dependencia del plugin.

Incluir ACF en nuestro plugin o tema

Incluir ACF dentro del plugin o tema

Reglas oficiales para distribuir ACF en un plugin o tema

Según la documentación oficial podremos instalar distintas versiones de ACF (de pago o la gratuita) según la finalidad económica de nuestro plugin/tema:

Pasos para incluir el plugin de ACF en nuestros desarrollos

Son pocos y muy fáciles los pasos a seguir:

  1. Descarga una copia de la versión que necesites (respetando las reglas del punto anterior)
  2. Copia la carpeta con el plugin dentro de tu tema/plugin.
  3. Haz un include del archivo principal del plugin ACF.
  4. Configura los directorios y PATH del plugin.
  5. Opcional, puedes ocultar el menú de ACF en el administrador de WordPress.

Para los pasos 3, 4 y 5 abriremos nuestro fichero functions.php (del plugin o tema) y pegaremos el siguiente código. Modificar las rutas con el nombre de vuestro directorio de ACF.

https://gist.github.com/maugelves/d2082ecd69145ca37b1dbae1b93b1b9a

Crear una dependencia del plugin

Otra posible solución es declarar el plugin ACF como una dependencia de nuestro plugin. Esto significa que cuando se active el plugin o tema y no tengamos el plugin de ACF saldrá un mensaje advirtiéndonos que necesitamos instalarlo para el correcto funcionamiento.

Mensaje de dependencia del plugin Advanced Custom Field Pro
Mensaje de dependencia del plugin Advanced Custom Field Pro

Para declarar esta dependencia necesitaremos una pequeña librería de PHP llamada «TGM Plugin Activation» de la que tengo un artículo explicando cómo utilizarla.

Los pasos a seguir para declarar la dependencia son:

  1. Descargar la librería TGM Plugin Activation
  2. Hacer un include de la librería en nuestro fichero functions.php
  3. Declarar la dependencia del plugin gratuito o de pago según nuestras necesidades

A continuación detalle el código para cualquiera de las dos versiones del plugin:

Dependencia para la versión gratuita de ACF

Dependencia para la versión PRO de ACF


Conclusión

Dependiendo del proyecto, utilizar ACF puede ser una gran ventaja en ahorro de tiempo de desarrollo. Pero esto generará que nuestro desarrollo dependa de un plugin de terceros. Utilizando cualquier de estas dos técnicas podemos quedarnos tranquilos que nuestro código funcionará correctamente ¿Cuál de las dos técnicas utilizar? Como siempre, cada proyecto es único y debemos valorar cuál es la solución más óptima en cada caso.

Página 1 de 6

Funciona con WordPress & Tema de Anders Norén