Joomla

Joomla es mi CMS preferido, que permite desarrollar todo sitios web dinámicos e interactivos, una simple web , un blog, una tienda online, lo que se te ocurra se puede hacer con Joomla.
Su nombre es una pronunciación fonética para anglófonos de la palabra swahili jumla, que significa "todos juntos" o "como un todo". Se escogió como una reflexión del compromiso del grupo de desarrolladores Joomla y la comunidad del proyecto.
Es desarrollado principalmente en PHP ,puede ver en este link Requisitos software para cada versión Joomla de la pagina Oficial
Mas información y descarga de la Pagina Oficial.
- Andres Cordeiro
- Joomla
Introducción
Hace unas semanas nos encontramos con un problema bastante molesto en un sitio Joomla 5. Al intentar indexar el Buscador Inteligente (Smart Search), aparecía el siguiente mensaje de error:
Se ha producido un error
Duplicate entry 'dirección-*' for key 'idx_term_language'
El indexador se detenía inmediatamente, sin importar cuántos artículos teníamos ni qué plugins estaban activos. Este fallo impedía que la búsqueda inteligente funcionara, lo que afecta directamente a la experiencia de los usuarios al buscar contenido en el sitio.
En esta entrada quiero contaros cómo detectamos el error, qué pruebas realizamos y la solución que finalmente funcionó, paso a paso, para que podáis aplicarla vosotros si os encontráis en la misma situación.
Cómo detectamos el error
Lo primero que hicimos fue mirar la tabla donde se almacenan los términos indexados por Smart Search: finder_terms. Ejecutamos un simple SELECT COUNT(*) para ver si había algún registro previo que pudiera causar el duplicado:
SELECT COUNT(*) FROM finder_terms;
El resultado fue 0 registros. Esto nos confirmó que el error no se debía a datos existentes, sino que Joomla estaba generando el mismo término dos veces en memoria durante el proceso de indexación.
A continuación, revisamos el índice que bloqueaba la inserción:
SHOW INDEX FROM finder_terms WHERE Key_name='idx_term_language';
Todo estaba correcto: era un índice UNIQUE sobre las columnas (term, language). Por tanto, la base de datos estaba funcionando bien, y el problema estaba en la lógica de Joomla, no en la tabla ni en el índice.
¿A qué se debe este problema?
Tras investigar, descubrimos que el error ocurre principalmente por tres motivos:
-
Normalización Unicode en PHP: Joomla genera los términos internamente y normaliza los caracteres especiales. Por ejemplo,
direcciónse convierte en dos versiones que para PHP parecen distintas pero MySQL las considera iguales. -
Collation de la base de datos: con la configuración por defecto (
utf8mb4_unicode_ci), MySQL no distingue correctamente ciertos acentos, lo que provoca que detecte duplicados. -
Idioma global (
*): Joomla asigna el mismo término a todos los idiomas, aumentando la probabilidad de que se produzca un conflicto.
En pocas palabras, el duplicado no estaba en la base de datos, sino que se generaba durante la creación de términos en memoria, justo antes de insertarlos.
Solución paso a paso
Después de analizar el problema, aplicamos la siguiente solución:
- Vaciar la tabla de términos:
TRUNCATE TABLE finder_terms;
Esto eliminó cualquier posible registro residual y nos dio un punto de partida limpio.
- Cambiar la collation de la columna
terma binaria:
ALTER TABLE finder_terms
MODIFY COLUMN term VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL;
¿Por qué esto funciona?
utf8mb4_bindistingue mayúsculas, minúsculas y acentos.- Evita que MySQL considere duplicados términos que solo se diferencian por un acento.
-
Permite que Joomla inserte todos los términos, incluso con caracteres especiales o multilenguaje, sin que el índice UNIQUE bloquee la operación.
-
Reindexar desde Joomla:
- Backend → Smart Search → Clear Index
- Backend → Smart Search → Index
El proceso se completó sin errores, y ahora todos los términos se insertan correctamente, incluyendo “dirección” y otros con acentos.
Medidas preventivas
Para que este error no vuelva a aparecer:
- Hacer siempre un backup completo antes de modificar tablas o collation.
- Revisar los plugins de campos personalizados o SEO, ya que pueden generar tokens duplicados.
- Evitar duplicar contenido con caracteres especiales en idioma global.
- Comprobar periódicamente que Smart Search puede indexar sin problemas tras cambios importantes en el sitio.
Conclusión
El error Duplicate entry 'dirección-*' for key 'idx_term_language' en Joomla 5 es un caso típico de colisión de términos generados internamente, causado por la normalización Unicode y la collation de la base de datos.
Vaciar la tabla de términos y aplicar collation binaria a la columna term es la forma más efectiva de solucionarlo. Tras aplicar estos pasos, el Buscador Inteligente funciona correctamente, incluso con contenido multilenguaje y caracteres especiales.
Si alguna vez os encontráis con un error similar, ahora sabéis cómo identificarlo y solucionarlo paso a paso, sin afectar la integridad de vuestro sitio.
- 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.
- Andres Cordeiro
- Joomla
Introducción
En los últimos días nos encontramos con un problema curioso en uno de nuestros sitios web desarrollados en Joomla. Cada vez que intentábamos guardar un artículo o simplemente cerrar la ventana de edición, aparecía un mensaje de error 403 Forbidden que impedía completar la acción. A simple vista podía parecer un fallo de Joomla, de permisos o incluso del formulario, pero después de revisarlo a fondo vimos que la causa era mucho más concreta y, sobre todo, más común de lo que parece.
En esta entrada os contamos cómo detectar este tipo de errores cuando Joomla no permite guardar un artículo y qué medidas tomar para solucionarlo. Y, como siempre, aunque nuestro caso tiene un origen muy definido, es posible que en otras instalaciones el fallo responda a motivos distintos. Si os ocurre algo parecido pero no encaja con lo que explicamos aquí, estaremos encantados de leerlo en los comentarios.
Cómo detectar el error
Lo primero que hicimos fue fijarnos bien en el comportamiento del sistema: el error no aparecía en todos los artículos, sino únicamente en uno muy concreto. Así que revisamos su contenido y, como suele recomendarse en estos casos, analizamos también la petición POST que Joomla envía al servidor al pulsar “Guardar” o “Cerrar”.
En esa petición se incluían todos los campos jform[...] del artículo, pero lo interesante era el volumen de información que contenía:
- Etiquetas HTML completas
- Múltiples
<img>con rutas largas - Atributos con comillas
- Títulos con caracteres especiales
- Texto codificado para el formulario
Todo ello encajaba bastante bien con un patrón típico: mod_security —el firewall web que usan muchos hostings— suele bloquear peticiones que contienen combinaciones de HTML, comillas, rutas o parámetros extensos si considera que podrían ser peligrosas.
Para confirmar esta teoría, comparamos nuestro caso con otros problemas documentados tanto en el bug tracker de Joomla como en foros de usuarios. La coincidencia era clara: si un artículo con cierto contenido HTML generaba un 403 Forbidden al guardarse, casi siempre estaba relacionado con una regla del firewall del servidor, no con Joomla.
¿A qué se debe este problema?
El error surge porque el firewall del servidor interpreta parte de la información del artículo como una posible amenaza. No importa que el contenido sea legítimo: si coincide con una regla predefinida de mod_security, la acción se bloquea antes incluso de que Joomla llegue a procesarla.
En nuestro caso, el artículo incluía varias imágenes, atributos HTML y caracteres codificados que hacían saltar una de esas reglas. Y como consecuencia, cada intento de guardar o cerrar terminaba en el mismo mensaje: 403 Forbidden.
Solución paso a paso
Una vez detectado el origen del problema, las soluciones eran bastante claras. Estas son las que recomendamos:
1. Revisar mod_security con el hosting
La solución más efectiva es contactar con el proveedor de hosting y pedir que revisen los registros de mod_security. Ellos pueden localizar la regla exacta que se está activando y añadir una excepción para la URL de edición de artículos o para esa regla concreta.
2. Desactivar temporalmente mod_security
Muchos paneles de hosting permiten desactivarlo momentáneamente. Si al hacerlo el artículo se guarda sin problemas, ya está confirmado: el bloqueo venía del firewall.
3. Simplificar el contenido para probar
Otra prueba útil consiste en eliminar parte del contenido del artículo hasta que deje de fallar. Si sin imágenes funciona, y con imágenes vuelve a fallar, también apuntamos directamente al firewall.
4. Revisar permisos y archivo .htaccess
Aunque en nuestro caso no fue necesario, conviene comprobar que los permisos del sitio y las reglas del .htaccess no estén añadiendo restricciones adicionales.
Con cualquiera de estos pasos debería ser posible guardar el artículo sin problemas y continuar trabajando con normalidad.
Notas finales
Aunque este error concreto se debía claramente a mod_security, es importante recordar que otros factores pueden provocar fallos similares al guardar artículos en Joomla. Por ejemplo, contenido mal codificado, caracteres no permitidos en la base de datos o incluso algo tan simple como un emoji que no se puede almacenar correctamente.
En nuestro caso, el origen estaba totalmente identificado, pero si os encontráis con un problema parecido que no encaje con lo explicado aquí, no dudéis en dejar vuestro comentario. Cada instalación es un mundo, y estaríamos encantados de echaros una mano.
- Andres Cordeiro
- Joomla
Hace poco comenzamos a actualizar una plantilla antigua de Joomla 3 a Joomla 5. Desde Joomla 4.0 se recomienda que, en producción, las plantillas finales guarden sus recursos como CSS, JavaScript e imágenes dentro del directorio media. Esto ayuda a que Joomla sea más rápido y a que la instalación esté más organizada.
El resto de archivos —index.php (la estructura base), overrides de componentes, plugins y módulos— se mantienen en templates/nombrePlantilla.
El problema que nos surgió fue el siguiente:
¿Cómo trabajar en desarrollo con todos los recursos juntos y luego generar una plantilla lista para publicar siguiendo las buenas prácticas de Joomla?
En este artículo te voy a contar cómo Joomla gestiona la instalación de plantillas, cómo usar templateDetails.xml y joomla.asset.json para tener un flujo de trabajo limpio y versionable y cómo pasar fácilmente de desarrollo a producción sin romper rutas.
Un flujo de trabajo cómodo: todo junto en desarrollo, separado en producción
Durante el desarrollo de una plantilla Joomla es más cómodo tener todos los archivos en una sola carpeta. La clave está en que, al empaquetar la plantilla para producción:
- Los archivos PHP, overrides y estructura base deben ir a
templates/nombrePlantilla - Los recursos estáticos (CSS, JS, imágenes) deben ir a
media/templates/site/nombrePlantilla
Para esto Joomla nos da dos herramientas clave: templateDetails.xml y joomla.asset.json.
templateDetails.xml: organizando la instalación de la plantilla
El archivo templateDetails.xml es fundamental. Aquí le indicamos a Joomla qué archivos instalar, dónde colocarlos y cómo manejar la plantilla desde el administrador.
<files> – Archivos de la carpeta de la plantilla
En esta sección definimos los ficheros que van directamente a la carpeta principal de la plantilla. Ejemplo (de Cassiopeia):
<files>
<filename>component.php</filename>
<filename>error.php</filename>
<filename>index.php</filename>
<filename>joomla.asset.json</filename>
<filename>offline.php</filename>
<filename>templateDetails.xml</filename>
<folder>html</folder>
</files>
<media> – Recursos que irán al directorio media
Aquí definimos qué carpetas del paquete se instalarán en el directorio media de Joomla. Esto es lo que nos permite separar los assets de la lógica de la plantilla.
Ejemplo:
<media destination="templates/site/cassiopeia" folder="media">
<folder>js</folder>
<folder>css</folder>
<folder>scss</folder>
<folder>images</folder>
</media>
Con esto, al instalar la plantilla, Joomla colocará esos archivos en: media/templates/site/cassiopeia/
¿Cómo decide Joomla de dónde cargar los assets?
Aquí entra en juego joomla.asset.json, un archivo que Joomla usa desde la versión 4.0 para gestionar la carga de recursos. Este archivo nos permite declarar cada asset, asignarle un nombre único y establecer su ruta, evitando tener que tocar el index.php.
Ejemplo:
{
"name": "tpl_svbasic.bootstrap",
"type": "style",
"uri": "templates/solucionesvigobasicresponsiveJ5/css/bootstrap.min.css"
}
- name → nombre único del recurso.
- type → tipo de recurso (
stylepara CSS,scriptpara JS, etc.). - uri → ruta desde la raíz de Joomla.
Cargando un asset en Joomla
Si tenemos el recurso definido en joomla.asset.json, lo podemos cargar así:
use Joomla\CMS\Factory;
$app = Factory::getApplication();
$doc = $app->getDocument();
$wa = $doc->getWebAssetManager();
$wa->useStyle('tpl_svbasic.bootstrap');
O incluso registrarlo y usarlo directamente:
$wa->registerAndUseStyle(
'tpl_svbasic.bootstrap',
'templates/solucionesvigobasicresponsiveJ5/css/bootstrap.min.css'
);
Estrategia para desarrollo y producción
En desarrollo, trabajamos con las rutas dentro de la carpeta templates:
{
"name": "tpl_svbasic.bootstrap",
"type": "style",
"uri": "templates/solucionesvigobasicresponsiveJ5/css/bootstrap.min.css"
}
En producción, cambiamos la ruta para que apunte al directorio media:
{
"name": "tpl_svbasic.bootstrap",
"type": "style",
"uri": "media/templates/site/solucionesvigobasicresponsiveJ5/css/bootstrap.min.css"
}
Así conseguimos:
- Tener todos los recursos juntos y fácilmente versionables durante el desarrollo.
- Cambiar solo la ruta al empaquetar la plantilla.
- Hacer que Joomla coloque automáticamente cada archivo en su sitio durante la instalación.
Ventajas de este método
- Entorno de trabajo limpio y controlado.
- Cumple con las recomendaciones oficiales para plantillas Joomla 4 y Joomla 5.
- Evita rutas rotas y búsquedas interminables en el código.
Si desarrollas plantillas Joomla, este flujo de trabajo es una de las formas más cómodas y seguras de gestionar las rutas y cargar assets desde media, sin perder el control durante el desarrollo y sin complicaciones al publicar.
Weblinks es una extensión de Joomla que nos permite hacer un directorio de enlaces externos de una forma sencilla e intuitiva. Nosotros los utilizamos en esta web, aquí puede ver nuestro directorio de links que tenemos apuntados.
Este componente (extensión) de Joomla, hasta la versión 2.5 venía incluido, era una extensión Nativa de Joomla, pero en la versión 3.0 dejaron de incluirlo en el paquete de instalación. En la versión 4 de Joomla se rumoreaban que no se iba a continuar, aunque existe una versión para 4.0, sigue existiendo en JED de Joomla para poder descargarlo, aunque lleva un año sin actualizarse.
Nosotros aparte de utilizarla como un directorio, la utilizamos para insertar los enlaces a fuera de la web, el motivo de utilizarlo así es:
- Controlar los links rotos: Muchas veces cuando añadimos un link en un post, al cabo del tiempo lo cambia o lo quitan, esto es un problema y para detectarlo es muy sencillo si los tenemos registrados en una base de datos, que con una consulta podríamos comprobarlos todos.
- Estadísticas de pulsaciones: Saber qué links realmente hacen clic o no.
¿Cómo usamos Weblinks en nuestra web?
Una vez lo tengas instalado, pues vas a componentes y vas Enlaces Web, luego es muy sencillo añades enlaces y las categorías que quieres, es muy parecido al componente de contenido de artículos, con la diferencia que tienes un campo donde poner la URL.
Luego, si lo quieres mostrar en la web, simplemente añade el item de menu en donde quieres añadir. Al igual que un artículo o una categoría artículos.
Nosotros aparte utilizarlos como directorio de links, lo utilizamos para añadir los links en nuestros artículos por los motivos que ya indicamos antes.
Para añadir un link que tenemos en el componente Weblinks en un artículo, va a depender del editor que tengas, nosotros utilizamos JCE para la mayoría de los proyectos, por lo que simplemente pulsamos en icono de link, buscamos el componente enlace y ahí buscamos el link que deseamos añadir.
Donde lo puedo descargar Weblinks
En JED si buscas weblinks aparece, en la página oficial de Joomla puede descargar, te pongo aquí el link.
Existe un repositorio oficial, extensión weblink, donde puede ver si continúan o no el proyecto.
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.
Hoy me solicitarón añadir el plugin Google Tag Manager a un Joomla 4, como podemos ver es un plugin que solo es compatible para Joomla 3 y su ultima version es de 24 Junio 2020.
Pues nos ponemos manos a la obra , instalamos y va perfectamente la instalación.
Ahora activamos el plugin , tachan ERROR en JREQUEST!!!
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 :-)
Cambiar el favicon de la plantilla cassiopeia debería ser un parametro, esto lo comento para el proyecto de Pablo Arias que quiere montar una plantilla básica con cassiopeia pero con mas opciones. :-)
Al tajo, busco informacion y como siempre voy a las webs conocidad:
"Como cambiar el favicon en la plantilla de cassiopeia de Joomla 4" de Sergio Iglesias
En esta entrada lo explica super bien , donde poner el favicon , para las versiones anteriores 4.1.1 y para las superiores.
Lo unico que yo añadiría a esa entrada es explicar como carga el favicon , me explico:
$this->addHeadLink(HTMLHelper::_('image', 'joomla-favicon.svg', '', [], true, 1), 'icon', 'rel', ['type' => 'image/svg+xml']);
$this->addHeadLink(HTMLHelper::_('image', 'favicon.ico', '', [], true, 1), 'alternate icon', 'rel', ['type' => 'image/vnd.microsoft.icon']);
$this->addHeadLink(HTMLHelper::_('image', 'joomla-favicon-pinned.svg', '', [], true, 1), 'mask-icon', 'rel', ['color' => '#000']);
Como bien dice en la entrada Sergio, esas son la lineas que cargan el favicon y se pone las tres por los distintos navegadores.
La cuestion es que si tu en la ruta que indica que pongas tu favicon.
media/templates/site/cassiopeia/images/tufavicon.ico
Si haces como yo que solo pongo un favicon ( ico), como mi navegador admite los favicon svg, la primera linea carga el svg, pues entonces muestra ese favicon y no el que acabo de poner.
Mi solucion rápida es comentar la primera linea, aunque lo mejor sería conseguir el favico en ese formato. :-)
Me imagino que lo navegadores que solo admitan los mask-icon, cargaran la segunda linea no la primera.
