AEM Guide

Qué pertenece realmente al módulo ui.apps (y qué no)

Una guía práctica de qué debe contener el módulo Maven ui.apps de un proyecto AEM —componentes, clientlibs, diccionarios i18n— y por qué el contenido autorado nunca debería vivir ahí, junto con las reglas de filter.xml de FileVault que deciden qué se sobrescribe o se borra en cada despliegue.

ui.appsfilevaultmavencontent-packagecloud-manager

ui.apps es el módulo Maven de un proyecto AEM que construye un paquete de contenido FileVault que se instala en /apps. Eso lo sabe cualquier desarrollador de AEM. Lo que realmente causa incidentes es menos obvio: qué nodos exactamente pueden vivir ahí, y qué hace el filter.xml del paquete con cualquier otra cosa que encuentre bajo esas rutas en el momento del despliegue. Si el scope está mal definido, un despliegue rutinario de ui.apps puede borrar silenciosamente contenido que no tiene nada que ver con tu cambio.

Este artículo asume que ya conoces la estructura multimódulo estándar (core, ui.apps, ui.content, ui.frontend…) —se centra exclusivamente en qué debe contener ui.apps y cómo su filtro FileVault controla lo que ocurre al instalar.

Qué entrega realmente ui.apps

ui.apps es un paquete de contenido con packageType=application. En AEM as a Cloud Service, un paquete de tipo application solo puede tocar /apps —nunca /content, /conf ni ninguna otra área editable en tiempo de ejecución. Lo que pertenece bajo /apps es, por definición, código y configuración creados por desarrolladores y desplegados vía CI/CD, no contenido autorado por editores en la interfaz de AEM:

Algo que sorprende a los equipos que piensan todo en términos de /apps: las definiciones de plantillas editables y sus políticas no se despliegan desde ui.apps, aunque se sientan como “código”. Un cq:Template y sus nodos cq:Policy viven bajo /conf/mysite/settings/wcm/..., y /conf es una ruta mutable, editable por autores —las políticas en particular se editan habitualmente desde la UI “Edit Template” en producción. Como un paquete application solo puede tocar /apps, las plantillas y políticas tienen que desplegarse desde un paquete de tipo content (normalmente ui.content, o un módulo dedicado de configuración/estructura), típicamente con mode="merge" para que un redespliegue no pise los ajustes de política que un autor hizo después del go-live. Lo que realmente pertenece a ui.apps del mundo de las plantillas es el código del componente de estructura —el HTL/Java que hay detrás del layout container— no el nodo de plantilla ni el de política.

Por qué el contenido autorado nunca debe vivir en ui.apps

Las páginas bajo /content, los assets del DAM bajo /content/dam y las tags usadas para clasificar ese contenido son responsabilidad de ui.content, nunca de ui.apps —y esto no es solo una cuestión de estilo, lo impone AEM as a Cloud Service: un mismo paquete de contenido no puede desplegar a la vez en /apps y en un área editable en tiempo de ejecución como /content. Pero incluso sin esa regla estricta, mezclar ambos causa daño real:

filter.xml: qué controla realmente un filter root

Todo paquete de contenido —ui.apps incluido— declara su alcance en META-INF/vault/filter.xml mediante elementos <filter root="...">. Un filter root no es una pista sobre “dónde suele poner cosas este paquete”; según la documentación de Apache Jackrabbit FileVault, define el subárbol que el paquete posee a efectos de la importación:

Ese único hecho —las rutas declaradas pero no cubiertas por el contenido del paquete se borran, no se ignoran— es el mecanismo detrás de casi todo incidente del tipo “un despliegue borró contenido que no tenía nada que ver con mi cambio”.

Un filter.xml realista para ui.apps

<?xml version="1.0" encoding="UTF-8"?>
<workspaceFilter version="1.0">
    <filter root="/apps/mysite/components"/>
    <filter root="/apps/mysite/clientlibs"/>
    <filter root="/apps/mysite/i18n"/>
</workspaceFilter>

Tres roots estrechos y explícitos —cada uno coincide exactamente con el subárbol del que este módulo es responsable. Nada aquí reclama /apps en bloque, y nada llega hasta /conf o /content.

El error de ser demasiado amplio

<filter root="/apps"/>

Parece un atajo inofensivo —“somos dueños de /apps/mysite, y /apps/mysite está bajo /apps, así que por qué no”. Pero el filter root es /apps en sí mismo. Al instalar, FileVault considera ahora que todo el árbol /apps —incluyendo los propios Core Components de AEM bajo /apps/core, el paquete de otro equipo bajo /apps/othersite, cualquier cosa— está cubierto por este paquete. Como el jcr_root de tu paquete solo contiene realmente apps/mysite/..., todo lo demás bajo /apps está “cubierto pero no contenido”, y se borra al importar. Así es exactamente como un despliegue rutinario de ui.apps se carga los Core Components o una aplicación hermana en una instancia AEM compartida.

El error de ser demasiado estrecho

<filter root="/apps/mysite/components"/>
<!-- alguien añade /apps/mysite/templates/structure localmente
     y se olvida de añadir un filter root para esa ruta -->

El content-package-maven-plugin construye el paquete estrictamente a partir de lo que cubre filter.xml. Una carpeta añadida bajo jcr_root que no está bajo ningún filter root declarado simplemente se excluye del paquete construido —sin aviso, sin fallo de build. Está en git, existe en disco, y nunca llega a la instancia de destino. Este es el modo de fallo más silencioso: nada se rompe de forma visible, una funcionalidad simplemente no aparece nunca, y el arreglo suele ser “a alguien se le olvidó añadir una línea <filter root>”.

Dónde aparece esto en la práctica