enonic-controller-generator
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseEnonic XP Controller Generator
Enonic XP 控制器生成器
Procedures
操作步骤
Step 1: Detect Enonic XP Project
- Execute to locate the project root and existing components.
node scripts/find-enonic-targets.mjs <workspace-root> - If the script exits with code 1 (no markers found), inform the user that no Enonic XP project was detected and stop.
- Record the from stdout — all generated files target directories relative to this path.
sitePath
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 (, default) or JavaScript (
.ts). Read.jsfor guidance on TS vs JS differences.references/compatibility.md - Template engine — Thymeleaf (default) or Mustache.
- For pages/layouts: region names (default: for pages).
main - For parts: form fields (name, type, occurrences).
- For response processors: page contribution target (,
bodyEnd, etc.) and the content to inject.headEnd
- Component name (kebab-case, e.g.,
Step 4: Generate the XML Descriptor
- Read for the XML descriptor schema.
references/controller-reference.md - 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>(with inputs for parts), and<form>(for pages and layouts).<regions>
Step 5: Generate the Controller
- Read the appropriate template from :
assets/- for pages.
assets/page-controller.template.ts - for parts.
assets/part-controller.template.ts - for layouts.
assets/layout-controller.template.ts
- 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 for the Portal API surface (functions, import paths).
references/controller-reference.md - Place the controller at:
- Page: (or
<sitePath>/pages/<name>/<name>.ts).js - Part: (or
<sitePath>/parts/<name>/<name>.ts).js - Layout: (or
<sitePath>/layouts/<name>/<name>.ts).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 view file in the same directory as the controller.
.html - For pages and layouts, include attributes on container elements.
data-portal-region="<region-name>" - For region iteration, use with
data-th-each="component : ${region.components}".data-portal-component="${component.path}"
Step 7: Wire Response Processors (if applicable)
- If generating a response processor, check whether exists.
<sitePath>/site.xml - If it exists, add a entry inside the
<response-processor>block.<processors> - If it does not exist, create with the processor declaration.
<sitePath>/site.xml
Step 8: Update build.gradle Dependencies
- Check the project's for existing library includes.
build.gradle - Add any missing dependencies:
- — required for all controllers.
com.enonic.xp:lib-portal:${xpVersion} - — if the controller uses content queries.
com.enonic.xp:lib-content:${xpVersion} - — if using Thymeleaf rendering.
com.enonic.lib:lib-thymeleaf:2.0.0 - — if using Mustache rendering.
com.enonic.lib:lib-mustache:2.1.0
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 to cross-check the generated code against known-good patterns.
references/examples.md
步骤1:检测Enonic XP项目
- 执行命令定位项目根目录和现有组件。
node scripts/find-enonic-targets.mjs <workspace-root> - 如果脚本退出码为1(未找到项目标记),告知用户未检测到Enonic XP项目并终止流程。
- 记录标准输出中的——所有生成的文件都会放在该路径对应的相对目录下。
sitePath
步骤2:确定组件类型
- 确认用户需要的组件类型:
- Page —— 渲染完整页面,可声明一个或多个区域。
- Part —— 带配置表单的叶子组件,无区域。
- Layout —— 通过命名区域组织其他组件。
- Response processor —— 站点级别的过滤器,用于修改HTTP响应(例如注入脚本)。
- 如果需求不明确,先请用户明确组件类型再继续。
步骤3:收集组件详情
- 询问或推断以下信息:
- 组件名称(kebab-case格式,例如)。
hero-banner - 显示名称(人类可读格式,例如)。
Hero Banner - 开发语言 —— TypeScript(,默认)或JavaScript(
.ts),可参考.js了解TS和JS的差异。references/compatibility.md - 模板引擎 —— Thymeleaf(默认)或Mustache。
- 页面/布局类组件:区域名称(页面默认值为)。
main - Part类组件:表单字段(名称、类型、出现次数)。
- 响应处理器:页面注入目标位置(、
bodyEnd等)以及要注入的内容。headEnd
- 组件名称(kebab-case格式,例如
步骤4:生成XML描述符
- 参考中的XML描述符Schema。
references/controller-reference.md - 创建描述符文件:
- 页面:
<sitePath>/pages/<name>/<name>.xml - Part:
<sitePath>/parts/<name>/<name>.xml - 布局:
<sitePath>/layouts/<name>/<name>.xml
- 页面:
- 包含、
<display-name>、<description>(Part组件需包含输入项)和<form>(页面和布局组件需要)标签。<regions>
步骤5:生成控制器
- 从目录读取对应模板:
assets/- 页面对应
assets/page-controller.template.ts - Part对应
assets/part-controller.template.ts - 布局对应
assets/layout-controller.template.ts
- 页面对应
- 用实际的组件名称、配置字段映射、区域名称和库导入替换占位符。
- 如果用户选择JavaScript,将ES模块语法转换为CommonJS(/
require)。exports - 参考了解Portal API范围(函数、导入路径)。
references/controller-reference.md - 将控制器文件放在对应路径:
- 页面:(或
<sitePath>/pages/<name>/<name>.ts).js - Part:(或
<sitePath>/parts/<name>/<name>.ts).js - 布局:(或
<sitePath>/layouts/<name>/<name>.ts).js - 处理器:
<sitePath>/processors/<name>.js
- 页面:
步骤6:生成视图(如适用)
- 对于使用Thymeleaf或Mustache的页面、Part、布局组件,在控制器同级目录生成对应的视图文件。
.html - 页面和布局组件的容器元素需要添加属性。
data-portal-region="<region-name>" - 区域迭代使用搭配
data-th-each="component : ${region.components}"实现。data-portal-component="${component.path}"
步骤7:注册响应处理器(如适用)
- 如果生成的是响应处理器,检查是否存在。
<sitePath>/site.xml - 如果存在,在块中添加
<processors>条目。<response-processor> - 如果不存在,创建并添加处理器声明。
<sitePath>/site.xml
步骤8:更新build.gradle依赖
- 检查项目中已有的库引入。
build.gradle - 添加缺失的依赖:
- —— 所有控制器都需要。
com.enonic.xp:lib-portal:${xpVersion} - —— 如果控制器使用内容查询。
com.enonic.xp:lib-content:${xpVersion} - —— 如果使用Thymeleaf渲染。
com.enonic.lib:lib-thymeleaf:2.0.0 - —— 如果使用Mustache渲染。
com.enonic.lib:lib-mustache:2.1.0
步骤9:验证输出
- 确认描述符文件名与父目录名完全一致。
- 确认控制器文件名与描述符所在目录名一致。
- 确认控制器/视图中所有区域名称与XML描述符中声明的一致。
- 参考将生成的代码与已知的正确模式交叉校验。
references/examples.md
Error Handling
错误处理
- If exits with code 1 (
scripts/find-enonic-targets.mjs), inform the user that no Enonic XP project was found and suggest creating the standard directory structure underNO_PROJECT.src/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 to diagnose common causes.
references/troubleshooting.md - If the generated controller fails at runtime with view resolution errors, verify the view file is co-located with the controller and the call uses the correct filename.
resolve()
- 如果退出码为1(
scripts/find-enonic-targets.mjs),告知用户未找到Enonic XP项目,建议在NO_PROJECT下创建标准目录结构。src/main/resources/site/ - 如果目标路径已存在同名组件,警告用户并询问是否覆盖或重命名。
- 如果用户反馈Part出现404或区域缺失,参考排查常见原因。
references/troubleshooting.md - 如果生成的控制器运行时出现视图解析错误,确认视图文件与控制器同目录,且调用使用了正确的文件名。
resolve()