04 / Cómo funciona Lupus

Drupal fuera de Canvas

Desacoplar no significa prescindir de las capacidades de Drupal. Significa ofrecer una salida compatible y conectar su comportamiento con el frontal. No todos los módulos funcionan sin adaptación.

Todos los recorridos ↗

Entidades y view modes / Funciona aquí

La ficha y los teasers usan displays CE para el mismo nodo. Los campos y formateadores siguen configurados en Drupal; el frontend implementa ntt-insight y ntt-insight-card.

Views / Funciona aquí

lupus_decoupled_views añade el display de página CE. Reutiliza selección, filtros, modos de visualización y pager. Esta demo prueba páginas; no afirma haber probado todos los plugins, AJAX o Views embebidas en Canvas.

Bloques y rutas de módulo / Nuevo ejemplo real

ntt_lupus_examples devuelve un CustomElement desde un controlador PHP compatible. lupus_decoupled_block incorpora bloques visibles por región en la propiedad blocks. Hemos colocado un bloque configurable solo en esa ruta; Next.js presenta la región content. Cabecera y navegación siguen en el shell Next.js: las demás regiones se inspeccionan, no se duplican en la web.

Form API / Soporte documentado, integración Next parcial

lupus_decoupled_form puede envolver HTML Form API en elementos drupal-form--*. Drupal conserva validación y procesamiento. El frontend debe reenviar POST, cookies y tokens, manejar errores, mensajes y redirects, y aportar CSS/JS. Nuxt dispone de middleware; nuestro adaptador Next no implementa ese ciclo genérico. Las pantallas de login y recuperación de aquí son React a medida con POST directo a Drupal, no una prueba de Form API genérico por CE.

Webform, Layout Builder y otros módulos / Evaluar

Hay submódulos para Webform y Layout Builder. Webform no está instalado aquí y sus bibliotecas JS no llegan automáticamente al frontend; widgets complejos requieren adaptación. Layout Builder necesita bloques con salida CE compatible. Un módulo de negocio puede ofrecer una ruta CE o datos a un componente, pero su PHP, Twig y comportamientos JS no se convierten solos.

Ejemplo real de esta instalación

Debajo se muestra el bloque recibido realmente en blocks.content. Cambia su mensaje en la administración de bloques, guarda y recarga el ejemplo: la fuente del texto sigue siendo Drupal.

blocks.content.ntt_delivery_note

Inspeccionar contrato recibido en servidor
{
  "title": "Drupal module / CE",
  "content_format": "json",
  "content": {
    "element": "ntt-module-example",
    "props": {
      "title": "Un módulo Drupal, renderizado en Next.js",
      "description": "Esta ruta devuelve un CustomElement desde un controlador PHP. No es una página Canvas ni un nodo. Drupal resuelve el acceso y añade el bloque configurado; React presenta ambos.",
      "routeName": "ntt_lupus_examples.module"
    }
  },
  "metatags": {
    "meta": [],
    "link": []
  },
  "blocks": {
    "sidebar_first": {
      "canvas_lupus_theme_page_title": {
        "element": "drupal-markup",
        "slots": {
          "default": "\n\n"
        }
      },
      "canvas_lupus_theme_powered": {
        "element": "drupal-markup",
        "slots": {
          "default": "<span>Powered by <a href=\"https://www.drupal.org\">Drupal</a></span>"
        }
      }
    },
    "content": {
      "ntt_delivery_note": {
        "element": "ntt-delivery-note",
        "props": {
          "title": "Un bloque Drupal reutilizable",
          "description": "Este mensaje procede de un bloque configurado en Drupal, no de Canvas ni de un texto fijo en React."
        }
      }
    },
    "header": {
      "canvas_lupus_theme_site_branding": {
        "element": "drupal-markup",
        "slots": {
          "default": "<img src=\"https://dev-headless-lupus.pantheonsite.io/themes/custom/canvas_lupus_theme/logo.svg\" alt=\"Home\" />\nCanvas Lupus POC"
        }
      }
    },
    "primary_menu": {
      "canvas_lupus_theme_main_menu": {
        "element": "drupal-markup",
        "slots": {
          "default": "\n              <ul>\n              <li>\n        <a href=\"/\" data-drupal-link-system-path=\"&lt;front&gt;\">Home</a>\n              </li>\n        </ul>\n  \n\n"
        }
      }
    },
    "secondary_menu": {
      "canvas_lupus_theme_account_menu": {
        "element": "drupal-markup",
        "slots": {
          "default": "\n              <ul>\n              <li>\n        <a href=\"/user/login\" data-drupal-link-system-path=\"user/login\">Log in</a>\n              </li>\n        </ul>\n  \n\n"
        }
      }
    },
    "highlighted": {
      "canvas_lupus_theme_messages": {
        "element": "drupal-markup",
        "slots": {
          "default": "<div data-drupal-messages-fallback class=\"hidden\"></div>"
        }
      }
    },
    "breadcrumb": {
      "canvas_lupus_theme_breadcrumbs": {
        "element": "drupal-markup",
        "slots": {
          "default": "  <nav aria-labelledby=\"system-breadcrumb\">\n    <h2 id=\"system-breadcrumb\" class=\"visually-hidden\">Breadcrumb</h2>\n    <ol>\n          <li>\n                  <a href=\"/\">Home</a>\n              </li>\n        </ol>\n  </nav>\n"
        }
      }
    }
  }
}

Fuentes de la arquitectura