El selector de monedas no funciona con un plugin de caché en WordPress
Un selector de monedas que no funciona con un plugin de caché en WordPress suele mostrar uno de cuatro síntomas: los precios siguen en la moneda base después de cambiar, la moneda vuelve a la predeterminada en la página siguiente, hacer clic en el selector no hace nada, o todo funciona mientras tienes la sesión iniciada y falla para los visitantes. Dos cosas distintas lo causan. Una caché de página sirve HTML almacenado que se construyó para otro visitante, y la optimización de JavaScript (retrasar, diferir, minificar, combinar) rompe el orden en que se ejecutan los scripts del selector. Ambas tienen una solución que conserva tu caché y tus puntuaciones de velocidad.
Por qué una caché de página rompe el cambio de moneda
El shortcode [wpcs_price] convierte el importe en PHP mientras WordPress construye la página. Una caché de página guarda ese HTML terminado y envía la misma copia a los siguientes visitantes, de modo que todos ven la moneda del visitante que llenó la caché. La moneda elegida por el visitante sigue recordándose, pero PHP nunca se ejecuta para una página en caché, así que nada la usa.
La solución está en Ajustes → Currency Switcher → Opciones (Options): establece Uso un plugin de caché en mi sitio (I am using cache plugin on my site) en Sí (Yes). Con esta opción activada, la página se carga desde la caché y después el script del plugin front.js:
- recoge todos los precios impresos por
[wpcs_price](cada uno es unspan.wpcs_priceque lleva su importe original endata-amount); - envía una solicitud POST a
/wp-admin/admin-ajax.phpconaction=wpcs_get_prices_html; - sustituye los precios por la respuesta, que se calcula para este visitante, y ajusta el selector a la moneda del visitante.
Tres detalles importan cuando buscas el fallo:
- Hasta que llega esa respuesta, el selector ignora los clics, de modo que nunca cambia a partir de un estado obsoleto. Si la solicitud se bloquea o falla, el selector queda inerte. Es un motivo típico de «hacer clic no hace nada».
- La opción se escribe en la página como una pequeña variable de script. Las páginas guardadas en caché antes de cambiarla siguen llevando el valor antiguo, así que vacía todas las capas de caché después de guardar: plugin de caché, caché del servidor y CDN.
- Solo se vuelven a dibujar los precios de
[wpcs_price]. Una etiqueta[wpcs_current_currency], o los valores impresos por código PHP en una plantilla con $WPCS->wpcs_exchange_value(), se quedan como estaban en la caché. Excluye de la caché de página las páginas que dependan de ellos.
La misma solicitud aplica también las reglas GeoIP a los visitantes de páginas en caché; si la propia detección es incorrecta, consulta la detección de moneda por GeoIP no funciona.
¿La solicitud wpcs_get_prices_html ralentiza el sitio?
Las pruebas de velocidad como GTmetrix muestran un POST a admin-ajax.php con wpcs_get_prices_html cerca del final de la cascada, a veces con un tiempo largo al lado. Esto es lo que cuesta realmente:
- Es una solicitud por visualización de página, enviada en cada página que carga el script del plugin, porque el selector necesita la moneda del visitante incluso donde no se muestra ningún precio. Se envían como máximo 500 precios en una solicitud.
- Empieza después de analizar el HTML y no impide que la página se muestre. El visitante ve primero la página; los precios se actualizan un instante después.
- Su duración es aproximadamente el tiempo que WordPress necesita para cargar sin caché de página. En un sitio sano, es una fracción de segundo. Si tarda varios segundos, cada solicitud sin caché del sitio es así de lenta, y la causa está en los plugins o en el hosting, no en esta solicitud.
- Con JavaScript retrasado hasta la primera interacción, la solicitud empieza solo cuando la herramienta de pruebas simula una, por lo que aparece tarde e infla el tiempo de «carga completa» sin afectar a lo que ve el visitante.
Desactiva la opción solo si ninguna caché de página almacena tus páginas: ni plugin de caché, ni caché del servidor, ni CDN que almacene HTML. Entonces PHP imprime directamente la moneda correcta. Con cualquier caché de página activa, desactivarla rompe el cambio de moneda para los visitantes.
Encuentra los errores de JavaScript antes de cambiar ajustes
Prueba en una ventana privada donde no hayas iniciado sesión. Las cachés de página y la mayoría de los plugins de optimización omiten a los administradores con sesión iniciada, por eso el selector puede funcionar perfectamente para ti y fallar para todos los visitantes. Abre las herramientas para desarrolladores (F12), recarga y mira la Consola (Console):
| Mensaje de la consola | Qué ocurrió |
|---|---|
wpcs_array_of_get is not defined o wpcs_current_currency is not defined | El pequeño script en línea con los ajustes del selector se retrasó o se movió por debajo de los archivos de script del plugin |
jQuery is not defined | jQuery se retrasó o se difirió mientras se ejecutaban scripts que lo necesitan |
| Errores en un archivo combinado o minificado | Cualquier error en un archivo combinado detiene el código que viene después, selector incluido |
Después abre la pestaña Red (Network), escribe admin-ajax en el filtro y haz clic en la solicitud con wpcs_get_prices_html. Una respuesta correcta tiene el estado 200 y empieza con {"prices":. El estado 403 significa que la solicitud está bloqueada (consulta la última sección). Texto o HTML antes de la llave de apertura significa que otro plugin o un aviso de PHP imprimió salida dentro de la respuesta; el script no puede leerla, así que los precios se quedan como en la caché y el selector queda bloqueado. Ninguna solicitud con la opción activada significa que el script nunca se ejecutó: vuelve a la consola.
WP Rocket, Perfmatters y otros optimizadores: qué excluir
El selector necesita tres cosas que se ejecuten en orden: jQuery, el script en línea de ajustes que el plugin imprime en el head de la página, y los archivos de la carpeta js del plugin (front.js más la biblioteca de la vista de tu menú desplegable: ddslick, chosen o wSelect, y los scripts de Designer si los usas). Retrasar solo algunos de ellos provoca los errores not defined de arriba.
En WP Rocket, ve a Optimización de archivos (File Optimization) y añade estas líneas a Archivos JavaScript excluidos (Excluded JavaScript Files) bajo Retrasar la ejecución de JavaScript (Delay JavaScript execution):
/wp-content/plugins/currency-switcher/
wpcs_
/jquery-?[0-9.](.*)(.min|.slim|.slim.min)?.js
/jquery-migrate(.min)?.js
La primera línea cubre los archivos del plugin, wpcs_ es una palabra clave presente en el script en línea de ajustes, y las dos últimas líneas evitan que se retrase jQuery. Si siguen apareciendo errores con Cargar JavaScript diferido (Load JavaScript deferred) activado, excluye también ahí la carpeta del plugin. WP Rocket explica ambos campos en Delay JavaScript execution y Exclude files from Load JavaScript deferred.
Otras herramientas tienen los mismos interruptores con nombres distintos: retraso de scripts en Perfmatters, minificar y fusionar en WP-Optimize, minificar y combinar en W3 Total Cache. Excluye la misma carpeta del plugin y jQuery, o desactiva la combinación como prueba. Si el selector funciona con el optimizador desactivado, el problema es su configuración, y la consola te dice qué archivo está afectado.
Después de cada cambio, vacía la caché y los archivos generados por el optimizador (la mayoría de los plugins reconstruyen los archivos minificados y combinados al vaciar su caché), purga la CDN y recarga con Ctrl+F5. Probar contra archivos optimizados antiguos es el motivo más común por el que una exclusión correcta parece no funcionar.
Caché del servidor que no puedes desactivar
Los hostings gestionados suelen ejecutar su propia caché de página, que no se puede desactivar. Establece Uso un plugin de caché en mi sitio (I am using cache plugin on my site) en Sí (Yes) y vacía la caché del hosting después del cambio.
Deja Sin datos GET en el enlace (No GET data in link) en No: el selector envía entonces al visitante a la misma página con ?currency=EUR, PHP construye esa página y almacena la elección. Esto solo funciona mientras las URL con ese parámetro no se sirvan desde la caché. Muchas cachés de página omiten las URL con cadenas de consulta, pero algunas cachés de hosting almacenan cada una como una página aparte. Entonces la elección nunca se almacena y la página siguiente vuelve a la moneda anterior. Pide al hosting que omita la caché para el parámetro currency. Si no pueden, establece Sin datos GET en el enlace (No GET data in link) en Sí (Yes). La elección se guarda entonces mediante una solicitud a admin-ajax.php (wpcs_set_currency_ajax), que las cachés de página no almacenan, y la página recargada vuelve a dibujar sus precios. El mismo parámetro ?currency= permite además enlazar a una página en una moneda determinada, como se muestra en enlaces de moneda sin shortcode.
Solicitudes bloqueadas: «You do not have sufficient permissions» y 403
Cuando los visitantes que no han iniciado sesión ven You do not have sufficient permissions to access this page al cambiar, o las solicitudes anteriores devuelven 403, algo bloquea admin-ajax.php para las solicitudes anónimas: el cortafuegos de un plugin de seguridad, una función de «ocultar o bloquear wp-admin», una regla del cortafuegos del hosting o la protección con contraseña de la carpeta /wp-admin/. El plugin usa admin-ajax.php para estas acciones:
wpcs_get_prices_html: redibujado de precios en páginas en caché;wpcs_set_currency_ajax: cambio de moneda cuando Sin datos GET en el enlace (No GET data in link) está en Sí (Yes);wpcs_convert_currencyywpcs_rates_current_currency: los shortcodes del conversor y de los tipos de cambio.
Desactiva los plugins de seguridad y de optimización de uno en uno en una copia de pruebas hasta que la solicitud devuelva 200; después permite admin-ajax.php con estas acciones en los ajustes de ese plugin, o pide al hosting que lo excluya de su regla del cortafuegos.
Lista de comprobación
- Probado sin sesión iniciada en una ventana privada, tras vaciar todas las cachés y pulsar Ctrl+F5.
- Uso un plugin de caché en mi sitio (I am using cache plugin on my site) está en Sí (Yes) dondequiera que haya una caché de página activa.
- Sin errores en rojo en la consola; la solicitud
wpcs_get_prices_htmldevuelve 200 y empieza con{"prices":. - La carpeta del plugin, el script en línea
wpcs_y jQuery están excluidos del retraso, el diferido y la combinación. admin-ajax.phpno está bloqueado para los visitantes.- Las URL con
?currency=no se sirven desde la caché, o Sin datos GET en el enlace (No GET data in link) está en Sí (Yes).
Si el selector sigue fallando, abre un tema en el foro de soporte de WPCS con el enlace de la página, los errores de la consola, el estado y la respuesta de la solicitud a admin-ajax y la lista de herramientas de caché y de optimización del sitio.