Virtuemart

VirtueMart es componente de Joomla que nos da una solución de e-comercio. Ambos tiene la Licencia Pública General de GNU, por lo que son libres para su descarga, uso y modificación.
Te puedes descargar la ultima versión en su pagina oficial de virtuemart. Este paquete contiene 3 componente comprimidos, estos los tienes que instalar de forma independiente cada uno como cualquier otro componente de Joomla :
- CORE: El codigo del componente.
- AIO ( All in one): " Todo en uno" es decir plugins y modules de todo tipo para el componente (formas envío,formas de pago,....)
- TPDF : Librería que utiliza virtuemart para generar los pdf.
Tiene una web para la documentación muy amplia, tiene un foro que alimenta la comunidad de Virtuemart ademas de hacer soporte, tiene una API para hacer extensiones o plugins para interactuar con Virtuemart. Está traduccida a un mogollon de idiomas con sus paquetes, por supuesto tienes el paquete en español, a demas puedes participar en esas traducciones en transifex.
También podrías ver los cambios y como va el proyecto en el repositorio SVN.
Virtuemart fue la primera solución que convierta en un e-comerce tu Joomla, ambos fueron de la mano desde sus inicios, hoy en día, ya existen muchos mas componentes de Joomla que crean una tienda on-line y seguro que muy buenas, aunque nosotros seguimos siendo fieles a VIRTUEMART, el motivo principal es que lo conocemos su funcionamiento casi a la perfección.
- Andres Cordeiro
- Virtuemart
(Cómo funciona y por qué está planteado así)
El sistema de ruteo de SliderBuild está desarrollado en Vanilla PHP y parte de un principio deliberadamente simple: interpretar la URL para determinar con precisión qué datos deben consultarse y cómo deben devolverse.
Su responsabilidad es actuar como puente entre el CMS (Joomla / VirtueMart) y la cartelería digital, transformando consultas internas del sistema en respuestas JSON optimizadas para su consumo en pantalla.
En lugar de replicar lógica del CMS o crear múltiples endpoints especializados, el enfoque es más directo: la URL contiene toda la información necesaria. El sistema la analiza, identifica el tipo de consulta, aplica los modificadores indicados y construye la respuesta.
La URL no es solo una dirección: es la definición completa del comportamiento del slide.
1. Estructura de la URI
Formato base:
index.php?titulo={Personalizado}/{tipo}/{seccion}/{filtros}
Cada bloque tiene una responsabilidad clara dentro del flujo de ejecución. No hay ambigüedad: cada segmento activa una parte concreta del sistema.
1️⃣ Tipo
Es el primer nivel de decisión. Define qué estrategia de consulta se activa internamente:
homecategoriabusqueda
Desde un punto de vista técnico, este segmento equivale a seleccionar el controlador o el modo operativo. A partir de aquí, el sistema sabe qué tipo de datos debe solicitar al CMS.
Ejemplo:
index.php/home/ultimos-productos
El sistema interpreta que debe ejecutar una consulta global asociada al bloque “home”, no una navegación por categorías.
2️⃣ Sección
Define el recurso concreto sobre el que se va a trabajar. Puede representar:
- Una categoría principal
- Una subcategoría
- Una subcategoría de varios niveles
- Un término de búsqueda
Este bloque determina el alcance real de la consulta. El sistema no infiere nada adicional: ejecuta exactamente lo que se especifica.
Ejemplo conceptual:
index.php/categoria/bebidas
Devuelve únicamente los productos asociados a la categoría bebidas, sin incluir otras secciones.
3️⃣ Filtros
Son modificadores opcionales que ajustan el resultado, pero no cambian la fuente de datos. Permiten definir:
- Criterio de ordenación
- Dirección del orden
- Rango de resultados
En términos prácticos: primero se define qué se consulta (tipo y sección) y después cómo se quiere presentar.
4️⃣ Parámetros GET de personalización
Además de los segmentos que definen la lógica de consulta, el sistema admite parámetros GET destinados exclusivamente a personalizar la presentación del slider.
Estos parámetros no modifican la fuente de datos ni la consulta al CMS. Su función es alterar cómo se muestra la información en pantalla, manteniendo una separación clara entre:
- Lógica de datos (qué productos se obtienen)
- Lógica de presentación (cómo se visualizan)
Actualmente, los principales parámetros de personalización son:
?titulo=?cl=
?titulo=
Permite definir una rotulación personalizada para el slide, independientemente de la categoría o búsqueda utilizada.
Ejemplo:
index.php?titulo=OFERTAS SEMANA/categoria/lacteos
Aunque la consulta esté cargando la categoría lacteos, el encabezado visible en pantalla será “OFERTAS SEMANA”.
Este parámetro es especialmente útil cuando:
- Se quiere contextualizar visualmente una categoría existente.
- Se reutiliza una búsqueda técnica con una etiqueta comercial distinta.
- El término real de la consulta es demasiado largo para mostrarse como título.
?cl=
Permite definir el esquema de color del slider dentro de un conjunto de colores previamente configurados en el sistema.
No acepta valores arbitrarios, sino identificadores pertenecientes a una paleta predefinida en el archivo configuración. Esto garantiza coherencia visual y evita combinaciones fuera de estándar.
Ejemplo conceptual:
index.php?titulo=PACK AHORRO&cl=2/categoria/bebidas
En este caso:
- La consulta carga la categoría
bebidas. - El título visible será “PACK AHORRO”.
- El slider utilizará el esquema de color asociado al segundo color dentro del array definido en el archivo de configuración.
En conjunto, los parámetros GET permiten ajustar la identidad visual del slide sin alterar su comportamiento técnico. La URL sigue definiendo completamente el contenido, pero estos parámetros refinan la forma en la que dicho contenido se presenta.
2. Tipos de Consulta
2.1 Home
index.php/home/ultimos-productos
Este modo recupera productos definidos dentro del bloque “home” del CMS, como:
- Últimos productos añadidos
- Productos destacados
- Selecciones configuradas manualmente
No navega por categorías. Es una vista agregada pensada para bloques globales como “Novedades” o “Destacados”.
En este modo, los filtros avanzados pueden no tener efecto si el CMS no los admite para esa vista específica.
2.2 Categoría (Soporte multinivel)
index.php/categoria/{alias}
Permite recorrer la jerarquía completa de categorías definida en VirtueMart.
Para representar subniveles se utiliza el carácter:
~
Este símbolo sustituye a la barra / dentro de la jerarquía.
Ejemplo:
index.php/categoria/alimentacion~arroz-y-legumbres
Internamente equivale a:
alimentacion/arroz-y-legumbres
Si existe un nivel adicional:
index.php/categoria/alimentacion~arroz-y-legumbres~arroces
También puede accederse directamente si el CMS lo permite:
index.php/categoria/arroces
Ambas rutas terminan resolviendo en la categoría final arroces.
Importante:
- Las categorías son case sensitive.
- Deben escribirse en minúsculas.
- Los espacios se sustituyen por
-. - La jerarquía se representa con
~.
Ejemplo correcto:
index.php/categoria/cuidado-personal~higiene-bucal
2.3 Búsqueda
index.php/busqueda/{termino}
Replica el comportamiento del buscador del sitio.
Los espacios deben representarse con +, siguiendo el formato estándar de URLs.
Ejemplo básico:
index.php/busqueda/yogur+fresa
Este modo es especialmente útil cuando:
- No existe una categoría específica.
- Se quiere crear una colección puntual.
- Se trata de campañas temporales.
La consulta es case insensitive, lo que facilita la construcción de la URL. Puede copiarse directamente el valor de ?keyword= generado por el buscador del CMS.
Ejemplo de producto específico:
index.php/busqueda/Refresco+Pack+2+COCA+COLA+Original+2L
Esto permite generar un slide con un único producto sin necesidad de crear una categoría dedicada.
En búsquedas largas, se recomienda usar ?titulo= para evitar que el encabezado supere el límite visual (36 caracteres, normalmente distribuidos en 2 líneas).
index.php?titulo=PACK AHORRO/busqueda/Refresco+Pack+2+COCA+COLA+Original+2L
3. Filtrado y Ordenación
El sistema funciona como un proxy controlado: no reimplementa la lógica de VirtueMart, sino que traslada sus parámetros nativos dentro de la URL.
Ordenación
| Comando | Función |
|---|---|
/by,product_name |
Orden alfabético por nombre |
/by,product_price |
Orden por precio |
/by,product_sales |
Productos más vendidos |
/by,product_sku |
Orden por referencia |
/by,product_in_stock |
Orden por stock disponible |
/dirAsc |
Orden ascendente (por defecto suele ser descendente) |
Ejemplo:
index.php/categoria/bebidas/by,product_price/dirAsc
Devuelve los productos de la categoría bebidas ordenados de menor a mayor precio.
Paginación
/results,n-m
Define el rango exacto de productos que se devolverán.
Ejemplos:
/results,1-4
Muestra los productos del 1 al 4.
/results,5-8
Muestra los productos del 5 al 8.
Esto permite dividir un catálogo grande en varios slides sin añadir lógica adicional en el frontend.
Restricción importante: los rangos deben respetar bloques coherentes (normalmente múltiplos de 4, según configuración de VirtueMart).
Ejemplos correctos:
/results,1-4
/results,5-8
/results,1-20
/results,37-40
Ejemplos ajustados automáticamente:
/results,1-11 → se aproxima a /results,1-8
/results,3-8 → se ajusta al bloque válido más cercano
/results,1-21 → se aproxima a /results,1-20
Comprender esta lógica evita resultados inesperados en pantalla.
Limitaciones de los filtros
En aquellas situaciones en las que una consulta devuelve la totalidad de los resultados disponibles (por ejemplo, una categoría muy amplia sin límite de paginación), pueden producirse comportamientos no completamente predecibles en la ordenación.
Esto ocurre porque:
- El CMS puede aplicar la ordenación antes o después de ciertos procesos internos (joins, agrupaciones, disponibilidad, etc.).
- Algunas ordenaciones (como ventas o stock) pueden depender de datos agregados que no siempre se resuelven de forma óptima en consultas masivas.
- El volumen total de registros puede afectar a la consistencia del orden final cuando no se acota el rango.
Por este motivo, se recomienda aplicar ordenación únicamente cuando la consulta esté limitada mediante paginación en categorías o búsquedas.
Recomendación práctica
En lugar de:
index.php/categoria/bebidas/by,product_sales
Es preferible:
index.php/categoria/bebidas/by,product_sales/results,1-8
O en búsquedas:
index.php/busqueda/yogur+natural/by,product_price/dirAsc/results,1-4
De esta forma:
- La consulta se acota a un rango concreto.
- La ordenación se aplica sobre un conjunto controlado.
- El resultado es más consistente y predecible en pantalla.
En resumen, cuando se necesita ordenar, es buena práctica combinar siempre ordenación + paginación, especialmente en categorías amplias o búsquedas con muchos resultados. Esto evita efectos colaterales derivados de consultas demasiado extensas y mantiene el comportamiento del slide bajo control.
4. Ejemplo Completo
index.php?titulo=Nuestras Ofertas/categoria/lacteos~yogures-y-postres/by,product_price/dirAsc/results,1-4
Esta URL define completamente el comportamiento del slide:
- Personaliza el título como “Nuestras Ofertas”.
- Accede a la categoría principal
lacteos. - Entra en la subcategoría
yogures-y-postres. - Ordena los productos por precio.
- Aplica orden ascendente.
- Devuelve únicamente los cuatro primeros resultados.
No hay configuración adicional fuera de esta línea.
Conclusión
SliderBuild es actualmente un proyecto interno, en fase activa de desarrollo y evolución. No es una herramienta pública ni cerrada, sino una base técnica que se está consolidando progresivamente a partir de necesidades reales de operación.
En su estado actual, el sistema actúa como capa de integración entre CMS basados en Joomla + VirtueMart y entornos de cartelería digital, permitiendo transformar estructuras de catálogo en respuestas JSON controladas y predecibles.
El enfoque sigue siendo el mismo: que la URL defina completamente el comportamiento del slide, manteniendo el sistema ligero, desacoplado y fácil de mantener.
A medio plazo, la hoja de ruta contempla varias líneas de mejora:
- Ampliación de compatibilidad con otros sistemas, extendiendo el modelo actual más allá de Joomla + VirtueMart.
- Soporte de directorios y carpetas, para estructurar mejor configuraciones y recursos asociados a los slides.
- Incorporación de un scheduler, que permita programar activaciones, rotaciones o cambios automáticos sin intervención manual constante.
- Mayor diversidad de plantillas de slider, tanto en variedad visual como en flexibilidad estructural.
- Mejora progresiva de la calidad gráfica y de renderizado, optimizando legibilidad, jerarquía visual y adaptación a distintos formatos de pantalla.
El objetivo no es únicamente ampliar funcionalidades, sino consolidar una arquitectura sólida que permita crecer sin comprometer claridad ni mantenibilidad.
En definitiva, SliderBuild no es un producto terminado, sino una infraestructura en construcción: una base técnica pensada para escalar con orden, incorporando nuevas capacidades sin perder el principio que lo define — que el comportamiento esté explícitamente descrito y sea completamente controlable.
- Andres Cordeiro
- Virtuemart
Descripción del problema
Hace unos días detectamos un error puntual en una web de comercio electrónico basada en Joomla + VirtueMart. Al acceder a determinados productos desde el frontend, la página dejaba de cargarse y mostraba el siguiente mensaje:
0 Division by zero
El problema apareció justo después de una migración de servidor, lo que inicialmente nos llevó a pensar en un fallo de configuración, compatibilidad de versiones o estructura de categorías.
Proceso de análisis
El primer paso fue comprobar los elementos más evidentes:
- Verificación de categorías y subcategorías.
- Reasignación de productos a sus categorías correspondientes.
- Comprobación de menús y enlaces.
Sin embargo, el error persistía. Además, no solo se producía en el frontend: al acceder al administrador de VirtueMart y filtrar productos hasta llegar a la categoría afectada, el error volvía a aparecer exactamente igual.
Esto nos indicó que no se trataba de un problema de plantilla o vista, sino de algo más profundo, probablemente asociado a los propios datos del producto.
Para obtener mensajes de error más detallados, decidimos reproducir el entorno en una instalación local con una configuración menos restrictiva. Fue entonces cuando, al acceder a la misma categoría desde el administrador, apareció un mensaje mucho más revelador:
vmError: Img2Thumb NewImgCreate with imagecreatefromstring failed
Este error apuntaba directamente al sistema de creación de miniaturas (thumbnails) de VirtueMart.
Causa del problema
VirtueMart genera automáticamente miniaturas de las imágenes de producto utilizando librerías gráficas de PHP. Para ello, solo admite determinados formatos de imagen correctamente codificados.
En este caso, uno de los productos tenía asociada una imagen con una extensión válida a simple vista, pero que internamente no era procesable por el sistema de redimensionado. Al no poder obtener correctamente sus dimensiones, VirtueMart acababa realizando un cálculo inválido que desembocaba en un error de tipo división por cero.
Este comportamiento se manifestó de forma crítica en producción debido a un entorno PHP más estricto tras la migración, mientras que en local el sistema mostraba un error más descriptivo.
Solución aplicada
Para resolver el problema de forma segura, seguimos los siguientes pasos:
-
Desactivar temporalmente la creación automática de miniaturas Desde la configuración de VirtueMart, deshabilitamos la opción de redimensión dinámica de miniaturas dentro de la sección de archivos multimedia.
-
Corrección del producto afectado Accedimos al producto problemático, eliminamos la imagen asociada y guardamos los cambios. A continuación, subimos una nueva imagen válida y correctamente generada.
-
Reactivar la creación automática de miniaturas Una vez sustituida la imagen, volvimos a habilitar la generación automática de miniaturas.
Tras estos pasos, el error desapareció tanto en el frontend como en el backend.
Medidas preventivas
El tratamiento de imágenes en VirtueMart puede resultar especialmente delicado, sobre todo cuando las imágenes proceden de catálogos externos o proveedores.
Para evitar incidencias similares en el futuro, utilizamos un proceso automatizado de normalización de imágenes mediante scripts que:
- Reconvierte todas las imágenes a un formato estándar compatible.
- Garantiza una codificación correcta.
- Ajusta dimensiones y optimiza peso.
De este modo, todas las imágenes cumplen los requisitos necesarios antes de ser importadas al gestor de contenidos.
Conclusión
Aunque el error apareció tras una migración de servidor, la causa real no estaba en la infraestructura ni en la configuración de VirtueMart, sino en una imagen inválida que provocaba un fallo durante la generación de miniaturas.
La clave para resolver el problema fue reproducir el error en un entorno local y obtener mensajes más detallados. Una vez identificada la causa, la solución resultó sencilla.
Este tipo de incidencias pone de manifiesto la importancia de validar y estandarizar los recursos multimedia en plataformas de comercio electrónico para evitar errores difíciles de rastrear en producción.
Si recibes un email de tu web que en el asunto "Error con su forma de pago paypal en su tienda online" y en el body del email pone:
"Hola,
Error con su forma de pago paypal en su tienda Online. Los detalles están logueados en el archivo paypal.2.log.php
El equipo de VirtueMart"
No te asustes, es un error que se produjo en Pay Pal, en el archivo que indica, podras ver que tipo error fue.
Ahora voy tratar el siguiente error os indico que le apareció a varios clientes que les llevamos el mantenimiento web.
"ERROR checkPaypalIps: Error with REMOTE IP ADDRESS "
The remote address of the script posting to this notify script does not match a valid PayPal IP address
Si a ti, te aparece otro error no dudes en ponerte en contacto con nosotros y te lo estudiamos.
La intención con este post es ir anotando las errores que vamos encontrando para ello vamos diferencias cuando lo tenemos instalado en joomla 3.10.11 o en joomla 4.2.3, ya que hay errores diferentes en ambos.
Virtuemart 4.0.6.10690
- No encuentra en productos con la Ñ, en las versiones anteriores si lo hacía.
Busque cual era el error y encontré que en la clase de producto /administrator/components/com_virtuemart/models/product.php en la linea 454 tenía un filtro de string con el siguiente código:
$keyword = vRequest::filter(html_entity_decode($keyword, ENT_QUOTES, "UTF-8"),FILTER_SANITIZE_FULL_SPECIAL_CHARS,FILTER_FLAG_ENCODE_LOW);
Si lo sustituimos por uno menos estricto, por este:
$keyword = vRequest::filter(html_entity_decode($keyword, ENT_QUOTES, "UTF-8"),FILTER_SANITIZE_SPECIAL_CHARS,FILTER_FLAG_ENCODE_LOW);
Pues funciona , perfectamente.
El caso es que cuando fui ver si le podía mandar un issue a los creadores, me doy cuenta que en las nuevas versiones ya lo resolvieron, y lo cambiaron muchos mas ficheros, no me diera cuenta que fallaban también.
Llegué tarde :-)
Virtuemart genera json para metadatos en fichero sublayout/snippets.php
Nosotros nos encontramos con el dilema que nosotros redondeamos el precio a dos decimales, aunque en el metadatos ponemos todos los digitos, esto hace que google mechants nos rechace la ficha, ya que la web pone un precio y el metadato otro.
Para solicionarlo modificamos ese fichero en nuestra plantilla, redondeando el campo de precio : product->prices['salesPrice']
El codigo lo dejamos asi:
$description = str_replace('"','\"',htmlspecialchars(strip_tags($description)));
$PrecioFinal = number_format($product->prices['salesPrice'], 2, '.', ' '); // Precio ya con descuento..
?>.....
