CtrlK
BlogDocsLog inGet started
Tessl Logo
PluginPublic

adobe/aem-cloud-service

All AEM as a Cloud Service skills: component development, Workflow model design, development, triggering, launchers, debugging, and triaging, Dispatcher config authoring, advisory, incident response, performance tuning, and security hardening, Rapid Development Environment (RDE) deployment, log inspection, snapshots, and troubleshooting via `aio aem rde`, Jackrabbit Oak query/index tuning (property, Lucene index definitions), and extracting/inventorying JCR queries (XPath, SQL2, QueryBuilder) across a codebase.

Quality

85%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide
SecuritybySnyk

Low

Low-risk findings worth noting

Overview
Quality
Evals
Security
Files

aem-conventions.mdskills/create-component/references/

AEM Project Conventions

Configuration Source

Project configuration is loaded from .aem-skills-config.yaml in the project root (same level as pom.xml).

AI AGENT GATE CHECK - Read .aem-skills-config.yaml FIRST:

  • If file is missing or configured: false → STOP IMMEDIATELY. Do NOT read any other files. Do NOT explore the codebase. Display the configuration error message and WAIT.
  • If configured: true → Read project, package, and group values from that file. Proceed with component creation.

⚠️ AI AGENTS - ABSOLUTE RULES:

  1. READ .aem-skills-config.yaml FIRST - If missing or configured: false, STOP
  2. DO NOT read any other files in the repository to find values
  3. DO NOT explore /apps/, core/, pom.xml, or any existing components
  4. DO NOT infer values from folder structures, package names, or existing code
  5. ONLY USE VALUES FROM .aem-skills-config.yaml after configured: true
  6. VIOLATION = IMMEDIATE FAILURE - Any inference attempt is a rule violation

File Structure

Component Files

ui.apps/src/main/content/jcr_root/apps/[project]/components/{component-name}/
├── .content.xml                    # Component definition
├── {component-name}.html           # HTL template
├── _cq_dialog/
│   └── .content.xml                # Component dialog
└── _cq_editConfig.xml              # Edit configuration (optional)

Sling Models

core/src/main/java/[package-path]/
├── models/
│   ├── {ComponentName}Model.java   # Main component model
│   └── {ItemName}.java             # Child model (for multifield)
├── filters/
├── servlets/
├── services/
└── schedulers/

Note: [package-path] = [package] with dots replaced by slashes (e.g., com/mysite/core)

Unit Tests

core/src/test/java/[package-path]/
├── models/
│   └── {ComponentName}ModelTest.java
└── testcontext/                    # (optional)
    └── AppAemContext.java          # Optional shared test context helper

Clientlibs

ui.apps/src/main/content/jcr_root/apps/[project]/clientlibs/
├── clientlib-base/                 # Base styles/scripts
├── clientlib-site/                 # Site-wide
├── clientlib-dependencies/         # Third-party
└── clientlib-{component-name}-dialog/  # Component dialog clientlib

Component Definition Template

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:Component"
    jcr:title="{Component Display Title}"
    jcr:description="{Component Description}"
    componentGroup="[group]"
    generatedBy="aem-dev-agent"/>

Naming Conventions

ElementConventionExample
Component folderkebab-casehero-banner, tiles-list
HTL filematch folder namehero-banner.html
Sling Model classPascalCase + ModelHeroBannerModel.java
Multifield item classPascalCaseTileItem.java, LinkItem.java
Test classPascalCase + TestHeroBannerModelTest.java
CSS class (BEM)cmp-{name}__{element}cmp-hero-banner__title
Dialog clientlib category[project].{name}.dialog[project].hero-banner.dialog
Site clientlib category[project].{type}[project].base, [project].site

Name Transformation Examples

Component NameModel ClassTest ClassCSS Prefix
hero-bannerHeroBannerModelHeroBannerModelTestcmp-hero-banner
tiles-listTilesListModelTilesListModelTestcmp-tiles-list
contact-formContactFormModelContactFormModelTestcmp-contact-form

General Rules

Code Quality

  1. Always use Apache 2.0 license header in Java files
  2. Follow BEM naming for CSS: cmp-{component-name}__{element}--{modifier}
  3. Use meaningful, descriptive names
  4. Keep files focused (single responsibility)

AEM Best Practices

  1. Use Sling Models for business logic (not JSP/scripts)
  2. Follow HTL (Sightly) best practices (see htl-patterns.md)
  3. Include proper JCR node types and properties
  4. Use Touch UI dialogs (not Classic UI)

Component Design

  1. Implement hasContent() or isEmpty() in models
  2. Handle null/empty gracefully
  3. Use data-cmp-is attribute for JavaScript hooks
  4. Support author edit mode appropriately

Dialog Field Type Reference

For field type mappings (dialog field types → Granite resource types, Sling Model annotations), see assets/field-type-mappings.md or the Quick Reference table in SKILL.md.

For detailed dialog configuration, see dialog-patterns.md


Sling Model Annotations Quick Reference

AnnotationPurposeExample
@ValueMapValueSimple property@ValueMapValue private String title;
@ChildResourceNested resource@ChildResource(name="image") private Resource img;
@ChildResourceMultifield list@ChildResource(name="items") private List<Resource> items;
@SlingObjectCurrent resource@SlingObject private Resource resource;
@PostConstructInit logic@PostConstruct protected void init() {}

For detailed model patterns, see model-patterns.md


Related Rules Files

This project uses modular rules files for specific aspects:

Rules FilePurpose
dialog-patterns.mdDialog XML structure, field types, validation
htl-patterns.mdHTL template patterns, expressions, accessibility
model-patterns.mdSling Model structure, annotations, patterns
clientlib-patterns.mdClientlib structure, JS/CSS patterns
java-standards.mdJava code quality, Javadoc, error handling
test-patterns.mdUnit test structure, scenarios, assertions

Cross-File Coordination

When creating components, ensure consistency across all files:

Dialog field name="./title"
        ↓
Model: @ValueMapValue private String title;
        ↓
HTL: ${model.title}
        ↓
CSS: .cmp-component__title
Dialog PropertyModel FieldHTL ExpressionCSS Class
./titletitle${model.title}__title
./descriptiondescription${model.description @ context='html'}__description
./linkURLlinkURL${model.linkURL @ extension='html'}__link
./items (multifield)List<ItemModel> items${model.items} via data-sly-list__item

Placeholder Reference

All other rules files use these placeholders. The AI will substitute your configured values:

PlaceholderSubstituted WithUsed In
[project]Your project namePaths, resource types, clientlib categories
[package]Your Java packageModel imports, package declarations
[group]Your component groupComponent definitions
[package-path]Package as pathDirectory structures

skills

README.md

tile.json