Generates Enonic XP controller files (TypeScript/JavaScript) and paired XML descriptors for pages, parts, and layouts. Covers lib-portal imports, HTTP handler exports, region definitions, Thymeleaf/Mustache rendering, and response processors. Use when scaffolding page controllers with regions, part controllers with config access, layout controllers with multi-region support, or response processors for Enonic XP sites. Do not use for content type schemas, headless Next.js/React frontends, GraphQL Guillotine queries, or non-Enonic web frameworks.
80
100%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Step 1: Detect Enonic XP Project
node scripts/find-enonic-targets.mjs <workspace-root> to locate the project root and existing components.sitePath from stdout — all generated files target directories relative to this path.Step 2: Determine Component Type
Step 3: Gather Component Details
hero-banner).Hero Banner)..ts, default) or JavaScript (.js). Read references/compatibility.md for guidance on TS vs JS differences.main for pages).bodyEnd, headEnd, etc.) and the content to inject.Step 4: Generate the XML Descriptor
references/controller-reference.md for the XML descriptor schema.<sitePath>/pages/<name>/<name>.xml<sitePath>/parts/<name>/<name>.xml<sitePath>/layouts/<name>/<name>.xml<display-name>, <description>, <form> (with inputs for parts), and <regions> (for pages and layouts).Step 5: Generate the Controller
assets/:
assets/page-controller.template.ts for pages.assets/part-controller.template.ts for parts.assets/layout-controller.template.ts for layouts.require/exports).references/controller-reference.md for the Portal API surface (functions, import paths).<sitePath>/pages/<name>/<name>.ts (or .js)<sitePath>/parts/<name>/<name>.ts (or .js)<sitePath>/layouts/<name>/<name>.ts (or .js)<sitePath>/processors/<name>.jsStep 6: Generate the View (if applicable)
.html view file in the same directory as the controller.data-portal-region="<region-name>" attributes on container elements.data-th-each="component : ${region.components}" with data-portal-component="${component.path}".Step 7: Wire Response Processors (if applicable)
<sitePath>/site.xml exists.<response-processor> entry inside the <processors> block.<sitePath>/site.xml with the processor declaration.Step 8: Update build.gradle Dependencies
build.gradle for existing library includes.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 deprecated portalLib.assetUrl in XP 7.15+).Step 9: Validate Output
references/examples.md to cross-check the generated code against known-good patterns.scripts/find-enonic-targets.mjs exits with code 1 (NO_PROJECT), inform the user that no Enonic XP project was found and suggest creating the standard directory structure under src/main/resources/site/.references/troubleshooting.md to diagnose common causes.resolve() call uses the correct filename.029e044
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.