AEM ofrece una selección de informes estándar la mayoría de los cuales se basan en un marco de sistema de informes.
Con el marco puede ampliar estos informes estándar o desarrollar sus propios informes completamente nuevos. El marco de sistema de informes se integra estrechamente con los conceptos y principios de CQ5 existentes para que los desarrolladores puedan utilizar sus conocimientos actuales de CQ5 como trampolín para desarrollar informes.
Para los informes estándar entregados con AEM:
Estos informes se basan en el sistema de informes:
Los siguientes informes se basan en principios individuales y, por lo tanto, no pueden ampliarse:
El tutorial Creación de su propio informe - Un ejemplo también muestra cuántos de los principios siguientes se pueden utilizar.
También puede consultar los informes estándar para ver otros ejemplos de implementación.
En los ejemplos y definiciones que se muestran a continuación se utiliza la notación siguiente:
Cada línea define un nodo o una propiedad donde:
N:<name> [<nodeType>]
Describe un nodo con el nombre <*name*>
y el tipo de nodo <*nodeType*>
.
P:<name> [<propertyType]
Describe una propiedad con el nombre <*name*>
y un tipo de propiedad <*propertyType*>
.
P:<name> = <value>
Describe una propiedad <name>
que debe establecerse en el valor de <value>
.
La sangría muestra las dependencias jerárquicas entre los nodos.
Elementos separados por | denota una lista de posibles artículos; por ejemplo, tipos o nombres:
p. ej. String|String[]
significa que la propiedad puede ser String o String[].
[]
representa una matriz; como [] Stringo una matriz de nodos como en la Definición de Consulta.
A menos que se indique lo contrario, los tipos predeterminados son:
nt:unstructured
String
El sistema de informes se basa en los siguientes principios:
Se basa completamente en los conjuntos de resultados devueltos por una consulta ejecutada por CQ5 QueryBuilder.
El conjunto de resultados define los datos que se muestran en el informe. Cada fila del conjunto de resultados corresponde a una fila de la vista tabular del informe.
Las operaciones disponibles para la ejecución en el conjunto de resultados se parecen a los conceptos de RDBMS; principalmente agrupación y agregación.
La mayor parte de la recuperación y el procesamiento de datos se realiza en el servidor.
El cliente es el único responsable de mostrar los datos preprocesados. Solo se ejecutan en el cliente tareas de procesamiento menores (por ejemplo, la creación de vínculos en el contenido de la celda).
La estructura de sistemas de informes (ilustrada por la estructura de un informe estándar) utiliza los siguientes componentes básicos, alimentados por la cola de procesamiento:
La página del informe:
El reportbase
componente forma la base de cualquier informe tal como lo hace:
Contiene la definición de la consulta que ofrece el conjunto de datos de resultados subyacente.
Es un sistema de párrafos adaptado que contendrá todas las columnas ( columnbase
) agregadas al informe.
Define qué tipos de gráficos están disponibles y cuáles están activos actualmente.
Define el cuadro de diálogo Editar, que permite al usuario configurar ciertos aspectos del informe.
Cada columna es una instancia del componente columnbase
que:
reportbase
) del informe correspondiente.La consulta:
Se define como parte del componente reportbase
.
Se basa en CQ QueryBuilder.
Recupera los datos utilizados como base del informe. Cada fila del conjunto de resultados (tabla) está vinculada a un nodo como lo devuelve la consulta. A continuación, se extrae información específica para columnas individuales de este conjunto de datos.
Generalmente consiste en:
Una ruta de acceso raíz.
Esto especifica el subárbol del repositorio que se va a buscar.
Para ayudar a minimizar el impacto en el rendimiento, es aconsejable (intentar) restringir la consulta a un subárbol específico del repositorio. La ruta de acceso raíz puede predefinirse en la plantilla de informe o configurarse por el usuario en el cuadro de diálogo Configuración (Editar).
Se imponen para producir el conjunto de resultados (inicial); incluyen, por ejemplo, restricciones en el tipo de nodo o restricciones de propiedad.
El punto clave aquí es que cada nodo único devuelto en el conjunto de resultados de la consulta se utiliza para generar una sola fila en el informe (por lo tanto, una relación 1:1).
El desarrollador debe asegurarse de que la consulta definida para un informe devuelva un conjunto de nodos apropiado para ese informe. Sin embargo, el nodo en sí no necesita contener toda la información necesaria, sino que también se puede derivar de nodos principales y/o secundarios. Por ejemplo, la consulta utilizada para el Informe de usuario selecciona nodos según el tipo de nodo (en este caso rep:user
). Sin embargo, la mayoría de las columnas de este informe no toman sus datos directamente de estos nodos, sino de los nodos secundarios profile
.
La consulta devuelve un conjunto de datos resultante para que se muestre como filas en el informe. Cada fila del conjunto de resultados se procesa (en el servidor), en varias fases, antes de transferirse al cliente para que se muestre en el informe.
Esto permite:
Extraer y derivar valores del conjunto de resultados subyacente.
Por ejemplo, permite procesar dos valores de propiedad como un solo valor calculando la diferencia entre ambos.
Resolución de los valores extraídos; esto puede hacerse de diversas maneras.
Por ejemplo, las rutas se pueden asignar a un título (como en el contenido más legible para el ser humano de la propiedad jcr:title correspondiente).
Aplicación de filtros en varios puntos.
Crear valores compuestos, si es necesario.
Por ejemplo: consiste en un texto que se muestra al usuario, un valor que se utilizará para ordenar y una URL adicional que se utilizará (en el lado del cliente) para crear un vínculo.
El flujo de trabajo siguiente representa la cola de procesamiento:
Donde los pasos y elementos detallados son:
Transforma los resultados devueltos por la consulta inicial (reportbase) en el conjunto de resultados básico mediante extractores de valores.
Los extractores de valores se eligen automáticamente en función del tipo de columna. Se utilizan para leer valores de la Consulta JCR subyacente y crear un conjunto de resultados a partir de ellos; después de lo cual se podrá aplicar un nuevo tratamiento. Por ejemplo, para el tipo diff
, el extractor de valores lee dos propiedades, calcula el valor único que se agrega al conjunto de resultados. No se pueden configurar los extractores de valores.
Para ese conjunto de resultados inicial, que contiene datos sin procesar, se aplica filtro inicial (fase sin procesar).
Los valores son preprocesados; tal como se define para la fase apply.
El filtrado (asignado a la fase ** preprocesada) se ejecuta en los valores preprocesados.
Los valores se resuelven; según la resolución definida.
El filtrado (asignado a la fase ** resuelta) se ejecuta en los valores resueltos.
Los datos se agrupan y agregan.
Los datos de matriz se resuelven convirtiéndolos en una lista (basada en cadenas).
Se trata de un paso implícito que convierte un resultado de varios valores en una lista que se puede mostrar; es necesario para valores de celda (no agregados) basados en propiedades JCR de varios valores.
Los valores se vuelven a preprocesar; tal como se define para la fase afterApply.
Los datos se ordenan.
Los datos procesados se transfieren al cliente.
La consulta inicial que devuelve el conjunto de resultados de datos base se define en el componente reportbase
.
Otros elementos de la cola de procesamiento se definen en los componentes columnbase
.
Para crear y configurar un informe se necesita lo siguiente:
reportbase
componentecolumnbase
Los componentes de sistema de informes predeterminados se encuentran en /libs/cq/reporting/components
.
Sin embargo, se recomienda encarecidamente que no actualice estos nodos, sino que cree sus propios nodos de componentes en /apps/cq/reporting/components
o si es más apropiado /apps/<yourProject>/reports/components
.
Dónde (como ejemplo):
N:apps
N:cq [nt:folder]
N:reporting|reports [sling:Folder]
N:components [sling:Folder]
Bajo esta opción se crea la raíz para el informe y bajo esta, el componente base del informe y los componentes base de la columna:
N:apps
N:cq [nt:folder]
N:reporting|reports [sling:Folder]
N:components [sling:Folder]
N:<reportname> [sling:Folder]
N:<reportname> [cq:Component] // report base component
N:<columnname> [cq:Component] // column base component
Una página de informe debe utilizar el sling:resourceType
de /libs/cq/reporting/components/reportpage
.
No debe ser necesario un componente de página personalizado (en la mayoría de los casos).
Cada tipo de informe requiere un componente de contenedor derivado de /libs/cq/reporting/components/reportbase
.
Este componente actúa como contenedor del informe en su conjunto y proporciona información para:
N:<reportname> [cq:Component]
P:sling:resourceSuperType = "cq/reporting/components/reportbase"
N:charting
N:dialog [cq:Dialog]
N:queryBuilder
N:queryBuilder
N:propertyConstraints
[
N:<name> // array of nodes (name irrelevant), each with the following properties:
P:name
P:value
]
P:nodeTypes [String|String[]]
P:mandatoryProperties [String|String[]
]
propertyConstraints
Se puede utilizar para limitar el conjunto de resultados a nodos que tengan propiedades específicas con valores específicos. Si se especifican varias restricciones, el nodo debe satisfacer todas ellas (operación AND).
Por ejemplo:
N:propertyConstraints
[
N:0
P:sling:resourceType
P:foundation/components/textimage
N:1
P:jcr:modifiedBy
P:admin
]
Devolvería todos los textimage
componentes que el usuario admin
modificó por última vez.
nodeTypes
Se utiliza para limitar el conjunto de resultados a los tipos de nodo especificados. Se pueden especificar varios tipos de nodos.
mandatoryProperties
Se puede utilizar para limitar el resultado establecido a nodos que tengan todo de las propiedades especificadas. No se tiene en cuenta el valor de las propiedades.
Todos son opcionales y se pueden combinar según sea necesario, pero debe definir al menos uno de ellos.
N:charting
N:settings
N:active [cq:WidgetCollection]
[
N:<name> // array of nodes, each with the following property
P:id // must match the id of a child node of definitions
]
N:definitions [cq:WidgetCollection]
[
N:<name> // array of nodes, each with the following properties
P:id
P:type
// additional, chart type specific configurations
]
settings
Contiene definiciones para los gráficos activos.
active
Como se pueden definir varias opciones de configuración, puede utilizarlas para definir cuáles están activas actualmente. Se definen mediante una matriz de nodos (no existe una convención de nombres obligatoria para estos nodos, pero los informes estándar suelen utilizar 0
, 1
. x
), cada una con la siguiente propiedad:
id
Identificación de los gráficos activos. Debe coincidir con la identificación de uno de los gráficos definitions
.
definitions
Define los tipos de gráficos que están potencialmente disponibles para el informe. La configuración definitions
que se va a usar se especificará mediante la configuración active
.
Las definiciones se especifican mediante una matriz de nodos (también con el nombre 0
, 1
. x
), cada uno con las siguientes propiedades:
id
Identificación del gráfico.
type
Tipo de gráfico disponible. Seleccionar de:
pie
Gráfico circular. Generado solo a partir de datos actuales.
lineseries
Serie de líneas (puntos de conexión que representan las instantáneas reales). Generado sólo a partir de datos históricos.
Hay propiedades adicionales disponibles, según el tipo de gráfico:
para el tipo de gráfico pie
:
maxRadius
( Double/Long
)
Radio máximo permitido para el gráfico circular; por lo tanto, el tamaño máximo permitido para el gráfico (sin leyenda). Se omite si fixedRadius
está definido.
minRadius
( Double/Long
)
Radio mínimo permitido para el gráfico circular. Se omite si fixedRadius
está definido.
fixedRadius
( Double/Long
) Define un radio fijo para el gráfico circular.
para el tipo de gráfico lineseries
:
totals
( Boolean
)
True si se debe mostrar una línea adicional que muestre el Total.
predeterminada: false
series
( Long
)
Número de líneas/series que se van a mostrar.
predeterminado: 9
(también es el máximo permitido)
hoverLimit
( Long
)
Número máximo de instantáneas agregadas (puntos que se muestran en cada línea horizontal, que representan valores distintos) para las que se mostrarán ventanas emergentes, es decir, cuando el usuario pase el ratón sobre un valor distinto o la etiqueta correspondiente en la leyenda del gráfico.
predeterminado: 35
(es decir, no se muestra ninguna ventana emergente si se aplican más de 35 valores distintos para la configuración actual del gráfico).
Hay un límite adicional de 10 ventanas emergentes que se pueden mostrar en paralelo (se pueden mostrar varias ventanas emergentes cuando se pasa el ratón sobre los textos de la leyenda).
Cada informe puede tener un cuadro de diálogo de configuración, que permite al usuario especificar varios parámetros para el informe. Se puede acceder a este cuadro de diálogo a través del botón Editar cuando se abre la página del informe.
Este cuadro de diálogo es un cuadro de diálogo estándar de CQ 🔗 y se puede configurar como tal (consulte CQ.Dialog para obtener más información).
Un cuadro de diálogo de ejemplo puede tener el siguiente aspecto:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="https://www.day.com/jcr/cq/1.0" xmlns:jcr="https://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:Dialog"
height="{Long}424">
<items jcr:primaryType="cq:WidgetCollection">
<props jcr:primaryType="cq:Panel">
<items jcr:primaryType="cq:WidgetCollection">
<title
jcr:primaryType="cq:Widget"
path="/libs/cq/reporting/components/commons/title.infinity.json"
xtype="cqinclude"/>
<description
jcr:primaryType="cq:Widget"
path="/libs/cq/reporting/components/commons/description.infinity.json"
xtype="cqinclude"/>
<rootPath
jcr:primaryType="cq:Widget"
fieldLabel="Root path"
name="./report/rootPath"
rootPath=""
rootTitle="Repository root"
xtype="pathfield"/>
<processing
jcr:primaryType="cq:Widget"
path="/libs/cq/reporting/components/commons/processing.infinity.json"
xtype="cqinclude"/>
<scheduling
jcr:primaryType="cq:Widget"
path="/libs/cq/reporting/components/commons/scheduling.infinity.json"
xtype="cqinclude"/>
</items>
</props>
</items>
</jcr:root>
Se proporcionan varios componentes preconfigurados; se puede hacer referencia a ellos en el cuadro de diálogo, mediante la propiedad xtype
con un valor de cqinclude
:
title
/libs/cq/reporting/components/commons/title
Campo de texto para definir el título del informe.
description
/libs/cq/reporting/components/commons/description
Área de texto para definir la descripción del informe.
processing
/libs/cq/reporting/components/commons/processing
Selector para el modo de procesamiento del informe (carga manual o automática de datos).
scheduling
/libs/cq/reporting/components/commons/scheduling
Selector para programar instantáneas para el gráfico histórico.
Los componentes a los que se hace referencia deben incluirse mediante el sufijo .infinity.json
(véase el ejemplo anterior).
Además, se puede definir una ruta raíz para el informe:
rootPath
Esto limita el informe a una sección determinada (árbol o subárbol) del repositorio, lo cual se recomienda para la optimización del rendimiento. La ruta raíz se especifica mediante la propiedad rootPath
del nodo report
de cada página de informe (tomada de la plantilla al crearla).
Puede especificarse mediante:
Cada tipo de columna requiere un componente derivado de /libs/cq/reporting/components/columnbase
.
Un componente de columna define una combinación de lo siguiente:
definitions
nodo secundario).cq:editConfig
. para definir los Eventos y acciones necesarios.N:<columnname> [cq:Component]
P:componentGroup
P:jcr:title
P:sling:resourceSuperType = "cq/reporting/components/columnbase"
N:cq:editConfig [cq:EditConfig] // <a href="#events-and-actions">Events and Actions</a>
N:defaults // <a href="#column-default-values">Column Default Values</a>
N:definitions
N:queryBuilder // <a href="#column-specific-query">Column Specific Query</a>
P:property [String|String[]] // Column Specific Query
P:subPath // Column Specific Query
P:secondaryProperty [String|String[]] // Column Specific Query
P:secondarySubPath // Column Specific Query
N:data
P:clientFilter [String] // <a href="#client-filter">Client Filter</a>
P:resolver // <a href="#resolvers-and-preprocessing">Resolvers and Preprocessing</a>
N:resolverConfig // Resolvers and Preprocessing
N:preprocessing // Resolvers and Preprocessing
P:type // <a href="#column-specific-definitions">Column Specific Definitions</a>
P:groupable [Boolean] // Column Specific Definitions
N:filters [cq:WidgetCollection] // Column Specific Definitions
N:aggregates [cq:WidgetCollection] // Column Specific Definitions
Consulte también Definición del nuevo informe.
Esto define la extracción de datos específica (del conjunto de resultados de datos del informe) para su uso en la columna individual.
N:definitions
N:queryBuilder
P:property [String|String[]]
P:subPath
P:secondaryProperty [String|String[]]
P:secondarySubPath
property
Define la propiedad que se utilizará para calcular el valor real de la celda.
Si la propiedad se define como String[], se analizan varias propiedades (en secuencia) para buscar el valor real.
Por ejemplo, en el caso de:
property = [ "jcr:lastModified", "jcr:created" ]
El extractor de valor correspondiente (que se controla aquí):
subPath
Si el resultado no se encuentra en el nodo devuelto por la consulta, subPath
define dónde se encuentra realmente la propiedad.
secondaryProperty
Define una segunda propiedad que también debe utilizarse para calcular el valor real de la celda; esto solo se utilizará para determinados tipos de columnas (diferf y ordenable).
Por ejemplo, en el caso del informe Instancias de flujo de trabajo, la propiedad especificada se utiliza para almacenar el valor real de la diferencia de tiempo (en milisegundos) entre las horas de inicio y de finalización.
secondarySubPath
Similar a subPath, cuando se utiliza secondaryProperty
.
En la mayoría de los casos, sólo se utilizará property
.
El filtro de cliente extrae la información que se va a mostrar de los datos devueltos por el servidor.
Este filtro se ejecuta en el cliente, después de que se haya aplicado todo el procesamiento en el servidor.
N:definitions
N:data
P:clientFilter [String]
clientFilter
se define como una función de JavaScript que:
El ejemplo siguiente extrae la ruta de página correspondiente de una ruta de componente:
function(v) {
var sepPos = v.lastIndexOf('/jcr:content');
if (sepPos < 0) {
return v;
}
return v.substring(sepPos + '/jcr:content'.length, v.length);
}
La cola de procesamiento define los distintos solucionadores y configura el preprocesamiento:
N:definitions
N:data
P:resolver
N:resolverConfig
N:preprocessing
N:apply
N:applyAfter
resolver
Define la resolución que se va a utilizar. Están disponibles los siguientes resueltores:
const
Asigna valores a otros valores; por ejemplo, se utiliza para resolver constantes como en
a su valor equivalente English
.
default
Resolución predeterminada. Esta es una resolución ficticia que en realidad no resuelve nada.
page
Resuelve un valor de ruta a la ruta de la página adecuada; más precisamente, al nodo jcr:content
correspondiente. Por ejemplo, /content/.../page/jcr:content/par/xyz
se resuelve en /content/.../page/jcr:content
.
path
Resuelve un valor de ruta añadiendo opcionalmente una subruta y tomando el valor real de una propiedad del nodo (como se define en resolverConfig
) en la ruta resuelta. Por ejemplo: un path
de /content/.../page/jcr:content
puede resolverse con el contenido de la propiedad jcr:title
, lo que significaría que una ruta de página se resuelve con el título de la página.
pathextension
Resuelve un valor anteponiendo una ruta y tomando el valor real de una propiedad del nodo en la ruta resuelta. Por ejemplo, un valor de
puede estar precedido por una ruta como /libs/wcm/core/resources/languages
, tomando el valor de la propiedad language
, para resolver el código de país de
en la descripción del idioma German
.
resolverConfig
Proporciona definiciones para la resolución; las opciones disponibles dependen del resolver
seleccionado:
const
Utilice las propiedades para especificar las constantes que se deben resolver. El nombre de la propiedad define la constante que se va a resolver; el valor de la propiedad define el valor resuelto.
Por ejemplo, una propiedad con Nombre= 1
y Valor =One
resolverá 1 en Uno.
default
No hay configuración disponible.
page
propertyName
(opcional)
Define el nombre de la propiedad que debe utilizarse para resolver el valor. Si no se especifica, se utiliza el valor predeterminado jcr:title (el título de la página); para la resolución page
, esto significa que primero la ruta se resuelve en la ruta de la página y luego se resuelve en el título de la página.
path
propertyName
(opcional)
Especifica el nombre de la propiedad que debe utilizarse para resolver el valor. Si no se especifica, se utiliza el valor predeterminado jcr:title
.
subPath
(opcional)
Esta propiedad se puede utilizar para especificar un sufijo que se anexará a la ruta antes de que se resuelva el valor.
pathextension
path
(obligatorio)
Define la ruta que se va a anteponer.
propertyName
(obligatorio)
Define la propiedad en la ruta resuelta donde se encuentra el valor real.
i18n
(opcional; type Boolean)
Determina si el valor resuelto debe internacionalizarse (es decir, utilizando servicios de internacionalización de CQ5).
preprocessing
El preprocesamiento es opcional y se puede enlazar (por separado) a las fases de procesamiento apply o applyAfter:
apply
Fase inicial de preprocesamiento (paso 3 en la representación de la cola de procesamiento).
applyAfter
Aplicar después del preprocesamiento (paso 9 en la representación de la cola de procesamiento).
Los solucionadores se utilizan para extraer la información necesaria. Algunos ejemplos de los distintos solucionadores son:
Const
Lo siguiente resolverá un valor de contenido de VersionCreated
en la cadena New version created
.
Consulte /libs/cq/reporting/components/auditreport/typecol/definitions/data
.
N:data
P:resolver=const
N:resolverConfig
P:VersionCreated="New version created"
Página
Resuelve un valor de ruta de acceso a la propiedad jcr:description en el nodo jcr:content (secundario) de la página correspondiente.
Consulte /libs/cq/reporting/components/compreport/pagecol/definitions/data
.
N:data
P:resolver=page
N:resolverConfig
P:propertyName="jcr:description"
Ruta
Lo siguiente resuelve una ruta de /content/.../page
al contenido de la propiedad jcr:title
, lo que significa que una ruta de página se resuelve en el título de la página.
Consulte /libs/cq/reporting/components/auditreport/pagecol/definitions/data
.
N:data
P:resolver=path
N:resolverConfig
P:propertyName="jcr:title"
P:subPath="/jcr:content"
Extensión de ruta
Lo siguiente antepone un valor de
con la extensión de ruta /libs/wcm/core/resources/languages
y luego toma el valor de la propiedad language
para resolver el código de país de
a la descripción de idioma German
.
Consulte /libs/cq/reporting/components/userreport/languagecol/definitions/data
.
N:data
P:resolver=pathextension
N:resolverConfig
P:path="/libs/wcm/core/resources/languages"
P:propertyName="language"
La definición preprocessing
se puede aplicar a:
valor original:
La definición de preprocesamiento del valor original se especifica directamente en apply
y/o applyAfter
.
en su estado agregado:
Si es necesario, se puede proporcionar una definición independiente para cada agregación.
Para especificar el preprocesamiento explícito para los valores agregados, las definiciones de preprocesamiento deben residir en un nodo secundario aggregated
correspondiente ( apply/aggregated
, applyAfter/aggregated
). Si se requiere un preprocesamiento explícito para distintos agregados, la definición de preprocesamiento se encuentra en un nodo secundario con el nombre del respectivo acumulado (por ejemplo, apply/aggregated/min/max
u otros agregados).
Puede especificar una de las siguientes opciones que se utilizarán durante el procesamiento previo:
buscar y reemplazar
patronesCuando se encuentra, el patrón especificado (que se define como una expresión regular) se reemplaza por otro patrón; por ejemplo, se puede utilizar para extraer una subcadena del original.
formateadores de tipos de datos
Convierte un valor numérico en una cadena relativa; por ejemplo, el valor "que representa una diferencia de tiempo de 1 hora se resolvería en una cadena como 1:24PM (1 hour ago)
.
Por ejemplo:
N:definitions
N:data
N:preprocessing
N:apply|applyAfter
P:pattern // regex
P:replace // replacement for regex
// and/or
P:format // data type formatter
Para el preprocesamiento, puede especificar una pattern
(definida como una expresión regular o regex) que se encuentre y luego se sustituya por el patrón replace
:
pattern
La expresión normal que se utiliza para localizar una subcadena.
replace
La cadena, o representación de la cadena, que se utilizará como reemplazo de la cadena original. A menudo esto representa una subcadena de la cadena ubicada por la expresión regular pattern
.
Un ejemplo de reemplazo se puede desglosar como:
Para el nodo definitions/data/preprocessing/apply
con las dos propiedades siguientes:
pattern
: (.*)(/jcr:content)(/|$)(.*)
replace
:: $1
Una cadena que llega como:
/content/geometrixx/en/services/jcr:content/par/text
Se dividirá en cuatro secciones:
$1
- (.*)
- /content/geometrixx/en/services
$2
- (/jcr:content)
- /jcr:content
$3
- (/|$)
- /
$4
- (.*)
- par/text
Y reemplazado por la cadena representada por $1
:
/content/geometrixx/en/services
Estos formateadores convierten un valor numérico en una cadena relativa.
Por ejemplo, esto se puede usar para una columna de tiempo que permite agregados min
, avg
y max
. Como min
/ avg
/ max
agregados se muestran como una diferencia horaria (por ejemplo: 10 days ago
), requieren un formateador de datos. Para ello, se aplica un formateador datedelta
a los valores agregados min
/ avg
/ max
. Si también hay disponible un acumulado count
, no se necesita un formateador, ni el valor original.
Actualmente, los formateadores de tipo de datos disponibles son:
format
Formato de tipo de datos:
duration
Duración es el lapso de tiempo entre dos fechas definidas. Por ejemplo, el inicio y el final de una acción de flujo de trabajo que tomó 1 hora, comenzando en 2/13/11 11:23 h y finalizando una hora más tarde en 2/13/11 12:23 h.
Convierte un valor numérico (interpretado como milisegundos) en una cadena de duración; por ejemplo, 30000
tiene el formato * 30s
.*
datedelta
Datadelta es el lapso de tiempo entre una fecha pasada y "ahora" (por lo que tendrá un resultado diferente si el informe se ve en un momento posterior).
Convierte el valor numérico (interpretado como una diferencia de tiempo en días) en una cadena de fecha relativa. Por ejemplo, 1 tiene el formato de hace 1 día.
El ejemplo siguiente define el formato datedelta
para los agregados min
y max
:
N:definitions
N:data
N:preprocessing
N:apply
N:aggregated
N:min
P:format = "datedelta"
N:max
P:format = "datedelta"
Las definiciones específicas de columna definen los filtros y los agregados disponibles para esa columna.
N:definitions
P:type
P:groupable [Boolean]
N:filters [cq:WidgetCollection]
[
N:<name> // array of nodes (names irrelevant) with the following properties:
P:filterType
P:id
P:phase
]
N:aggregates [cq:WidgetCollection]
[
N:<name> // array of nodes (names irrelevant) with the following properties:
P:text
P:type
]
type
Las siguientes opciones están disponibles como opciones estándar:
string
number
int
date
diff
timeslot
Se utiliza para extraer partes de una fecha necesaria para la agregación (por ejemplo, grupo por año para obtener datos agregados para cada año).
sortable
Se utiliza para valores que utilizan diferentes valores (según se obtienen de diferentes propiedades) para ordenar y mostrar.
Además. cualquiera de los anteriores puede definirse como multivalor; por ejemplo, string[]
define una matriz de cadenas.
El tipo de columna elige el extractor de valores. Si hay un extractor de valores disponible para un tipo de columna, se utiliza este extractor. De lo contrario, se utiliza el extractor de valores predeterminado.
Un tipo puede (opcionalmente) tomar un parámetro. Por ejemplo, timeslot:year
extrae el año de un campo de fecha. Tipos con sus parámetros:
timeslot
- Los valores son comparables a las constantes correspondientes de java.utils.Calendar
.
timeslot:year
- Calendar.YEAR
timeslot:month-of-year
- Calendar.MONTH
timeslot:week-of-year
- Calendar.WEEK_OF_YEAR
timeslot:day-of-month
- Calendar.DAY_OF_MONTH
timeslot:day-of-week
- Calendar.DAY_OF_WEEK
timeslot:day-of-year
- Calendar.DAY_OF_YEAR
timeslot:hour-of-day
- Calendar.HOUR_OF_DAY
timeslot:minute-of-hour
- Calendar.MINUTE
groupable
Define si el informe se puede agrupar por esta columna.
filters
Definiciones de filtro.
filterType
Los filtros disponibles son:
string
Un filtro basado en cadenas.
id
Identificador de filtro.
phase
Fases disponibles:
raw
El filtro se aplica a los datos sin procesar.
preprocessed
El filtro se aplica a los datos preprocesados.
resolved
El filtro se aplica a los datos resueltos.
aggregates
Definiciones acumuladas.
text
Nombre textual del acumulado. Si no se especifica text
, tomará la descripción predeterminada del acumulado; por ejemplo, minimum
se utilizará para el min
acumulado.
type
Tipo acumulado. Los agregados disponibles son:
count
Cuenta el número de filas.
count-nonempty
Cuenta el número de filas no vacías.
min
Proporciona el valor mínimo.
max
Proporciona el valor máximo.
average
Proporciona el valor promedio.
sum
Proporciona la suma de todos los valores.
median
Proporciona el valor medio.
percentile95
Toma el porcentaje 95 de todos los valores.
Se utiliza para definir los valores predeterminados de la columna:
N:defaults
P:aggregate
aggregate
Los valores válidos aggregate
son los mismos que para type
en aggregates
(consulte Definiciones específicas de columna (definiciones: filtros / agregados) ).
Editar configuración define los eventos necesarios para que los oyentes detecten y las acciones que se aplicarán después de que se produzcan esos eventos. Consulte la introducción al desarrollo de componentes para obtener información general.
Se deben definir los siguientes valores para garantizar que se cubren todas las acciones necesarias:
N:cq:editConfig [cq:EditConfig]
P:cq:actions [String[]] = "insert", "delete"
P:cq:dialogMode = "floating"
P:cq:layout = "auto"
N:cq:listeners [cq:EditListenersConfig]
P:aftercreate = "REFRESH_INSERTED"
P:afterdelete = "REFRESH_SELF"
P:afteredit = "REFRESH_SELF"
P:afterinsert = "REFRESH_INSERTED"
P:aftermove = "REFRESH_SELF"
P:afterremove = "REFRESH_SELF"
Las columnas genéricas son una extensión donde (la mayoría de) las definiciones de columna se almacenan en la instancia del nodo de columna (en lugar del nodo de componente).
Utilizan un cuadro de diálogo (estándar) que se personaliza para el componente genérico individual. Este cuadro de diálogo permite al usuario del informe definir las propiedades de columna de una columna genérica en la página del informe (mediante la opción de menú Propiedades de columna…).
Un ejemplo es la columna Generic del Informe de usuario; consulte /libs/cq/reporting/components/userreport/genericcol
.
Para que una columna sea genérica:
Establezca la propiedad type
del nodo definition
de la columna en generic
.
Consulte /libs/cq/reporting/components/userreport/genericcol/definitions
Especifique una definición de cuadro de diálogo (estándar) en el nodo definition
de la columna.
Consulte /libs/cq/reporting/components/userreport/genericcol/definitions/dialog
Los campos del cuadro de diálogo deben hacer referencia a los mismos nombres que la propiedad del componente correspondiente (incluida su ruta).
Por ejemplo, si desea que el tipo de columna genérica se pueda configurar a través del cuadro de diálogo, utilice un campo con el nombre ./definitions/type
.
Las propiedades definidas con la IU/cuadro de diálogo tienen prioridad sobre las definidas en el componente columnbase
.
Defina Editar configuración.
Consulte /libs/cq/reporting/components/userreport/genericcol/cq:editConfig
Utilice metodologías de AEM estándar para definir propiedades de columna (adicionales).
Tenga en cuenta que para las propiedades definidas en las instancias de componente y columna, el valor de la instancia de columna tiene prioridad.
Las propiedades disponibles para una columna genérica son:
jcr:title
- nombre de columnadefinitions/aggregates
- agregadosdefinitions/filters
- filtrosdefinitions/type
- el tipo de columna (esto debe definirse en el cuadro de diálogo, ya sea mediante un selector/cuadro combinado o un campo oculto)definitions/data/resolver
y definitions/data/resolverConfig
(pero no definitions/data/preprocessing
o .../clientFilter
): resolución y configuracióndefinitions/queryBuilder
- la configuración del generador de consultasdefaults/aggregate
- el acumulado predeterminadoEn el caso de una nueva instancia de la columna genérica en el Informe de usuario, las propiedades definidas con el cuadro de diálogo se mantienen en:
/etc/reports/userreport/jcr:content/report/columns/genericcol/settings/generic
El diseño define qué tipos de columnas están disponibles para crear un informe. También define el sistema de párrafos al que se agregan las columnas.
Se recomienda encarecidamente crear un diseño individual para cada informe. Esto garantiza una flexibilidad total. Consulte también Definición del nuevo informe.
Los componentes de sistema de informes predeterminados se encuentran en /etc/designs/reports
.
La ubicación de los informes puede depender de la ubicación de los componentes:
/etc/designs/reports/<yourReport>
es adecuado si el informe se encuentra en /apps/cq/reporting
/etc/designs/<yourProject>/reports/<*yourReport*>
para informes que utilizan el /apps/<yourProject>/reports
patrón
Las propiedades de diseño requeridas se registran en jcr:content/reportpage/report/columns
(por ejemplo, /etc/designs/reports/<reportName>/jcr:content/reportpage/report/columns
):
components
Cualquier componente o grupo de componentes permitidos en el informe.
sling:resourceType
Propiedad con valor cq/reporting/components/repparsys
.
Un fragmento de diseño de ejemplo (tomado del diseño del informe de componentes) es:
<!-- ... -->
<jcr:content
jcr:primaryType="nt:unstructured"
jcr:title="Component Report"
sling:resourceType="wcm/core/components/designer">
<reportpage jcr:primaryType="nt:unstructured">
<report jcr:primaryType="nt:unstructured">
<columns
jcr:primaryType="nt:unstructured"
sling:resourceType="cq/reporting/components/repparsys"
components="group:Component Report"/>
</report>
</reportpage>
</jcr:content>
<!-- ... -->
No es necesario especificar diseños para columnas individuales. Las columnas disponibles se pueden definir en el modo de diseño.
Se recomienda no realizar ningún cambio en los diseños de informe estándar. Esto sirve para asegurarse de que no se pierden los cambios al actualizar o instalar revisiones.
Copie el informe y su diseño si desea personalizar un informe estándar.
Las columnas predeterminadas se pueden crear automáticamente cuando se crea un informe. Se especifican en la plantilla.
Cada tipo de informe debe proporcionar una plantilla. Son plantillas de CQ estándar y se pueden configurar como tales.
La plantilla debe:
establezca sling:resourceType
en cq/reporting/components/reportpage
indicar el diseño que se va a utilizar
cree un nodo secundario report
que haga referencia al componente de contenedor ( reportbase
) mediante la propiedad sling:resourceType
Un fragmento de plantilla de ejemplo (tomado de la plantilla de informe de componente) es:
<!-- ... -->
<jcr:content
cq:designPath="/etc/designs/reports/compreport"
jcr:primaryType="cq:PageContent"
sling:resourceType="cq/reporting/components/reportpage">
<report
jcr:primaryType="nt:unstructured"
sling:resourceType="cq/reporting/components/compreport/compreport"/>
</jcr:content>
<!-- .. -->
Un fragmento de plantilla de ejemplo que muestra la definición de la ruta raíz (tomada de la plantilla de informe de usuario) es:
<!-- ... -->
<jcr:content
cq:designPath="/etc/designs/reports/userreport"
jcr:primaryType="cq:PageContent"
sling:resourceType="cq/reporting/components/reportpage">
<report
jcr:primaryType="nt:unstructured"
rootPath="/home/users"
sling:resourceType="cq/reporting/components/compreport/compreport"/>
</jcr:content>
<!-- .. -->
Las plantillas de sistema de informes predeterminadas se encuentran en /libs/cq/reporting/templates
.
Sin embargo, se recomienda encarecidamente que no actualice estos nodos, sino que cree sus propios nodos de componentes en /apps/cq/reporting/templates
o si es más apropiado /apps/<yourProject>/reports/templates
.
Donde, como ejemplo (consulte también Ubicación de los componentes del informe):
N:apps
N:cq [nt:folder]
N:reporting|reports [sling:Folder]
N:templates [sling:Folder]
En esta sección se crea la raíz para la plantilla:
N:apps
N:cq [nt:folder]
N:reporting|reports [sling:Folder]
N:templates [sling:Folder]
N:<reportname> [sling:Folder]
Para definir un nuevo informe debe crear y configurar:
Para ilustrar estos pasos, el siguiente ejemplo define un informe que lista todas las configuraciones de OSGi dentro del repositorio; es decir, todas las instancias del nodo sling:OsgiConfig
.
Copiar un informe existente, luego personalizar la nueva versión, es un método alternativo.
Cree el nodo raíz para el nuevo informe.
Por ejemplo, en /apps/cq/reporting/components/osgireport
.
N:cq [nt:folder]
N:reporting [sling:Folder]
N:components [sling:Folder]
N:osgireport [sling:Folder]
Defina la base de informes. Por ejemplo, osgireport[cq:Component]
en /apps/cq/reporting/components/osgireport
.
N:osgireport [sling:Folder]
N:osgireport [cq:Component]
P:sling:resourceSuperType [String] = "cq/reporting/components/reportbase"
N:charting [nt:unstructured]
N:settings [nt:unstructured]
N:active [cq:WidgetCollection]
N:0 [nt:unstructured]
P:id [String] = "pie"
N:1 [nt:unstructured]
P:id [String] = "lineseries"
N:definitions [cq:WidgetCollections]
N:0 [nt:unstructured]
P:id [String] = "pie"
P:maxRadius [Long] = 180
P:type [String] = "pie"
N:1 [nt:unstructured]
P:id [String] = "lineseries"
P:type [String] = "lineseries"
N:dialog [cq:Dialog]
P:height [Long] = 424
N:items [cq:WidgetCollection]
N:props [cq:Panel]
N:items [cq:WidgetCollection]
N:title [cq:Widget]
P:path [String] = "/libs/cq/reporting/components/commons/title.infinity.json"
P:xtype [String] = "cqinclude"
N:description [cq:Widget]
P:path [String] = "/libs/cq/reporting/components/commons/description.infinity.json"
P:xtype [String] = "cqinclude"
N:rootPath [cq:Widget]
P:fieldLabel [String] = "Root path"
P:name [String] = "./report/rootPath"
P:xtype [String] = "pathfield"
N:processing [cq:Widget]
P:path [String] = "/libs/cq/reporting/components/commons/processing.infinity.json"
P:xtype [String] = "cqinclude"
N:scheduling [cq:Widget]
P:path [String] = "/libs/cq/reporting/components/commons/scheduling.infinity.json"
P:xtype [String] = "cqinclude"
N:queryBuilder [nt:unstructured]
P:nodeTypes [String[]] = "sling:OsgiConfig"
Esto define un componente base de informe que:
sling:OsgiConfig
pie
y lineseries
Defina el primer componente de columna (columna base). Por ejemplo, bundlecol[cq:Component]
en /apps/cq/reporting/components/osgireport
.
N:osgireport [sling:Folder]
N:bundlecol [cq:Component]
P:componentGroup [String] = "OSGi Report"
P:jcr:title = "Bundle"
P:sling:resourceSuperType [String] = "cq/reporting/components/columnbase"
N:cq:editConfig [cq:EditConfig]
P:cq:actions [String[]] = "insert", "delete"
P:cq:dialogMode [String] = "floating"
P:cq:layout [String] = "auto"
N:cq:listeners [cq:EditListenersConfig]
P:aftercreate [String] "REFRESH_INSERTED"
P:afterdelete [String] "REFRESH_SELF"
P:afteredit [String] "REFRESH_SELF"
P:afterinsert [String] "REFRESH_INSERTED"
P:aftermove [String] "REFRESH_SELF"
P:afterremove [String] "REFRESH_SELF"
N:defaults [nt:unstructured]
P:aggregate [String] = "count"
N:definitions [nt:unstructured]
P:groupable [Boolean] = false
P:type [String] = "string"
N:queryBuilder [nt:unstructured]
P:property [String] = "jcr:path"
Define un componente base de columna que:
jcr:path
para cada nodo sling:OsgiConfig
count
Bundle
(título de columna dentro de la tabla)OSGi Report
En este ejemplo no hay definiciones de N:data
y P:clientFilter
. Esto se debe a que el valor recibido del servidor se devuelve 1:1, que es el comportamiento predeterminado.
Es lo mismo que las definiciones:
N:data [nt:unstructured]
P:clientFilter [String] = "function(v) { return v; }"
Donde la función simplemente devuelve el valor que recibe.
Defina el diseño del informe. Por ejemplo, osgireport[cq:Page]
en /etc/designs/reports
.
N:osgireport [cq:Page]
N:jcr:content [nt:unstructured]
P:jcr:title [String] = "OSGi report"
P:sling:resourceType [String] = "wcm/core/components/designer"
N:reportpage [nt:unstructured]
N:report [nt:unstructured]
N:columns [nt:unstructured]
P:components [String] = "group:OSGi Report"
P:sling:resourceType [String] = "cq/reporting/components/repparsys"
Cree el nodo raíz para la nueva plantilla de informe.
Por ejemplo, en /apps/cq/reporting/templates/osgireport
.
N:cq [nt:folder]
N:reporting [sling:Folder]
N:templates [sling:Folder]
N:osgireport [cq:Template]
Defina la plantilla de informe. Por ejemplo, osgireport[cq:Template]
en /apps/cq/reporting/templates
.
N:osgireport [cq:Template]
P:allowedPaths [String[]] = "/etc/reports(/.*)?"
P:jcr:description [String] = "Use this report generator to create a new OSGi report."
P:jcr:title [String] = "OSGi Report Template"
P:ranking [Long] = 100
P:shortTitle [String] = "OSGi Report"
N:jcr:content [cq:PageContent]
P:cq:designPath [String] = "/etc/designs/reports/osgireport"
P:sling:resourceType [String] = "cq/reporting/components/reportpage"
N:report [nt:unstructured]
P:rootPath [String] = "/"
P:sling:resourceType [String] = "cq/reporting/components/osgireport/osgireport"
N:thumbnail.png [nt:file]
Define una plantilla que:
allowedPaths
para los informes resultantes; en el caso anterior, en cualquier lugar bajo /etc/reports
Ahora se puede crear una instancia del nuevo informe:
Abra la consola Herramientas.
Seleccione Informes en el panel izquierdo.
Luego Nuevo… de la barra de herramientas. Defina un Título y Nombre, seleccione el nuevo tipo de informe (la Plantilla de informe OSGi) de la lista de las plantillas y haga clic en Crear.
La nueva instancia del informe aparecerá en la lista. Haga clic en el doble para abrirlo.
Arrastre un componente (por ejemplo, Paquete en el grupo Informe OSGi) desde la barra de tareas para crear la primera columna y inicio de la definición del informe.
Como este ejemplo no tiene columnas agrupables, los gráficos no estarán disponibles. Para ver los gráficos, establezca groupable
en true
:
N:osgireport [sling:Folder]
N:bundlecol [cq:Component]
N:definitions [nt:unstructured]
P:groupable [Boolean] = true
En esta sección se describen las opciones de configuración avanzadas para los servicios OSGi que implementan el marco de trabajo del informe.
Se pueden ver mediante el menú Configuración de la consola web (disponible por ejemplo en http://localhost:4502/system/console/configMgr
). Al trabajar con AEM existen varios métodos para gestionar los parámetros de configuración de dichos servicios; consulte Configuración de OSGi para obtener más detalles y las prácticas recomendadas.
Tiempos define los datos históricos de huso horario para los que se crean. Esto sirve para garantizar que el gráfico histórico muestre los mismos datos para cada usuario de todo el mundo.
Localedefine la configuración regional que se utilizará junto con el huso horario para los datos históricos. La configuración regional se utiliza para determinar algunas configuraciones de calendario específicas de la configuración regional (por ejemplo, si el primer día de una semana es domingo o lunes).
La ruta de acceso de instantáneas define la ruta raíz en la que se almacenan las instantáneas de los gráficos históricos.
La ruta a los informes define la ruta en la que se ubican los informes. El servicio de instantáneas lo utiliza para determinar los informes para tomar instantáneas.
Las instantáneas diarias definen la hora de cada día en que se toman las instantáneas diarias. La hora especificada está en la zona horaria local del servidor.
Las instantáneas por hora definen el minuto de cada hora en que se toman instantáneas por hora.
Filas (máx) define el número máximo de filas almacenadas para cada instantánea. Este valor debe elegirse razonablemente; si es demasiado alto, esto afectará el tamaño del repositorio, si es demasiado bajo, los datos podrían no ser precisos debido a la manera en que se manejan los datos históricos.
Los datos falsos, si están habilitados, se pueden crear datos históricos falsos mediante el fakedata
selector; si está desactivado, el uso del fakedata
selector generará una excepción.
Dado que los datos son falsos, sólo debe utilizarse para fines de prueba y depuración.
El uso del selector fakedata
finalizará el informe de forma implícita, de modo que se perderán todos los datos existentes; los datos se pueden restaurar manualmente, pero este proceso puede llevar mucho tiempo.
El usuario de instantáneas define un usuario opcional que se puede utilizar para tomar instantáneas.
Básicamente, se toman instantáneas para el usuario que ha finalizado el informe. Puede haber situaciones (por ejemplo, en un sistema de publicación, en las que este usuario no existe porque su cuenta no se ha replicado) en las que desee especificar un usuario de reserva que se utilice en su lugar.
Además, especificar un usuario podría suponer un riesgo para la seguridad.
Si se habilita, obligue al usuario de instantáneas, todas las instantáneas se tomarán con el usuario especificado en Usuario de instantáneas. Esto podría tener graves repercusiones en la seguridad si no se gestiona correctamente.
Los datos del informe pueden ser diferentes para cada usuario y idioma. Por lo tanto, los datos del informe se almacenan en caché por informe, usuario e idioma. Esto significa que un valor máximo de entradas de 2
realmente almacena en caché los datos para: