PS PrestaShop Principiante

DataFirefly Live Counters — Guía completa

Instalar, configurar y explotar los 17 contadores animados de prueba social para PrestaShop 8 y 9: clientes, pedidos enviados, seguidores Facebook e Instagram, 5 temas visuales, caché multicapa y refresco AJAX en vivo.

Actualizado Versión del módulo 1.0.1

DataFirefly Live Counters muestra en tu tienda PrestaShop un widget de contadores animados alimentado en parte automáticamente por tu base (clientes activos, pedidos enviados, productos, países servidos) y en parte por valores que tú introduces (reseñas, satisfacción, seguidores en redes sociales…). El widget se engancha de forma nativa en varios hooks (home, footer, carrito, columnas) o en cualquier lugar de tu tema mediante la etiqueta Smarty widget name="dflivecounters". Esta documentación cubre la instalación, la configuración de los 17 contadores disponibles, los 5 temas visuales, la estrategia de caché, la conexión de las APIs de Facebook e Instagram, el refresco AJAX en vivo y la resolución de los principales problemas.

Instalación

  1. Descarga el archivo dflivecounters.zip desde tu cuenta DataFirefly.
  2. Back-office de PrestaShop → MódulosSubir un módulo → envía el ZIP.
  3. Al instalarse, el módulo registra 7 hooks de visualización e inicializa una decena de variables de configuración. No se crea ninguna tabla SQL: todos los ajustes se guardan en ps_configuration.
  4. El módulo carga su autoloader PSR-4 standalone — no se requiere ningún composer install en el servidor.

Compatible con PrestaShop 8.0 a 9.x, PHP 8.1+. Multi-tienda nativo, multiidioma vía Polylang Pro o el sistema multiidioma nativo de PrestaShop. Compatible con modo demo.

Apariencia del widget

Abre Módulos → DataFirefly Live Counters → Configurar. La primera sección agrupa los ajustes de apariencia global.

Tema visual

Cinco temas listos para usar:

  • Minimal: máxima sobriedad, fondo blanco, ideal para temas limpios.
  • Glassmorphism: vidrio esmerilado con backdrop-blur, fondo ligeramente teñido con el color primario. Muy de moda.
  • Gradient: fondo en degradado de ancho completo del color primario a un tono más oscuro. Gran impacto visual, texto blanco.
  • Card: tarjetas blancas elevadas con sombra suave y hover. Clásico premium.
  • Flat: fondo ligeramente teñido con el color primario, valores coloreados en primario.

Título y subtítulo

Mostrados sobre la cuadrícula de contadores. Déjalos vacíos para ocultar la cabecera (útil en el footer donde el contexto ya lo proporciona el entorno).

Colores

Tres colores principales dirigen todo el widget mediante variables CSS (--dflc-primary, --dflc-text, --dflc-bg):

  • Color primario: iconos por defecto, acento del tema Flat, degradado del tema Gradient.
  • Color del texto: título, subtítulo, valores y etiquetas.
  • Color de fondo: fondo de la sección (ignorado en los temas Glassmorphism y Gradient que aplican su propio fondo).

Cada contador también puede tener su propio color de icono (campo «Icon color» en la fila del contador), lo que te permite por ejemplo mantener los iconos de Facebook e Instagram en sus colores de marca conservando la coherencia del resto.

Columnas

Dos ajustes independientes:

  • Columnas desktop: 1 a 6 (por defecto 4).
  • Columnas mobile: 1 a 3 (por defecto 2). El breakpoint es 768 px.

Duración de la animación CountUp

Duración en milisegundos durante la cual las cifras se animan de 0 hasta su valor objetivo (por defecto 2 000 ms). Se aplica una curva ease-out cubic para una deceleración suave. Pon 0 para desactivar la animación y mostrar el valor final de inmediato.

En dispositivos con prefers-reduced-motion: reduce, la animación se desactiva automáticamente, sea cual sea la duración configurada.

Refresco AJAX en vivo (opcional)

Cuando se activa, el widget consulta periódicamente un endpoint JSON para actualizar los valores sin recargar la página. Dos parámetros:

  • Live refresh: ON/OFF.
  • Intervalo: en segundos, mínimo 30 (por defecto 60). Forzado a 30 si introduces menos.

El endpoint responde con un Cache-Control: public, max-age=30 que permite a tu CDN absorber el tráfico. La animación de transición de un valor al otro arranca desde el valor mostrado actualmente, no desde cero — el efecto visual es más natural.

«Date from»

Fecha de referencia usada por dos contadores:

  • Pedidos enviados: solo contabiliza los pedidos creados después de esta fecha (filtro WHERE date_add >= ?).
  • Años de experiencia: calcula automáticamente el número de años transcurridos desde esta fecha hasta hoy.

Catálogo de contadores

Hay 17 contadores disponibles, repartidos en tres grupos según su modo de cálculo.

Contadores automáticos (5)

Estos contadores leen en tiempo real los datos de tu PrestaShop. No requiere ninguna entrada.

  • Clientes: clientes activos (active = 1 AND deleted = 0), delimitados al shop context. TTL 15 min.
  • Pedidos enviados: pedidos cuyo historial de estados incluye al menos uno de los estados seleccionados (campo «Order states counted as shipped»). Si no se selecciona ningún estado, el módulo usa automáticamente el flag shipped = 1 de la tabla ps_order_state. TTL 15 min.
  • Pedidos procesados: todos los pedidos cuyo estado actual tiene el flag logable = 1 (el flag canónico de PrestaShop para los pedidos que cuentan en las estadísticas). Excluye por tanto cancelaciones y reembolsos. TTL 15 min.
  • Productos: productos activos y visibles del catálogo, delimitados al shop context. TTL 30 min.
  • Países servidos: número de países distintos que han recibido al menos un pedido (COUNT(DISTINCT id_country) sobre la tabla ps_address unida con ps_orders). TTL 1 h.

Contadores híbridos (4)

Estos contadores intentan primero un cálculo automático, luego recurren al valor manual que has introducido como respaldo.

  • Años de experiencia: calculado desde la «Date from»; valor manual si prefieres fijar una cifra redondeada (ej.: «12» en vez de «11»). TTL 24 h.
  • Artículos publicados: autodetección de las tablas de los principales módulos de blog de PrestaShop (smart_blog_post, prestablog_news, psblog_post, ph_simpleblog_post) vía INFORMATION_SCHEMA. Si no hay coincidencia, usa el valor manual. TTL 24 h.
  • Seguidores de Facebook: llamada a la Graph API de Facebook con un Page Access Token de larga duración. Respaldo manual si no está configurado o si la API falla. TTL 1 h.
  • Seguidores de Instagram: llamada a la Graph API de Instagram (cuenta Business o Creator requerida). Respaldo manual. TTL 1 h.

Contadores manuales (8)

Estos contadores muestran simplemente el valor que introduces. Ideales para métricas que PrestaShop no puede calcular o sobre las que quieres tener control total.

  • Reseñas de clientes: número de reseñas (desde Trustpilot, Avis Vérifiés, Google, etc.).
  • Satisfacción: tasa de satisfacción. Consejo: usa un sufijo «%» y un valor 0–100.
  • CO₂ ahorrado: kg de emisiones evitadas. Consejo: sufijo «kg».
  • Premios: premios, certificaciones, distinciones.
  • Horas de soporte: sufijo «h».
  • Seguidores de TikTok: la Display API de TikTok requiere un OAuth por usuario impracticable para un widget público. Entrada manual.
  • Seguidores de X (Twitter): la X API v2 es de pago. Entrada manual.
  • Seguidores de LinkedIn: LinkedIn Organization Followers exige una aprobación Marketing Developer Platform. Entrada manual.

Configuración por contador

Cada fila de contador en el admin propone los mismos ajustes:

  • Activado (ON/OFF): solo los contadores activados aparecen en el widget. El orden de visualización sigue el del admin.
  • Etiqueta personalizada: reemplaza la etiqueta por defecto. Déjala vacía para usar la etiqueta nativa traducida al idioma del visitante.
  • Valor (manual): para los contadores manuales y el respaldo de los híbridos.
  • Offset: entero añadido al valor calculado. Útil para partir de una cifra más atractiva sin tocar la base de datos. Para los contadores «Clientes» y «Pedidos enviados» por ejemplo, puedes añadir respectivamente +500 y +2 000 si tu tienda acaba de migrar. La etiqueta «Current live» junto al campo Offset te indica el valor bruto calculado por PrestaShop, sin offset.
  • Prefijo / Sufijo: 4 y 6 caracteres respectivamente. El prefijo y el sufijo permanecen fijos incluso durante la animación.
  • Decimales: 0 a 3. El formato usa Intl.NumberFormat con la locale del visitante (separadores de miles y coma decimal localizados).
  • Color de icono: reemplaza el color primario para ese icono únicamente.

Las etiquetas personalizadas se almacenan en configuración por tienda y por idioma vía el sistema nativo de PrestaShop. Así puedes tener «Clientes felices» en español y «Happy customers» en inglés — o incluso una etiqueta diferente por tienda en multi-tienda.

Estados de pedido «enviados»

El contador «Pedidos enviados» se apoya por defecto en el historial de estados. El ajuste Order states counted as shipped te permite elegir con precisión qué estados cuentan. En una instalación PrestaShop estándar, son los estados con ID 4 (Enviado) y 5 (Entregado) los que están preseleccionados.

Si tu tienda usa estados personalizados (ej.: «Recogida en tienda», «Click & Collect recogido»), no olvides añadirlos a la selección — de lo contrario estos pedidos no se contabilizarán.

Si no se selecciona ningún estado, el módulo recurre a un fallback que consulta el flag shipped = 1 de la tabla ps_order_state. Este enfoque es más permisivo y captura la mayoría de las configuraciones comunes.

Configurar Facebook

  1. Ve a developers.facebook.com y crea una App de tipo «Business».
  2. En la sección Graph API Explorer, selecciona tu App y luego tu Página de Facebook.
  3. Genera un Page Access Token con los scopes pages_read_engagement y pages_show_list.
  4. Intercambia este token corto (1 h) por un token de larga duración (60 días) vía el endpoint /oauth/access_token?grant_type=fb_exchange_token.
  5. Obtén tu Page ID en los ajustes de tu Página (sección «Transparencia de la Página», o directamente en el Graph API Explorer).
  6. Rellena los dos campos en la configuración de Live Counters y guarda. El contador de Facebook se actualiza al guardar.

El token de larga duración expira a los 60 días. Pasado ese tiempo, el contador recurre al respaldo manual. Ponte un recordatorio para renovar el token antes de la expiración.

Configurar Instagram

  1. Tu cuenta de Instagram debe estar en modo Business o Creator. Las cuentas personales no están soportadas por la Graph API.
  2. Vincula tu cuenta de Instagram a una Página de Facebook (ajustes de la Página → Instagram).
  3. En el Graph API Explorer, consulta /me/accounts con tu Page Access Token para recuperar el Instagram User ID asociado (campo instagram_business_account).
  4. Usa el mismo token de Facebook de larga duración para la API de Instagram.
  5. Rellena el IG User ID y el token en la configuración de Live Counters.

Estrategia de caché

El caché funciona en dos niveles para garantizar un TTFB constante incluso bajo tráfico.

Caché por contador

Cada contador tiene su propio TTL:

  • 15 minutos: Clientes, Pedidos enviados, Pedidos procesados.
  • 30 minutos: Productos.
  • 1 hora: Países servidos, Facebook, Instagram.
  • 24 horas: Años de experiencia, Artículos publicados, y todos los contadores manuales.

El caché usa primero la capa Cache nativa de PrestaShop (memcached, APCu o Redis si están configurados en tu servidor), luego un fallback filesystem en var/cache/dflivecounters/. Esto garantiza que los TTL se respeten incluso si la capa nativa está en modo «no-cache».

Caché del widget renderizado

El HTML completo del widget se cachea él mismo durante 60 segundos por idioma y por hook (dflc_widget_LANG_HASH). Esta segunda capa absorbe la mayoría del tráfico incluso cuando los contadores internos ya están al día.

Purga automática

  • Guardar la configuración purga automáticamente todas las cachés del módulo.
  • Un botón Purgar caché está disponible en el panel de admin para invalidación manual.
  • La desinstalación del módulo purga el caché automáticamente.

El panel de admin muestra las estadísticas en directo: número de entradas en caché, tamaño en KB, ruta de la carpeta. Útil para verificar que el caché filesystem está activo.

Colocar el widget en tu tema

El módulo registra 7 hooks al instalarse:

  • displayHome — página de inicio
  • displayFooter — pie de página
  • displayFooterBefore — justo antes del footer (PS 8+)
  • displayLeftColumn / displayRightColumn — columnas laterales
  • displayShoppingCartFooter — página de carrito, bajo el resumen
  • actionFrontControllerSetMedia — registra los assets CSS/JS

Puedes añadir o quitar hooks desde Diseño → Posiciones en el back-office.

Colocación libre vía Smarty

Para colocar el widget en un punto preciso de tu tema (ej.: en la ficha de producto, bajo el título de una categoría), usa la etiqueta widget Smarty:

{widget name="dflivecounters"}

El widget implementa la interfaz WidgetInterface nativa de PrestaShop, lo que lo hace invocable desde cualquier plantilla .tpl de tu tema.

Personalizar la plantilla del widget

La plantilla Smarty principal es views/templates/hook/widget.tpl. Para sobreescribirla sin modificar el módulo (para preservar las actualizaciones), cópiala en tu tema, en la carpeta themes/tu-tema/modules/dflivecounters/views/templates/hook/widget.tpl.

Variables Smarty expuestas:

  • {$dflc.counters} — array de cada contador con las claves key, label, value, icon, prefix, suffix, decimals, icon_color
  • {$dflc.theme} — slug del tema (minimal, glassmorphism, gradient, card, flat)
  • {$dflc.title}, {$dflc.subtitle}
  • {$dflc.primary_color}, {$dflc.text_color}, {$dflc.bg_color}
  • {$dflc.cols_desktop}, {$dflc.cols_mobile}
  • {$dflc.hook} — nombre del hook de origen (útil para adaptar el renderizado según la colocación)

Endpoint AJAX

El controlador front refresh expone una URL JSON utilizable por el live refresh o por cualquier integración de terceros:

index.php?fc=module&module=dflivecounters&controller=refresh

La respuesta JSON contiene un booleano success, un timestamp Unix, y un objeto counters donde cada clave es el identificador del contador (customers, shipped_orders, facebook, instagram, etc.) y cada valor es el número actual. El contenido refleja los contadores activados en el momento de la llamada, con los offsets aplicados. La respuesta se sirve con Cache-Control: public, max-age=30.

Accesibilidad

El widget está diseñado para respetar las recomendaciones WCAG 2.2 AA:

  • Estructura semántica: section, header, ul role="list", li.
  • Todos los iconos SVG tienen aria-hidden="true" (decorativos).
  • Respeto estricto de prefers-reduced-motion: reduce: animación desactivada, valor final mostrado de inmediato.
  • Contrastes: los colores por defecto respetan una ratio superior a 4.5:1 en los temas Minimal y Card. Verifica tus colores personalizados con una herramienta como axe DevTools.
  • Formato de los números: font-variant-numeric: tabular-nums para un ancho de cifra constante (evita el «salto» visual durante la animación).

RGPD

El widget está diseñado para no requerir ninguna mención de consentimiento:

  • Ninguna cookie depositada del lado del visitante.
  • Ningún script de terceros cargado (sin Facebook Pixel, sin Google Tag Manager).
  • Las llamadas API de Facebook e Instagram se realizan del lado del servidor en PHP, nunca desde el navegador. Ningún dato del visitante se transmite a Meta.
  • Ningún dato personal recopilado o almacenado por el módulo.

Compatibilidad y notas técnicas

  • PrestaShop 8.0 a 9.x, PHP 8.1+.
  • Multi-tienda nativo: todas las consultas SQL están delimitadas al Shop::getContextListShopID().
  • Multiidioma: Polylang Pro o sistema multiidioma nativo de PrestaShop.
  • Ninguna tabla SQL creada: configuración almacenada en ps_configuration.
  • Autoloader PSR-4 standalone (sin composer install en el servidor).
  • WidgetInterface nativo de PrestaShop: utilizable vía {widget name="dflivecounters"}.
  • Peso de los assets: 3 KB JS, 2 KB CSS. Ninguna petición externa por defecto.
  • Conforme con las convenciones AJAX de PrestaShop 9: $this->module->l() en lugar de $this->l(), controlador front dedicado para el refresco, nunca sobreescribe ajaxRender.

FAQ y resolución de problemas

El widget no aparece en la página de inicio. Comprueba que el módulo está enganchado al hook displayHome en Diseño → Posiciones. Comprueba también que al menos un contador esté activado: sin ningún contador activado, el widget no devuelve nada (silenciosamente).

El contador de Facebook se queda a cero. Varias causas posibles: Page ID incorrecto, token caducado (vida útil 60 días), scope ausente (pages_read_engagement es obligatorio). Purga el caché del módulo y recarga la configuración: el valor devuelto por la Graph API aparecerá junto a la etiqueta «Current live».

El contador Pedidos enviados es demasiado bajo. Comprueba la selección «Order states counted as shipped»: solo cuentan los estados seleccionados. Si quieres incluir estados personalizados (ej.: «Click & Collect recogido»), añádelos a la selección.

Los números parecen congelados y no reflejan mi tráfico real. Es el caché haciendo su trabajo. El TTL por defecto va de 15 minutos (clientes, pedidos) a 24 horas (contadores estáticos). Usa el botón Purgar caché para invalidar manualmente. Para un refresco automático, activa el modo Live refresh.

La animación CountUp no se dispara. El widget usa IntersectionObserver y se dispara en el momento en que entra en el viewport. Si el widget ya está visible al cargar la página (ej.: colocado en la parte superior), la animación arranca de inmediato. Si se queda congelada en cero: revisa la consola JavaScript de tu navegador, otro módulo podría estar rompiendo el bundle JS.

El widget rompe mi Lighthouse / Core Web Vitals. Con una colocación al pie de página (footer) y el caché de 60 s sobre el HTML renderizado, el impacto CLS / LCP es insignificante. Si ves un problema, comprueba que no has activado el Live refresh con un intervalo demasiado corto (el AJAX se dispara mientras Lighthouse mide). Para una auditoría limpia, desactiva el live refresh.

En multi-tienda, ¿los contadores están delimitados por tienda? Sí. Todas las consultas SQL usan Shop::getContextListShopID(). En modo «todas las tiendas», los contadores acumulan; en modo «una tienda», solo cuentan esa. Las etiquetas y el valor manual también son por-tienda-por-idioma.

¿Cómo añado un nuevo contador personalizado? Crea una clase que extienda Df/LiveCounters/Counter/AbstractCounter (o ManualCounter para un contador 100% manual), implementa getKey(), getDefaultLabel() y getValue(), luego añade la instancia al array de instancias del CounterRegistry. Para no perder tu código en la próxima actualización, crea un mini-módulo compañero que inyecte tu contador en el registry vía un hook personalizado — no dudes en contactarnos para un ejemplo.

¿Te ha resultado útil esta página?

¿Sigues atascado? Contacta con soporte