Manual · 10

Páginas dinámicas (Catch-All)

¿Quieres una lista en /blog y el artículo en /blog/mein-artikel, sin crear una página propia para cada artículo? Para eso existe Catch-All.

  1. Crea la página /blog y, en Ajustes, marca Catch-All.
  2. En la Collection blog, crea un campo slug (la parte de la URL de cada artículo).
  3. HTML de la página /blog:
{% if route.slug %}
  {% with post=item("blog", "slug", route.slug) %}
    {% if not post %}{{ not_found() }}{% endif %}
    <article>
      <h1>{{ post.titel }}</h1>
      <p class="datum">{{ post.datum }}</p>
      {{ image(post.bild, "(min-width: 900px) 60vw, 100vw") }}
      {{ post.text|markdown }}
      <a href="/blog">← Todos los artículos</a>
    </article>
  {% endwith %}
{% else %}
  <h1>Blog</h1>
  {% for post in data("blog", "sort", "-datum") %}
    <a class="teaser" href="/blog/{{ post.slug }}">
      <h2>{{ post.titel }}</h2>
      <p>{{ post.text|truncatechars:160 }}</p>
    </a>
  {% endfor %}
{% endif %}
  1. Título SEO de la página:
{% if route.slug %}{{ item("blog", "slug", route.slug).titel }} – {% endif %}Blog

Así funciona:

  • /blog → route.slug está vacío → lista.
  • /blog/mein-artikel → no existe ninguna página mein-artikel → la página Catch-All responde con route.slug = "mein-artikel".
  • /blog/gibts-nicht → item() no encuentra nada → not_found() devuelve la página 404 con estado 404.
  • Las subpáginas reales tienen prioridad: si creas /blog/archiv como página normal, se muestra esa.
  • Rutas de varios niveles: /blog/2025/rueckblick da route.slug = "2025/rueckblick", route.rest.0 = "2025", route.rest.1 = "rueckblick".

Para probar, la vista previa de las páginas Catch-All tiene el campo Subruta. Si el template llama a not_found() (p. ej. sin subruta), la vista previa muestra, en lugar de un error, un aviso con las subrutas existentes, obtenidas de la fuente del sitemap o de la Collection detectada.

Sitemap: si en el HTML, en el título SEO o en el campo Head de la página Catch-All aparece item("<collection>", "<feld>", route.slug), IllusionCMS incluye todas las entradas publicadas de esa Collection como páginas de detalle en /sitemap.xml (no los borradores ni las entradas sin valor en el campo). Las subpáginas reales tienen prioridad.

Páginas de detalle de otras fuentes: si la página lee sus datos de otra forma, desde IllusionDB, una fuente REST o mediante un Workflow, defines la fuente en los Ajustes de la página Catch-All, en Páginas de detalle para el sitemap y la exportación estática:

  • Tabla de IllusionDB: conexión, tabla, la columna con la parte de la URL (p. ej. slug), opcionalmente una columna con la fecha de modificación (<lastmod>) y reglas o una vista guardada como filtro, p. ej. solo aktiv = true.
  • Workflow: la entrada HTTP de un Workflow (como con workflow()) que devuelve una lista: objetos con el campo de URL o simplemente textos. Recibe sitemap=1 en msg.payload. Así llegan también al sitemap las fuentes REST y las listas calculadas.
  • Comprobar muestra cuántas páginas de detalle resultan y las primeras direcciones. Los valores con / dan rutas de varios niveles (berlin/zahnarzt → /leistungen/berlin/zahnarzt).
  • De IllusionDB solo se consultan la columna con la parte de la URL y la fecha.
  • La lista se guarda en caché 10 minutos. Si en algún momento la fuente no está disponible, el último estado se mantiene en el sitemap, en lugar de que desaparezcan miles de direcciones.
  • A partir de 50 000 direcciones, /sitemap.xml se convierte automáticamente en un índice de sitemaps con /sitemap-1.xml, /sitemap-2.xml, … (límite de los buscadores por archivo).
  • La exportación estática incluye las mismas páginas de detalle, aunque nada enlace a ellas.

Datos de IllusionDB: las páginas de detalle también pueden obtener sus registros directamente de una base de datos, mediante un Workflow con el node IllusionDB; consulta Workflows → IllusionDB.