EM4me

Perfiles de propiedades

Los perfiles de propiedades definen los campos de propiedades de forma centralizada para un área: por campo un nombre, un tipo, opcionalmente un rango de valores fijo (selección simple o múltiple) y un valor predeterminado. Los perfiles pueden heredar unos de otros (sección «Herencia»). El editor de propiedades y el panel de propiedades de bloque sugieren los campos definidos, ofrecen los rangos de valores como listas de selección y toman el tipo de la definición. Los perfiles solo existen en el contexto de un área: la configuración vive en el archivo del área (Ajustes → Perfiles de propiedades), los perfiles en sí son archivos Markdown normales. La funcionalidad puede activarse o desactivarse como extensión «Perfiles de propiedades» (Ajustes → Extensiones); sin configuración o con la extensión desactivada, ambos editores se comportan como de costumbre (inferencia de tipos y sugerencias estándar).

Archivos de perfil y formato de las definiciones

Un perfil es un archivo Markdown en la carpeta de perfiles configurada; el nombre del perfil es el nombre del archivo sin la extensión. Las definiciones de campos están en el frontmatter bajo la clave fields; el contenido del archivo debajo es una descripción libre:

---
fields:
  - name: estado
    values: [abierto, en curso, terminado]
    default: abierto
  - name: presupuesto
    type: number
  - name: temas
    type: multistring
    values: [proyecto, persona, lugar]
  - name: vencimiento
    type: date
---

Atributos por definición:

Atributo Significado
name nombre del campo (obligatorio, único por perfil)
type string, multistring, number, boolean, date, multiline, link (enlace a un archivo), time (hora), formula y lookup (campos derivados) u object y objectlist (campos estructurados); sin indicación, string
values opcional: rango de valores fijo como lista de valores (para string, multistring, number y date)
multiple opcional: varios valores — el valor es una lista. Rige para todo tipo salvo boolean y multiline; solo en el campo de texto cambia entonces el tipo a multistring, en los demás el nombre del tipo permanece (un campo de enlace con varios destinos es link con multiple)
default opcional: valor inicial al crear el campo mediante el editor
valuesFrom opcional: fuente del repertorio de valores con note (ruta de una nota de valores) y/o query (consulta); junto con values se aplica values
options opcional: indicaciones propias del tipo en un subobjeto, véase la tabla siguiente
fields opcional: definiciones hijas anidadas según el mismo esquema; atendidas por object y objectlist. En cualquier otro tipo siguen admitidas pero sin efecto

Un campo multistring con values es automáticamente una selección múltiple. El nombre del campo es la única indicación obligatoria: cualquier otra indicación es opcional, y los archivos de perfil existentes siguen siendo válidos sin cambios. valuesFrom, options y los fields anidados ya forman parte del formato, pero en esta versión aún no se evalúan (sección «Límites»). Las definiciones individuales defectuosas (por ejemplo un tipo desconocido o un nombre de campo duplicado) solo se suspenden a sí mismas; las demás definiciones del perfil siguen vigentes. La lista de perfiles de los ajustes muestra los avisos escritos bajo el perfil correspondiente — con la definición afectada, la indicación errónea y lo que se esperaba en su lugar, en las definiciones hijas con la ruta hacia el campo padre — y abre el archivo del perfil con un clic.

Opciones propias del tipo

El subobjeto options lleva las indicaciones que solo rigen para un tipo determinado:

Tipo Indicación Significado
number step, min, max paso y límites del campo numérico
date shift desplazamiento en días; rellena previamente un campo vacío al primer clic, una fecha existente permanece intacta
link restrictTo, display, sort ruta de carpeta (o lista) a la que se limitan las sugerencias; campo de metadatos del destino como nombre mostrado; orden name o path
campo de selección control: cycle la selección simple se convierte en un botón que pasa al siguiente valor al hacer clic; el valor guardado sigue siendo el mismo que sin la opción
formula expression La regla de cálculo sobre los demás campos del mismo documento
lookup from, relatedField Consulta que acota los documentos consultados (toda el área si se omite); campo por el que apuntan a este documento

Una indicación desconocida o mal rellenada se descarta individualmente con un aviso; el campo y las demás indicaciones siguen siendo efectivos. Una opción prevista para un tipo posterior puede figurar ya sin causar daño.

Repertorios de valores

El repertorio de valores permitido de un campo de selección tiene tres fuentes posibles: la lista fija values, una nota de valores o una consulta. values y valuesFrom se excluyen mutuamente; si figuran ambos, se aplica values y la lista de perfiles de los ajustes señala la contradicción.

---
fields:
  - name: lugar
    valuesFrom:
      note: 90 Organización/Valores/Lugares.md
  - name: proyecto
    type: link
    valuesFrom:
      query: WHERE tipo = "proyecto"
---

Una nota de valores es una nota corriente con un valor por línea; su ruta es relativa al área. Las líneas vacías y los espacios de borde se descartan, un bloque de metadatos de la nota no forma parte del repertorio. Se actualiza como un archivo de perfil: una modificación surte efecto sin reiniciar, incluso si viene de fuera. Así el repertorio pasa a ser contenido corriente que se puede enlazar, comentar y compartir.

Una consulta entrega los valores desde el fondo: los nombres de sus coincidencias. Solo se evalúa cuando un campo necesita realmente sus valores, y se recuerda hasta el siguiente cambio del fondo; no se calcula nada de antemano sobre el conjunto. Un documento sin campo de consulta no cuesta, por tanto, ninguna evaluación.

Si falta una fuente, está vacía o no es evaluable, el campo sigue utilizable: el repertorio está vacío, aparece una indicación en el campo, y los valores propios siguen siendo posibles como en todas partes.

Asignación y perfil estándar

Los documentos se asignan mediante un campo del frontmatter; el nombre del campo es configurable por área (por defecto class). El valor es un nombre de perfil o una lista de varios nombres de perfiles:

Un documento encuentra además su perfil mediante una etiqueta o su carpeta, sin que en él deba figurar un campo de asignación. Estas asignaciones pertenecen al área y se configuran en Ajustes → Perfiles de propiedades: una fila por perfil, con sus etiquetas y sus rutas de carpeta.

  • Etiqueta: cuenta por igual desde el bloque de metadatos (tags) y desde el texto (#etiqueta): para la asignación, una etiqueta es una etiqueta. También una modificación sin guardar surte efecto de inmediato.
  • Carpeta: una ruta vinculada incluye sus subcarpetas, para que una subdivisión posterior no tenga que mantenerse. La ruta relativa al área se compara por nombres de carpeta completos; «10 Proyectos Archivo» no cae, por tanto, bajo «10 Proyectos».
---
class:
  - proyecto
  - persona
---

Además se puede elegir un perfil estándar: sus definiciones se aplican a todos los archivos del área, incluso sin campo de asignación. Los nombres de perfiles coinciden sin distinguir mayúsculas y minúsculas.

Herencia

Un perfil puede heredar las definiciones de otro. Para ello, el frontmatter del archivo de perfil nombra, junto a fields, como máximo un perfil padre y, opcionalmente, nombres de campos a excluir:

---
extends: proyecto
exclude: [estado]
fields:
  - name: fase
  - name: autor
---
  • extends nombra el perfil padre; son posibles cadenas de varios niveles, no existe más de un perfil padre.
  • exclude excluye campos heredados. La exclusión actúa en la cadena de herencia en la que está, no para todo el documento.
  • Un campo propio con el mismo nombre reemplaza por completo al heredado.

Un ciclo en la relación de padres o un perfil padre inexistente solo termina la cadena afectada y produce un aviso en la lista de perfiles de los ajustes; la resolución continúa.

Perfil interno

Junto a los archivos de perfil de la carpeta existe el perfil interno Ereignis de la extensión Eventos. Forma parte automáticamente de la resolución de perfiles y de la lista de perfiles en los ajustes (allí marcado como perfil interno), define los ocho campos event-* y no se puede editar ni eliminar; tampoco se ofrece como perfil estándar. Actúa también sin carpeta de perfiles configurada, con el campo de asignación estándar class; si un archivo de perfil lleva el mismo nombre, el perfil interno tiene prioridad. Con la extensión Eventos desactivada desaparece de la resolución y de la lista.

Reglas de conflicto

Para un archivo rige la unión de todas las definiciones de todos los perfiles que lo alcanzan. La resolución es una única secuencia ordenada en cuatro pasos, del enunciado más explícito al más general:

  1. el campo de asignación del documento, en el orden de mención
  2. una etiqueta del documento
  3. la carpeta del documento
  4. el perfil estándar del área

Por cada perfil alcanzado vienen primero sus propios campos, luego los de su cadena de herencia de abajo arriba; cada perfil se procesa exactamente una vez en todos los pasos. Si más de un perfil define el mismo nombre de campo, las reglas son deterministas:

  1. Gana la primera coincidencia de la secuencia: una vía más arriba supera a cualquier vía más abajo.
  2. Entre varios perfiles del mismo paso gana el mencionado primero (lista de asignación u orden de las asignaciones).
  3. Dentro de una cadena gana el perfil heredero sobre sus padres; un campo propio sustituye así al heredado del mismo nombre.

Las vías se complementan, no se sustituyen: un documento con campo de asignación y carpeta coincidente lleva los campos de ambos. Una vía que apunta a un perfil ya alcanzado no añade nada: se desprende de «cada perfil exactamente una vez» y no necesita regla propia. Y una contradicción entre etiqueta y carpeta no lo es: decide el orden, no hay ni consulta ni advertencia.

Un ejemplo con cuatro perfiles: todos (campo tags), proyecto (hereda de todos; campos fase, estado), artículo (hereda de proyecto, excluye estado; campos propios fase, autor) y reunión (campos estado, lugar). Un documento con class: [artículo, reunión] y el perfil estándar todos recibe fase y autor de artículo, tags a través de la cadena desde todos, estado y lugar de reunión — la exclusión en artículo solo actúa en su cadena; a través de reunión, estado llega de todos modos.

Símbolo del perfil en el documento

Un perfil puede llevar un símbolo: un único carácter, normalmente un emoji, en el bloque de metadatos del archivo de perfil:

---
icon: 📅
fields:
  - name: lugar
---

La cabecera de la sección Propiedades muestra el símbolo del perfil que se resolvió primero para el documento; la información emergente indica su nombre y el paso por el que se encontró. Ese es el verdadero propósito: en cuanto etiqueta y carpeta intervienen, un documento puede llevar campos de los que en él no se dice nada; el símbolo responde entonces al porqué.

Sin perfil o sin símbolo no aparece nada; no se crea ningún marcador de posición. Una indicación de más de un carácter se descarta con un aviso, el perfil sigue siendo efectivo.

Efecto en los editores

Las definiciones actúan en el editor de propiedades y de forma idéntica en el panel de propiedades de bloque; los bloques de un archivo heredan la resolución de su archivo.

  • Sugerencias de campos: «Añadir propiedad» muestra primero los campos definidos aún no presentes (con el nombre del perfil como distintivo), después las sugerencias habituales; «Campo propio» al final sigue siendo la vía libre. La selección crea el campo con el tipo definido y el valor predeterminado.
  • Listas de selección: los campos con rango de valores ofrecen los valores definidos como lista de selección (selección simple) o como sugerencias de entrada de la barra de fichas (selección múltiple); «Valor propio…» sigue permitiendo entradas libres.
  • Tipo establecido: los campos definidos muestran el tipo definido, el selector de tipo está bloqueado y nombra el perfil. Si el valor existente se desvía del tipo, el selector permanece libre para poder convertir el valor al tipo definido.
  • Los campos de enlace ofrecen los destinos del área como autocompletado, marcan un destino inexistente y lo abren mediante la flecha: el mismo camino que un clic en un enlace wiki. Con multiple llevan varios destinos en la barra de fichas.
  • Los campos de hora usan el control de hora; el valor figura entre comillas en el bloque de metadatos, porque 09:30 se leería de otro modo como número.
  • Los campos definidos llevan una marca discreta en el nombre del campo; la información sobre herramientas nombra el perfil.

Incorporación de todos los campos a la vez

El menú de sugerencias «Añadir propiedad» está agrupado por perfil: bajo cada nombre de perfil aparecen, con sangría, sus campos aún no presentes, y debajo las sugerencias estándar sin perfil bajo «Otros campos». Un clic en el nombre del perfil añade en un solo paso todos los campos que aún faltan de ese perfil; un clic en un campo individual sigue añadiendo solo ese.

La incorporación es deliberadamente aditiva:

  • Solo se crean los campos que faltan; los valores existentes y el orden de los campos permanecen intactos, y no surgen duplicados.
  • Un campo con valor predeterminado recibe ese valor; un campo sin valor predeterminado se crea vacío según el tipo: texto, fecha y lista quedan vacíos, un número empieza en 0, un booleano en «falso». El contenido se edita después como de costumbre.
  • En el frontmatter del documento, los campos vacíos aparecen como una simple clave sin valor (campo:).

Toda la incorporación es un único paso y puede deshacerse por completo con una sola acción de deshacer. Se aplica en el editor de propiedades y en el panel de propiedades de bloque, y desaparece cuando la extensión «Perfiles de propiedades» está desactivada.

Formulario de campos del documento

Arriba, la sección muestra los campos que el documento contiene; debajo, el área desplegable «Todos los campos de este documento» reúne los campos que definen los perfiles vigentes y que el documento aún no lleva. Ambos juntos responden por completo a qué puede llevar este documento; la unión se reparte en lugar de duplicarse, para que ningún campo aparezca dos veces.

Procedencia de cada campo. Cada campo lleva el símbolo del perfil del que procede su definición; la información emergente nombra el perfil y la vía. En una definición heredada se trata del perfil en el que realmente está — no del perfil asignado.

La cadena de perfiles vigentes figura por encima de los campos que faltan, porque responde a la pregunta de la que se derivan los campos. Cada nivel muestra el símbolo, el nombre del perfil y la vía por la que el perfil se aplica; la profundidad de herencia se ve como sangría. A partir del primer nivel heredado, la línea indica «heredado» en lugar de la vía — un perfil heredado se aplica por la misma vía que su hijo, y ahí la herencia es la información que ayuda.

Incorporación por nivel. Junto a un nivel con campos faltantes hay un botón que crea exactamente esos campos de una vez: con un valor vacío acorde al tipo, sin tocar los valores existentes y como un único paso de deshacer — la misma vía que la incorporación de todos los campos. Un nivel sin campos faltantes no lleva botón; prometería una acción que no hace nada.

Un campo que el documento aún no lleva permanece fuera mientras esté vacío. El simple despliegue no escribe, pues, nada en el bloque de metadatos; solo un valor introducido o la incorporación convierte el campo en un campo del documento.

Con un bloque de metadatos defectuoso el área no aparece — allí rige el mismo aviso que para «Añadir propiedad». Tampoco aparece sin perfil vigente ni con la extensión «Perfiles de propiedades» desactivada; nunca surge un área vacía ni un marcador de posición.

Tres accesos llevan al formulario: la propia área desplegable, el comando «Abrir el formulario de campos del documento» y la entrada «Abrir el formulario de campos» del menú contextual de la pestaña. Los dos últimos hacen visible la sección si está oculta, despliegan el área y la desplazan a la parte visible; la entrada del menú contextual se refiere a la pestaña pulsada y la activa antes.

Vista por perfil como consulta

La pregunta «qué documentos pertenecen a este perfil» es una consulta, y el comando «Insertar consulta de perfil» la escribe entera: pregunta por el perfil cuando hay varios posibles e inserta un bloque de consulta ordinario en la posición del cursor. No surge ninguna vista propia — la salida pasa por la presentación de resultados ya existente del lenguaje de consulta.

La consulta generada abarca las tres vías de asignación explícitas del perfil — el campo de asignación, cada vinculación por etiqueta y cada vinculación por carpeta. Una condición de carpeta incluye las subcarpetas, igual que la propia vinculación:

```perspective-query
LIST
WHERE class = "proyecto"
  OR icontains(file.tags, "proyecto")
  OR (file.folder = "10 Proyectos" OR startswith(lower(file.folder), "10 proyectos/"))
```

Dos casos se apartan de esto:

  • El perfil estándar del área rige para todo lo que no tiene otra asignación. Por eso el comando produce para él una consulta sobre todos los documentos del área en lugar de la negación de todas las vinculaciones — sería larga, opaca y se volvería silenciosamente falsa en cuanto se añadiera una vinculación.
  • Los perfiles herederos quedan fuera. Si cliente hereda de proyecto, los documentos de cliente no aparecen en la consulta de proyecto: llevan sus campos, pero no son proyectos.

A partir de ahí el bloque insertado es contenido ordinario — se puede modificar, ampliar con columnas, ordenación o límite, mover y borrar como cualquier otra consulta. Un documento que lo contiene es así también una vista guardada: se puede nombrar, enlazar y marcar. A la inversa: la consulta refleja la asignación en el momento de generarse. Si más tarde se añade una vinculación, el bloque ya escrito no la sigue; entonces se genera de nuevo o se completa a mano.

El comando desaparece con la extensión «Perfiles de propiedades» desactivada.

Campos derivados

Dos clases de campo no llevan su valor, sino que lo reciben al mostrarse. Un campo de fórmula calcula a partir de los demás campos del mismo documento; un campo de recopilación reúne los documentos que apuntan a este mediante un campo indicado:

---
fields:
  - name: neto
    type: number
  - name: impuesto
    type: number
  - name: bruto
    type: formula
    options:
      expression: neto + impuesto
  - name: artículos
    type: lookup
    options:
      from: FROM "Artículos"
      relatedField: proyecto
---

Una expresión de fórmula usa el mismo lenguaje y el mismo catálogo de funciones que una columna de consulta, incluido el cálculo de fechas y duraciones; puede referirse a cualquier otro campo del documento, incluso a otro campo de fórmula. El orden en el archivo de perfil no importa.

El valor no está en el archivo. Surge cuando alguien lo mira y luego vuelve a desaparecer: abrir un documento no lo modifica, y el valor siempre está al día. Por eso, en ambos editores de propiedades los campos derivados aparecen como no editables, sin botón de borrado y con el tipo bloqueado; tampoco se ofrecen nunca para su adopción.

Si un valor queda vacío, una indicación en el campo dice por qué: dos campos se remiten en círculo, una regla de cálculo nombra un campo que aquí no existe, la expresión no se puede evaluar, o falta la regla por completo. Nunca se bloquea nada, y los demás campos siguen calculando.

Un campo de recopilación consulta el índice del área y por eso solo se evalúa cuando se muestra; el resultado vale hasta que cambie el contenido. Un enlace cuenta en todas sus escrituras —[[destino]], [[destino|etiqueta]] y el nombre desnudo—, y también acierta un enlace que pase por un alias de este documento.

La contrapartida se asume conscientemente: como un valor derivado no está en el archivo, tampoco está en el índice y no admite condición de consulta. Donde eso moleste, que calcule la consulta: puede hacer lo mismo.

Campos estructurados

Un campo puede llevar un objeto con campos hijos con nombre o una lista de objetos semejantes. Sin ellos, «reunión con tres participantes» necesitaría tres listas paralelas para nombre, función y empresa, cuya relación solo está en el orden:

---
fields:
  - name: participantes
    type: objectlist
    fields:
      - name: persona
        type: link
      - name: función
        values: [Dirección, Acta, Invitado]
---

Las definiciones hijas están anidadas y siguen el mismo esquema que el nivel superior: pueden llevar cualquier tipo, incluido otro objeto, y tener sus propios rangos de valores y opciones. Un tipo objeto sin fields está admitido; entonces muestra su valor solo en lectura.

Ambos editores de propiedades los muestran apilados: los campos hijos sangrados bajo su campo, cada uno con el control de su tipo; en una lista, cada entrada forma un grupo con un botón para quitarla y, debajo, uno para añadir. Una entrada nueva nace vacía, y un campo hijo aún sin definir permanece visiblemente vacío en lugar de rellenarse; tampoco se escribe.

En el bloque de metadatos los valores aparecen como una estructura anidada corriente:

---
class: Reunión
participantes:
  - persona: "[[Anna Ejemplo]]"
    función: Dirección
  - persona: "[[Bo Muestra]]"
    función: Invitado
---

Así siguen siendo legibles sin la aplicación. Un valor hijo que ninguna definición explica no se pierde por ello: no obtiene control, pero se conserva.

Lo mismo vale para las propiedades de un párrafo (propiedades de bloque), con una diferencia: un valor estructurado allí no aparece en el índice del área y por eso no admite condición de consulta de bloque.

Validación suave

Las desviaciones nunca bloquean ni cambian el valor: un valor fuera del rango de valores o un valor que no corresponde al tipo definido solo produce un icono de aviso en el campo; la información sobre herramientas nombra el motivo. El Markdown y el frontmatter siguen siendo libremente editables, también directamente en el código fuente.

Límites

  • Un valor derivado no puede fijarse como valor ordinario; sigue siendo calculado. No se prevé un tipo para contenido anidado libre: basta la visualización de solo lectura.
  • Renombrar un archivo de perfil no cambia los valores de asignación en los documentos; entonces apuntan a un perfil inexistente (los ajustes marcan un perfil estándar que falta).
  • Los perfiles están directamente en la carpeta de perfiles; las subcarpetas no se incluyen.
  • Las definiciones actúan en los dos editores de propiedades. Los tipos de campo que estarían ligados a un lienzo espacial quedan aplazados hasta que exista uno.
  • La vinculación de un perfil a un grupo de marcadores y la asignación mediante una consulta están deliberadamente aplazadas; etiqueta y carpeta cubren los casos documentados y siguen siendo explicables.