Parámetros y Plantillas Liquid

Esta guía te mostrará cómo crear y usar parámetros personalizados dentro de tus informes. El módulo "Params" te permite definir campos de entrada usando YAML. Estos parámetros pueden insertarse dinámicamente en tus consultas usando el lenguaje de plantillas Liquid, haciendo que tus informes sean flexibles e interactivos.

Vista General

La interfaz de "Params" está diseñada para ser intuitiva. Típicamente verás dos secciones principales:

  1. Formulario de Parámetros (Panel Superior): Esta área muestra el formulario interactivo generado a partir de tus definiciones YAML. Tú u otros usuarios finales usarán este formulario para ingresar valores para los parámetros.
  2. Editor YAML (Panel Inferior): Aquí es donde tú, como diseñador del informe, definirás la estructura y el tipo de cada parámetro usando YAML. Los cambios aquí se reflejan en el Formulario de Parámetros.

Overall UI Overview

Definiendo Parámetros con YAML

Los parámetros se definen en el editor YAML. Cada parámetro tiene un nombre (que será su clave) y un conjunto de propiedades que definen su comportamiento y apariencia en el formulario.

Estructura Básica

Aquí está la estructura general para definir un parámetro:

parameter_name:
    type: 'inputType'
    description: 'A helpful description for the user.'
    # Other properties specific to the type...
  • parameter_name: Así es como te referirás al parámetro en tus plantillas Liquid (p.ej., {{ parameter_name }}).
  • type: Especifica el tipo de campo de entrada. Los tipos comunes incluyen text, number, date, select y multiselect.
  • description: (Opcional pero muy recomendado) Proporciona un tooltip o texto de ayuda junto al parámetro en el formulario. Los usuarios pueden verlo a menudo haciendo clic en un icono "i" (información).

Tipos Comunes de Parámetros

1. Entrada de Texto

Para texto general, nombres, títulos o cualquier dato de cadena.

report_title:
    type: 'text'
    description: 'Ingresa el título principal para tu informe.'

2. Entrada Numérica

Para valores numéricos, como cantidades, montos o IDs.

minimum_amount:
    type: 'number'
    description: 'Filtra resultados mayores que esta cantidad.'
item_count:
    type: 'number'
    description: 'Especifica el número de elementos.'

3. Entrada de Fecha

Para seleccionar fechas. Las fechas típicamente se esperan en formato YYYY-MM-DD.

start_date:
    type: 'date'
    description: 'Selecciona la fecha de inicio para el rango de datos.'
end_date:
    type: 'date'
    description: 'Selecciona la fecha de fin para el rango de datos.'

Parámetros Select y Multiselect

Estos tipos permiten a los usuarios elegir de una lista predefinida de opciones.

1. Opciones Estáticas

Puedes definir opciones directamente en el YAML.

  • Lista Simple: Cada elemento en la lista se convierte tanto en la etiqueta de visualización como en el valor enviado.
status_filter_simple:
    type: 'select'
    description: 'Filtrar por un estado simple.'
    options:
        - "Pendiente"
        - "Completado"
        - "Fallido"
  • Pares Etiqueta-Valor: Proporciona un arreglo donde el primer elemento es la etiqueta de visualización y el segundo es el valor enviado. Esto es útil cuando el texto de visualización necesita ser más amigable para el usuario que el valor real usado en una consulta.
country_code_selector:
    type: 'select'
    description: 'Selecciona un país.'
    options:
        - [ "Estados Unidos", "US" ]
        - [ "Canadá", "CA" ]
        - [ "Reino Unido", "GB" ]
        - [ "Australia", "AU" ]

user_roles_multiselect:
    type: 'multiselect'
    description: 'Selecciona uno o más roles de usuario.'
    options:
        - [ "Administrator", "admin" ]
        - [ "Editor", "editor" ]
        - [ "Viewer", "viewer" ]

Para multiselect, el valor del parámetro será un arreglo de los valores seleccionados (p.ej., ["admin", "viewer"]).

2. Opciones Dinámicas (desde Consultas)

Una característica poderosa es poblar opciones select o multiselect desde los resultados de otra consulta ya definida en tu módulo "Queries". Esto es extremadamente útil para asegurar que tus menús desplegables siempre tengan los datos más recientes (p.ej., una lista de clientes, productos o categorías).

Para hacer esto, usa las claves query, labels y values bajo options:

customer_id:
    type: 'select'
    description: 'Selecciona un cliente de la lista.'
    options:
        query: 'all_customers_query'  # Nombre de una consulta existente que devuelve datos de clientes
        labels: 'customer_name'       # Columna de 'all_customers_query' para mostrar como etiquetas
        values: 'id'                  # Columna de 'all_customers_query' para usar como valores de opción

product_skus:
    type: 'multiselect'
    description: 'Selecciona uno o más productos.'
    options:
        query: 'active_products_query' # Nombre de una consulta existente que devuelve datos de productos
        labels: 'product_title'        # Columna de 'active_products_query' para visualización
        values: 'sku'                  # Columna de 'active_products_query' para los valores de opción

Importante:

  • Las consultas especificadas (p.ej., all_customers_query, active_products_query) deben ser consultas de informe definidas y devolver datos.
  • Los campos labels y values deben corresponder a nombres de columnas reales en la salida de esas consultas.

Usando Parámetros en Consultas con Liquid

Una vez que los parámetros están definidos y los usuarios proporcionan valores a través del formulario, puedes usar estos valores en tus consultas SQL (u otros tipos de scripts soportados por el módulo "Queries") usando plantillas Liquid.

Liquid es un lenguaje de plantillas que te permite incrustar contenido dinámico. Los valores de los parámetros se insertan usando dobles llaves: {{ parameter_name }}.

Interpolación Básica de Variables

Digamos que has definido los siguientes parámetros en YAML:

start_date:
    type: 'date'
end_date:
    type: 'date'
status:
    type: 'select'
    options:
        - "Active"
        - "Inactive"
minimum_value:
    type: 'number'

Y un usuario proporciona los siguientes valores:

  • start_date: 2024-01-01
  • end_date: 2024-03-31
  • status: Active
  • minimum_value: 100

Puedes usar estos en una consulta SQL así:

SELECT *
FROM transactions
WHERE transaction_date BETWEEN '{{start_date}}' AND '{{end_date}}'
  AND account_status = '{{status}}'
  AND amount >= {{minimum_value}};

Cuando la consulta se ejecute, Liquid la procesará y el SQL real enviado a la base de datos será:

SELECT *
FROM transactions
WHERE transaction_date BETWEEN '2024-01-01' AND '2024-03-31'
  AND account_status = 'Active'
  AND amount >= 100;

Nota sobre Comillas en SQL:

  • Liquid inserta el valor del parámetro directamente.
  • Para valores de cadena o fecha en SQL, asegúrate de envolver la etiqueta Liquid en comillas simples: '{{parameter_name}}'.
  • Para valores numéricos, las comillas generalmente no son necesarias: {{numeric_parameter}}.

Plantillas Liquid Avanzadas

Liquid ofrece más que solo sustitución de variables. Puedes usar etiquetas para lógica (como condiciones if y bucles for) y filtros para modificar variables.

Lógica Condicional: if, elsif, else

Puedes incluir condicionalmente partes de tu consulta usando etiquetas {% if %}. Esto es muy útil para filtros opcionales.

Sintaxis: {% if condition %} ... parte SQL a incluir si la condición es verdadera ... {% elsif another_condition %} ... parte SQL si la primera condición es falsa y esta es verdadera ... {% else %} ... parte SQL si todas las condiciones anteriores son falsas ... {% endif %}

Ejemplo: Filtro de cliente opcional.

Asumamos que tienes un parámetro customer_id que podría estar vacío si el usuario quiere ver datos de todos los clientes.

# Parameter definition
optional_customer_id:
    type: 'number'
    description: 'Ingresa ID de Cliente (opcional). Deja en blanco para todos los clientes.'
# Asume también un parámetro 'department' (texto)
department:
    type: 'text'
    description: 'Filtrar por departamento (p.ej., Ventas, RRHH).'

Query:

SELECT *
FROM employee_data
WHERE 1 = 1 -- Un truco común para asegurar que las cláusulas AND siempre puedan agregarse
    {% if department and department != "" %}
  AND department_name = '{{department}}'
{% endif %}
{% if optional_customer_id %}
  AND customer_id = {{optional_customer_id}}
{% endif %}
  • Si department es "Ventas" y optional_customer_id es 123, renderiza:
    SELECT *
    FROM employee_data
    WHERE 1=1
      AND department_name = 'Sales'
      AND customer_id = 123
  • Si department está vacío y optional_customer_id también está vacío, renderiza:
    SELECT *
    FROM employee_data
    WHERE 1=1

    (La verificación department != "" maneja casos donde una cadena vacía podría pasarse para un campo de texto.)

Bucles: for

Los bucles son esenciales cuando se trabaja con parámetros que pueden tener múltiples valores, como los de una entrada multiselect. Un caso de uso común es construir cláusulas SQL IN.

Sintaxis: {% for item in collection %} ... contenido a repetir para cada elemento ... {{ item }} ... {{ forloop.index }} ... {{ forloop.last }} {% endfor %}

Ejemplo: Filtrar por múltiples SKUs de producto desde un parámetro multiselect.

# Parameter definition
selected_skus:
    type: 'multiselect'
    description: 'Selecciona uno o más SKUs de producto.'
    options:
        query: 'all_products'
        labels: 'product_name'
        values: 'sku'

Si un usuario selecciona SKUs: ["ABC-1001", "XYZ-2002", "DEF-3003"], el parámetro selected_skus contendrá este arreglo.

Query:

SELECT *
FROM products
WHERE 1 = 1 {% if selected_skus and selected_skus.size > 0 %}
  AND sku IN (
    {% for current_sku in selected_skus %}
      '{{ current_sku }}'{% unless forloop.last %},{% endunless %}
    {% endfor %}
  )
{% endif %}
  • selected_skus.size > 0: Verifica si el arreglo no está vacío. (.size es una forma común en Liquid de obtener la longitud del arreglo o longitud de cadena).
  • {% for current_sku in selected_skus %}: Itera a través de cada SKU en el arreglo.
  • '{{ current_sku }}': Pone cada SKU entre comillas simples (asumiendo que los SKUs son cadenas).
  • {% unless forloop.last %},{% endunless %}: Agrega una coma después de cada SKU, a menos que sea el último elemento en el bucle. Esto crea una lista SQL correctamente formateada.

SQL renderizado si selected_skus es ["ABC-1001", "XYZ-2002"]:

SELECT *
FROM products
WHERE 1 = 1
  AND sku IN (
              'ABC-1001',
              'XYZ-2002'
    )

Filtros Liquid

Los filtros modifican la salida de variables u objetos Liquid. Se usan con un carácter de tubería |. {{ variable | filter_name: argument }}

Aquí están algunos filtros comunes y útiles:

  • default: Proporciona un valor de respaldo si la variable está vacía o no definida.

    -- Procesamiento para región: {{ region_param | default: 'América del Norte' }}
    WHERE start_date >= '{{ start_date_param | default: "2024-01-01" }}'
  • date: Formatea una fecha. La entrada puede ser una marca de tiempo, una cadena de fecha reconocida por Liquid, o la palabra especial "now" (o "today").

    -- Informe generado el: {{ "now" | date: "%Y-%m-%d %H:%M:%S" }}
    -- Mes de transacción: {{ transaction_date_param | date: "%B %Y" }}

    (Nota: Los parámetros de fecha del formulario podrían ya estar en formato compatible con SQL YYYY-MM-DD, por lo que reformatear podría no ser siempre necesario para cláusulas SQL WHERE pero puede ser útil para comentarios o visualización.)

  • Manipulación de Cadenas:

    • upcase, downcase, capitalize:
      WHERE product_category = '{{ category_param | upcase }}'
    • append, prepend: Agrega texto al principio o al final.
      {% assign log_prefix = user_id_param | prepend: "User_" %}
      -- Prefijo de Log: {{ log_prefix }}
    • replace, replace_first: Reemplaza ocurrencias de una subcadena.
      -- {{ 'Informe de Ventas para Q1' | replace: 'Q1', 'Q2' }}
      -- Renderiza: Informe de Ventas para Q2
    • strip, lstrip, rstrip: Elimina espacios en blanco.
    • truncate: Acorta una cadena a una longitud especificada. {{ long_description | truncate: 25, "..." }} (muestra los primeros 25 caracteres, luego "...")
    • escape: Escapa una cadena (p.ej., para HTML o XML, menos común directamente en valores SQL pero bueno para comentarios o código generado). -- Comentario de usuario: {{ user_comment_param | escape }}
  • Filtros de Arreglo/Colección:

    • size: Devuelve el número de elementos en un arreglo o caracteres en una cadena. (Ya usado en el ejemplo del bucle for).
    • join: Une elementos de arreglo en una cadena con un separador.
      {% comment %} Si selected_tags_param es ("urgente", "revisar"( {% endcomment %}
      -- Etiquetas: {{ selected_tags_param | join: ", " }}
      -- Renderiza: Etiquetas: urgente, revisar
    • first, last: Obtiene el primer o último elemento de un arreglo.
    • map: Itera sobre un arreglo y extrae una propiedad de cada elemento (si los elementos son objetos) o aplica un filtro a cada elemento.

      {% comment %}
        Si items_param es ({id:1, name:"A"}, {id:2, name:"B"})
        Esto crearía un arreglo como (1, 2)
      {% endcomment %}
      {% assign item_ids = items_param | map: "id" %}
      
      {% comment %}
        Si string_numbers_param es ("10", "20", "30")
        Esto puede intentar convertirlos (el comportamiento depende de la variante de Liquid)
        Un truco común para convertir cadena a número es 'plus: 0' si 'to_number' no está disponible.
      {% endcomment %}
      {% assign numeric_values = string_numbers_param | map: plus: 0 %}
      
      {% comment %}
        Si categories_param es ("electrónica", "libros")
        Esto crea ("ELECTRÓNICA", "LIBROS")
      {% endcomment %}
      {% assign uppercased_categories = categories_param | map: 'upcase' %}
    • uniq: Elimina elementos duplicados de un arreglo.
    • sort: Ordena un arreglo. Puede tomar un nombre de propiedad para objetos. {% endraw %}
  • Filtros Matemáticos:

    • plus, minus, times, divided_by, modulo: Realizan aritmética.
      {% assign page_size = 20 %}
      {% assign current_page = page_number_param | default: 1 %}
      {% assign offset_value = current_page | minus: 1 | times: page_size %}
      LIMIT {{ page_size }} OFFSET {{ offset_value }}

Asignando Variables: assign

Puedes crear nuevas variables Liquid dentro de tu plantilla.

{% assign default_records_limit = 50 %}
{% assign records_to_fetch = user_limit_param | default: default_records_limit %}
SELECT * FROM data_table LIMIT {{ records_to_fetch }};

Capturando Salida: capture

Puedes capturar un bloque de salida Liquid renderizada en una variable.

{% capture filename %}report_{{ report_type_param | default: 'generic' }}_{{ "now" | date: "%Y%m%d" }}.csv{% endcapture %}
-- Nombre de archivo sugerido: {{ filename }}

Lógica Case/When (Declaración Switch)

Para lógica condicional más compleja basada en el valor de una sola variable.

{% assign status_id_value = 0 %}
{% case status_param %}
  {% when "Pending" %}
    {% assign status_id_value = 1 %}
  {% when "Active" %}
    {% assign status_id_value = 2 %}
  {% when "Closed" %}
    {% assign status_id_value = 3 %}
  {% else %}
    {% assign status_id_value = -1 %}
{% endcase %}

SELECT * FROM items WHERE status_identifier = {{ status_id_value }};

Guardando tus Parámetros

Después de definir o modificar tus parámetros en el editor YAML, o cuando los valores predeterminados en el formulario necesitan persistir, deberás guardarlos. Busca un botón o icono de "Guardar", a menudo un símbolo de nube o disco. Esta acción almacenará tu configuración YAML y cualquier valor predeterminado actual que hayas establecido en el formulario.

Consejos y Mejores Prácticas

  • Nombres Descriptivos: Usa nombres claros y significativos para tus parámetros. start_date es mejor que d1.
  • Siempre Agrega Descripciones: El campo description es invaluable para los usuarios finales que pueden no conocer el propósito de cada parámetro.
  • Prueba Exhaustivamente: Después de configurar parámetros y usarlos en consultas, prueba con varias entradas:
    • Valores válidos.
    • Valores vacíos (si son opcionales).
    • Casos extremos.
  • Comillas en SQL: Recuerda que Liquid inserta valores tal como están. Los valores de cadena y fecha en consultas SQL generalmente necesitan estar encerrados en comillas simples ('{{my_string_param}}'). Los valores numéricos típicamente no.
  • multiselect y Cláusulas IN: Cuando uses multiselect para cláusulas SQL IN, usa el bucle for con forloop.last para formatear correctamente la lista separada por comas, y asegúrate de que los valores de cadena dentro de la lista estén individualmente entre comillas si es necesario.
  • Empieza Simple: Si eres nuevo en Liquid, comienza con interpolaciones básicas de variables y gradualmente introduce lógica más compleja como condiciones if y bucles for según sea necesario.
  • Consulta la Documentación de Liquid: Liquid tiene muchas más características. Si tienes una transformación específica en mente, la documentación oficial de Liquid (o la específica de la implementación de Liquid de tu plataforma) puede ser un gran recurso.

Al dominar los parámetros y las plantillas Liquid, puedes crear informes altamente dinámicos y amigables para el usuario que se adapten a diversas necesidades analíticas.