Saltar al contenido
openplate

La aplicación

Páginas de contenido

Las páginas legales como archivos markdown que montas (CONTENT_DIR): la carpeta, el formato de archivo, qué se rechaza y las secciones con nombre de las dos páginas de botones reglamentarios

Esta página es una traducción automática de la documentación en inglés.

openplate carga páginas legales a partir de archivos markdown que montas en el contenedor. El repositorio no contiene ningún texto legal propio. Tú redactas los términos, la política de privacidad, el aviso legal (imprint) y las páginas de los dos botones reglamentarios. Describen tu instancia y te identifican como el operador.

Cómo activarla

Define CONTENT_DIR con una carpeta que la aplicación pueda leer:

sh
CONTENT_DIR=/srv/openplate-content

Con un contenedor, monta la carpeta en solo lectura y apunta la variable al punto de montaje:

yaml
services:
  openplate:
    environment:
      CONTENT_DIR: /content
    volumes:
      - ./content:/content:ro

Un valor que no apunte a ninguna carpeta detiene el arranque. Un fallo de montaje se nota de inmediato. La aplicación no puede iniciarse y mostrarse como una instancia sin páginas legales.

Con CONTENT_DIR sin definir

Este es el comportamiento predeterminado, y conviene para una instancia doméstica que no vende nada.

  • Cada ruta de contenido responde 404: /terms, /privacy, /privacy/website, /imprint, /withdrawal, /kuendigung, /kuendigung/bestaetigt, /widerrufen y /widerrufen/bestaetigt.
  • El pie de página público solo dibuja Fuente, Licencia y Preferencias. Los cinco enlaces legales (Privacidad, Términos, Imprint y los dos botones reglamentarios) no se dibujan.
  • Ajustes, Acerca de no tiene el grupo Legal. Con la carpeta montada, esa página enumera los mismos cinco enlaces bajo el encabezado Legal, de modo que una persona con la sesión iniciada, que no ve el pie de página, aún puede acceder al aviso legal.
  • La nota que ve un visitante que no ha iniciado sesión en una página personal enlaza al inicio y al inicio de sesión, sin enlace al aviso legal ni a la privacidad.
  • El formulario del boletín, si lo activaste, omite la línea de privacidad.

Los enlaces reaparecen cuando la carpeta contiene un imprint.md, en el idioma del lector o en inglés. El aviso legal sirve de comprobación porque la legislación alemana lo exige en cualquier instancia que publique cualquiera de los demás.

La carpeta

<CONTENT_DIR>/
  en/
    terms.md
    privacy.md
    imprint.md
    ...
  de/
    terms.md
    ...

Una carpeta por idioma: en, de, fr, it, es o tr. Un archivo por página, nombrado por su slug:

SlugRuta en la aplicación
terms/terms
privacy/privacy
privacy-website/privacy/website
imprint/imprint
withdrawal/withdrawal
kuendigung/kuendigung
kuendigung-bestaetigt/kuendigung/bestaetigt
widerrufen/widerrufen
widerrufen-bestaetigt/widerrufen/bestaetigt

Una página que falte en el idioma del lector se sirve en inglés. Una página que también falte en inglés devuelve un 404. La aplicación solo lee estos slugs. Nunca construye una ruta a partir de una URL.

La aplicación lee cada archivo al recibir una petición y mantiene la página procesada en memoria. Vuelve a leer el archivo cuando cambian su fecha de modificación o su tamaño. Cualquier cambio en un archivo montado aparece en la siguiente petición sin necesidad de reiniciar.

El formato de archivo

UTF-8, finales de línea LF, sin marca de orden de bytes (BOM). Cada archivo empieza exactamente con este front matter:

---
title: Terms of service
updated: 2026-09-21
---

title es el encabezado de la página. updated es una fecha del calendario, y la aplicación la dibuja bajo el encabezado como "Última actualización", en el idioma del lector. No repitas ninguno de los dos en el cuerpo.

El cuerpo solo utiliza este subconjunto:

  • Encabezados ## y ###. # es el título y nunca se escribe.
  • Párrafos, separados por una línea en blanco.
  • Listas con - o 1. , de un solo nivel, sin sangría.
  • **strong** y *emphasis*.
  • Enlaces [text](target). El destino es una ruta dentro de la app (/imprint), https://, mailto: o tel:. Las rutas de la app se abren sin recargar la página.
  • Salto de línea manual: una barra invertida como último carácter de la línea, seguida de la siguiente línea del mismo párrafo. Úsala para direcciones postales.
  • Lista de definiciones: una línea con el término seguida de una o más líneas con : definition, sin líneas en blanco entre las entradas.
  • Carácter de escape: una barra invertida antes de \, *, [ o ] hace que se interprete de forma literal.

Los párrafos anteriores al primer encabezado forman la entradilla de la página y se muestran con un tamaño mayor.

Qué se rechaza

Cualquier tipo de HTML sin procesar (un < seguido de una letra, /, ! o ?), referencias a caracteres HTML como &amp;, imágenes, tablas, código, citas en bloque, encabezados # o ####, listas anidadas o con sangría y cualquier marcador de posición {{.

Los archivos que no respetan el formato se se rechaza, no se repara. La app registra cada error junto con su número de línea, una sola vez por versión del archivo. La página devuelve un 503 con la pantalla de error neutra. Si una página legal omitiera una tabla en silencio o mostrara una etiqueta como texto, publicaría un documento que nadie redactó. Corrige el archivo y la siguiente petición lo servirá de inmediato.

Secciones con nombre

Hay dos páginas que mantienen un formulario en el código de la app: /kuendigung (cancelar un contrato) y /widerrufen (desistir de un contrato). Sus páginas de confirmación mantienen el justificante en el código. Las etiquetas del formulario, los botones, los mensajes de validación y las líneas del justificante forman parte de la app. El texto que los rodea procede del archivo. Una sección con nombre contiene cada fragmento que la app sitúa alrededor del formulario:

:::section unavailable
Text of the section, in the same subset.
:::

Cada una de estas páginas debe incluir exactamente las secciones indicadas abajo, una sola vez cada una. Si falta una sección o se añade una de más, se rechaza como cualquier otro error.

SlugSecciónDónde lo muestra la app
kuendigung(cuerpo)La entradilla, encima del formulario de cancelación.
kuendigungunavailableEn el lugar del formulario si CORE_URL no está configurado, y debajo del botón de envío si el envío no puede conectar con el servicio de declaraciones.
kuendigung-bestaetigt(cuerpo)Normalmente vacío.
kuendigung-bestaetigtmail-noticeDespués de las líneas del justificante y antes del botón de imprimir.
widerrufen(cuerpo)La entradilla, encima del formulario de desistimiento.
widerrufenunavailableIgual que en kuendigung.
widerrufen-bestaetigt(cuerpo)Normalmente vacío.
widerrufen-bestaetigtmail-noticeIgual que en kuendigung-bestaetigt.

El resto de páginas no tienen secciones: todo su cuerpo constituye la página completa.

El título de kuendigung es el texto exigido por la legislación alemana para esa página, y lo mismo se aplica a widerrufen. El pie de página y los botones de envío de la app ya incluyen los textos legales requeridos para los botones.

De dónde obtienen sus archivos las instancias de openplate

Las instancias alojadas montan los archivos guardados en un repositorio privado, con un árbol por instancia. Ese repositorio valida cada archivo frente a este formato antes de distribuirlo. Si una página es rechazada, se detecta antes de que llegue a un servidor.

Edita esta página en GitHub