Ir al contenido
Docxcelerate

Nodos

El modelo de nodos

Qué tienen en común todos los nodos, en qué se diferencian y dónde está documentado cada uno.

Un documento es un árbol de nodos. Todo nodo es tres cosas: un id, una clase y una regla para producir contenido.

paragraph<MemberData>({
  id: "greeting",                                // the address
  render: (data) => `Dear ${data.memberName},`,  // the rule
});                                              // the helper is the kind

Resuelto con tus datos, se convierte en JSON puro:

{ "id": "greeting", "kind": "paragraph", "mode": "static", "text": "Dear Adaeze Nkemelu," }

Sin estilos, sin maquetación. Eso le corresponde al renderizador.

Cada tipo tiene una página propia, con todas las opciones que admite y una vista previa de cada manera de escribirlo.

Estructura

section Groups nodes under a titled heading.

The only construct that nests today. Its title carries into the document outline, so the structure you write is the structure the reader sees.

Helpers: section, Section

export const Opening = section<SampleData>({ id: "opening", title: "Your renewal" }, [
  Greeting,
  PriceChange,
]);

Referencia de Section, con vistas previas →

tableOfContents A marker for a contents list, ahead of the renderers that build one. Aún sin helper

The kind is part of the letter schema and both renderers accept it, but no authoring helper is exported yet. Writing the component by hand works — a node component is a function returning a definition, and the helpers are conveniences over exactly that shape.

export const Contents: NodeComponent<SampleData> = () => ({
  kind: "tableOfContents",
  id: "contents",
  title: "What is in this letter",
});

Referencia de Table of contents, con vistas previas →

Texto

paragraph A block of prose, rendered from your data or from prompts.

The workhorse. A static paragraph returns a string from your typed data; a dynamic one carries prompts and a placeholder, and is filled at request time. Both land as the same node kind, differing only by `mode`.

export const Greeting = paragraph<SampleData>({
  id: "greeting",
  render: (data) => `Dear ${data.memberName},`,
});

Referencia de Paragraph, con vistas previas →

Medios

image A picture resolved from your data or described by a prompt.

A static image points at something you hold — a signature, a logo, a site photograph — with every field able to vary per recipient. A dynamic image describes what is wanted and leaves the endpoint to make it.

export const Signature = image<SampleData>({
  id: "signature",
  src: (data) => data.signatureUrl,
  alt: (data) => `Signed by ${data.managerName}`,
  width: 180,
  height: 60,
});

Referencia de Image, con vistas previas →

clipArt Named visual blocks — rules, marks, callouts — drawn by the renderer. Planeado

Not built yet. Nothing is fetched: the node names a shape and the renderer draws it, so it stays sharp in the DOCX and ships no asset.

Datos

graph A bar, line or pie chart declared as data.

Charts are declared, never drawn: `graphType` fixes the form, `data` returns the payload. Holding numbers rather than an image means one declaration serves every renderer and stays diffable in the artifact.

export const VisitsByMonth = graph<SampleData>({
  id: "visits-by-month",
  graphType: "bar",
  data: (data) => ({
    labels: data.visitsByMonth.map((entry) => entry.month),
    series: [{ name: "Visits", values: data.visitsByMonth.map((entry) => entry.visits) }],
  }),
  caption: (data) => `Your visits to ${data.centreName}, last six months`,
});

Referencia de Graph, con vistas previas →

table Rows and columns, with cells that are themselves nodes. Planeado

Not built yet. The intent is a node whose cells hold other nodes, so a table composes the way a section does rather than becoming a second content model beside it.

Los ids son direcciones

El id de un nodo es la forma en que un endpoint de generación apunta a ese párrafo, y la forma en que dos artefactos de compilación se alinean en un diff. Renombrar uno rompe todo lo que lo señale desde fuera, igual que renombrar una ruta de API.

Mantenlos únicos dentro del documento. No cuesta nada y hace legibles los logs.

Estático y dinámico

Un nodo estático calcula su contenido en local a partir de tus datos. Un nodo dinámico lleva prompts y un marcador de posición, y se rellena en el momento de la petición.

Nunca declaras cuál quieres. Hay un helper por clase — paragraph, image, graph — y el modo se infiere de las opciones que le des: aporta el miembro de resolución local (render, src, data) y el nodo es estático; aporta prompts en su lugar y es dinámico. Ambos se resuelven al mismo kind y se diferencian por mode en el documento compilado.

Aportar los dos es un error de compilación, así que mode tiene exactamente una fuente de verdad. Estático y dinámico explica dónde está la línea y por qué.

Anidamiento

section es hoy el único nodo que contiene hijos, y acepta cualquier clase, incluidas otras secciones. Un nodo de tabla con nodos en sus celdas es lo siguiente, con el mismo principio: los contenedores contienen los componentes que ya escribes, en lugar de un segundo modelo de contenido al lado.

Sobre estas vistas previas

Cada vista previa de aquí es una compilación real. src/nodes/, en el repositorio de este sitio, guarda un archivo por variante, escrito contra el paquete publicado; un paso de compilación resuelve cada uno mediante buildDocument y lo renderiza con el renderizador que sirve dxcl dev. El código que se muestra es el archivo que se ejecutó, y el JSON es lo que devolvió — de modo que estas páginas se rompen a gritos en vez de quedarse silenciosamente obsoletas.


Editar esta página en GitHub ↗