enonic-controller-generator
Enonic XP Controller Generator
Procedures
Step 1: Detect Enonic XP Project
- Execute
node scripts/find-enonic-targets.mjs <workspace-root>to locate the project root and existing components. - If the script exits with code 1 (no markers found), inform the user that no Enonic XP project was detected and stop.
- Record the
sitePathfrom stdout — all generated files target directories relative to this path.
Step 2: Determine Component Type
- Identify which component type the user requires:
- Page — renders a full page, may declare one or more regions.
- Part — a leaf component with a config form, no regions.
- Layout — organizes other components via named regions.
- Response processor — a site-level filter that modifies the HTTP response (e.g., inject scripts).
- If the request is ambiguous, ask the user to clarify the component type before proceeding.
Step 3: Gather Component Details
- Ask for or infer the following:
- Component name (kebab-case, e.g.,
hero-banner). - Display name (human-readable, e.g.,
Hero Banner). - Language — TypeScript (
.ts, default) or JavaScript (.js). Readreferences/compatibility.mdfor guidance on TS vs JS differences. - Template engine — Thymeleaf (default) or Mustache.
- For pages/layouts: region names (default:
mainfor pages). - For parts: form fields (name, type, occurrences).
- For response processors: page contribution target (
bodyEnd,headEnd, etc.) and the content to inject.
- Component name (kebab-case, e.g.,
Step 4: Generate the XML Descriptor
- Read
references/controller-reference.mdfor the XML descriptor schema. - Create the descriptor file:
- Page:
<sitePath>/pages/<name>/<name>.xml - Part:
<sitePath>/parts/<name>/<name>.xml - Layout:
<sitePath>/layouts/<name>/<name>.xml
- Page:
- Include
<display-name>,<description>,<form>(with inputs for parts), and<regions>(for pages and layouts).
Step 5: Generate the Controller
- Read the appropriate template from
assets/:assets/page-controller.template.tsfor pages.assets/part-controller.template.tsfor parts.assets/layout-controller.template.tsfor layouts.
- Replace placeholders with the actual component name, config field mappings, region names, and library imports.
- If JavaScript was requested, convert the ES module syntax to CommonJS (
require/exports). - Read
references/controller-reference.mdfor the Portal API surface (functions, import paths). - Place the controller at:
- Page:
<sitePath>/pages/<name>/<name>.ts(or.js) - Part:
<sitePath>/parts/<name>/<name>.ts(or.js) - Layout:
<sitePath>/layouts/<name>/<name>.ts(or.js) - Processor:
<sitePath>/processors/<name>.js
- Page:
Step 6: Generate the View (if applicable)
- For pages, parts, and layouts using Thymeleaf or Mustache, generate a paired
.htmlview file in the same directory as the controller. - For pages and layouts, include
data-portal-region="<region-name>"attributes on container elements. - For region iteration, use
data-th-each="component : ${region.components}"withdata-portal-component="${component.path}".
Step 7: Wire Response Processors (if applicable)
- If generating a response processor, check whether
<sitePath>/site.xmlexists. - If it exists, add a
<response-processor>entry inside the<processors>block. - If it does not exist, create
<sitePath>/site.xmlwith the processor declaration.
Step 8: Update build.gradle Dependencies
- Check the project's
build.gradlefor existing library includes. - Add any missing dependencies:
com.enonic.xp:lib-portal:${xpVersion}— required for all controllers.com.enonic.xp:lib-content:${xpVersion}— if the controller uses content queries.com.enonic.lib:lib-thymeleaf:2.0.0— if using Thymeleaf rendering.com.enonic.lib:lib-mustache:2.1.0— if using Mustache rendering.com.enonic.lib:lib-asset:${libVersion}— if the controller generates asset URLs (replaces the deprecatedportalLib.assetUrlin XP 7.15+).
Step 9: Validate Output
- Verify the descriptor file name matches the parent directory name exactly.
- Verify the controller file name matches the descriptor directory name.
- Verify all region names in the controller/view match those declared in the XML descriptor.
- Read
references/examples.mdto cross-check the generated code against known-good patterns.
Error Handling
- If
scripts/find-enonic-targets.mjsexits with code 1 (NO_PROJECT), inform the user that no Enonic XP project was found and suggest creating the standard directory structure undersrc/main/resources/site/. - If a component with the same name already exists at the target path, warn the user and ask whether to overwrite or rename.
- If the user reports a 404 on a part or missing regions, read
references/troubleshooting.mdto diagnose common causes. - If the generated controller fails at runtime with view resolution errors, verify the view file is co-located with the controller and the
resolve()call uses the correct filename.
More from webmaxru/enonic-agent-skills
enonic-webhook-integrator
Sets up Enonic XP event listeners, webhook configurations, and external system integrations triggered by content lifecycle events. Covers lib-event listener registration, node event filtering, outbound webhook configuration via com.enonic.xp.webhooks.cfg, custom HTTP service controllers for inbound webhooks, task-based async processing with lib-task, and outbound HTTP calls with lib-httpClient. Use when listening for content publish/create/update/delete events, configuring outbound webhooks, building HTTP service endpoints for inbound webhooks, or triggering async processing on content changes. Do not use for content querying, frontend component development, non-Enonic event systems, or GitHub webhook configuration.
91skill-creator
Authors and structures professional-grade agent skills following the agentskills.io spec. Use when creating new skill directories, drafting procedural instructions, or optimizing metadata for discoverability. Don't use for general documentation, non-agentic library code, or README files.
89enonic-api-reference
Enonic XP server-side JavaScript/TypeScript API reference for all /lib/xp/* libraries. Provides function signatures, parameters, return types, and usage examples for lib-content, lib-node, lib-auth, lib-portal, lib-context, lib-event, lib-task, lib-repo, lib-io, lib-mail, and lib-schema. Use when looking up Enonic XP library functions, parameter shapes, return types, or usage examples. Do not use for Guillotine GraphQL queries, content type schema definitions, Enonic CLI commands, or non-Enonic JavaScript APIs.
89agent-skill-deploy
>
89enonic-content-migration
Generates Enonic XP scripts for bulk content operations — creating, updating, querying, migrating, and transforming content using lib-content and lib-node APIs. Covers the query DSL (NoQL), aggregations, batch processing, task controllers for long-running operations, and export/import workflows. Use when writing bulk content creation, update, or deletion scripts, querying with NoQL syntax, migrating content between environments, running long-running task operations, or working with aggregations and paginated retrieval. Do not use for Guillotine GraphQL frontend queries, content type schema definitions, single contentLib.get() calls, or non-Enonic data migration tools.
89enonic-sandbox-manager
Guides developers through Enonic CLI commands for sandbox management, project scaffolding, local development, app deployment, and CI/CD pipeline generation. Use when creating Enonic XP sandboxes, starting or stopping local instances, scaffolding projects from starters, running dev mode with hot-reload, deploying apps, or generating CI/CD workflows for Enonic apps. Don't use for writing XP application code (controllers, content types), querying via Guillotine or lib-content APIs, configuring non-Enonic environments, or Docker/Kubernetes deployment of XP.
89