Guide to AEMaaCS Development with AI

Author: Tom Cranstoun
AEM Development with AI:

My Journey with Cline

AEMaaCS Development with AI: My Journey with Cline

After years of working with Adobe Experience Manager (AEM), I want to share something exciting that's transforming how I approach development. First, let me be clear - I'm not a traditional developer. While I understand AEM deeply from a technical perspective and have fixed my share of broken instances, I don't typically write components or workflows. My strength lies in understanding how AEM works at its core.

The Evolution of My Approach

I recently embarked on an experiment with AI-assisted development, going through three distinct phases before finding what I consider a game-changing solution. It started with exploring various tools and approaches, but the real breakthrough came when I discovered Cline (formerly known as Claude Dev). I started out with a ‘kitchen-sink’ approach, creating a RAG knowledge base for Edge Delivery Services and cursor IDE, as the internet does not have a huge history for EDS. This technique does not work for pure AEMaaCS -- too much info out there, no need for a RAG.

Originally, I employed a hard-coded strategy where I assigned a distinct domain name following a specific pattern. For instance, "my company name is tom.com", “my content group name is Tom Site - Content” etc. This involved manually creating and maintaining individual settings for each facet, which presented several challenges.

This naming convention is specific to this project's setup and is crucial for proper component organization and visibility in the AEM authoring interface.

Firstly, it was time-consuming to set up and manage the structures

Secondly, the hard-coded approach lacked flexibility. If a name or branding changed, I would need to manually update the values This process was not only tedious but also prone to errors.

Additionally, the hard-coded approach made it difficult to maintain consistency across different platforms and systems. For example, if I wanted to share this with another developer, on another project they would have to input new values

To address these challenges, I decided to adopt a more dynamic and scalable approach. Instead of hard-coding the names, I implemented an AI Strategy where the AI would introspect the code to obtain the values

Overall, transitioning from a hard-coded approach to an introspection system has greatly improved the efficiency, flexibility, and scalability of my content management process, allowing me to work on multiple codebases with multiple developers, with no changes required. This would only work if the AI could scan my directories and read files; Enter CLINE.

Enter Cline

https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev

What makes Cline special? It's an AI-powered command line tool that integrates directly with your IDE. Unlike traditional coding assistants, Cline leverages Anthropic's computer use capabilities, allowing it to interact directly with your codebase. While the name might be as quirky as "Edge Delivery Services," the capabilities are impressive.

Cost and Setup

The Magic of Proper Prompting

The secret sauce isn't just the tool - it's how you instruct it. I've refined my prompts through multiple iterations to create a system that:

  1. Introspects existing project structures
  2. Generates appropriate configurations
  3. Adapts to project conventions rather than enforcing pre-existing ones
  4. Understands AEM's component patterns

A Practical Example

During a recent demonstration, I created a simple "Hello World" component. The fascinating part wasn't just that it worked, but how it worked:

What's particularly impressive is that this happened with zero manual coding. When issues arose (as they always do in development), the system was capable of self-correction and provided clear explanations of what needed to be fixed.

Beyond Basic Components

The system isn't limited to simple components. I've developed prompts for:

Each prompt is engineered to understand and work within AEM's architectural patterns.

Prompt Engineering is Key

One crucial learning: prompt engineering is not simple. While you can get basic results with simple prompts, the real power comes from properly engineered prompts. I've spent significant time learning how to structure these prompts effectively. As I tell my colleagues, it's like the difference between instructing a junior developer with rigid steps versus giving them room to surprise you with their approach.

Looking Forward

The landscape of AI development tools is rapidly evolving. While Cline currently has an advantage due to its computer use capabilities, other tools like Cursor are catching up. Since they're both using Claude under the hood, the differentiator comes down to how they interact with your repository.

Want to Try It?

I'm currently sharing my prompts with other developers for testing and feedback. If you're interested in experimenting with this approach, I'd love to hear your results, especially with real-world implementations.

Final Thoughts

The most exciting part of this journey has been discovering how AI can complement our understanding of AEM rather than replace it. It's not about removing the developer from the equation - it's about amplifying what we can accomplish while maintaining control over the architecture and implementation.

Remember, the goal isn't to replace traditional development practices but to enhance them. Whether you're building simple components or complex workflows, the right combination of AI assistance and human oversight can significantly improve your development workflow.

My Prompt for “Create an AEM Component”

 # AEM Component Creator - AI Prompt

Version 3.4 - Project Introspection Based with Property Alignment and Model Registration, Tom Cranstoun, Nov 2024

## Overview

This prompt creates AEM components by introspecting the existing project structure and generating appropriate configurations and code. It adapts to the project's conventions and patterns rather than enforcing predefined ones, with special attention to property alignment across all component files and proper model registration.

## Project Structure Analysis

The component creator first analyzes:

1. Project namespace from `/apps` directory
2. Java package structure from `core/src/main/java`
3. Component patterns from existing components
4. Clientlib organization
5. Resource type conventions
6. Component Group conventions (Critical for sidebar visibility)
7. Property naming conventions and alignment
8. Model registration and package exports

## Configuration Generation

Instead of using static configuration, generates from project:

```javascript
{
    // Derived from project structure
    namespace: {
        apps: derived from /apps/{namespace},
        java: derived from core/src/main/java/com/{namespace},
        content: derived from /content/{namespace}
    },
    
    // Extracted from existing components
    patterns: {
        resourceTypes: analyzed from components,
        modelPackage: derived from Java structure,
        clientlibs: derived from clientlib structure,
        componentGroup: derived from container policies,
        propertyNames: derived from existing components,
        modelRegistration: derived from existing models 
    },
    
    // Discovered from project
    conventions: {
        naming: extracted from existing components,
        structure: based on project organization,
        clientlibs: from clientlib patterns,
        allowedComponentGroups: from container policies,
        propertyAlignment: from component analysis,
        packageExports: from bnd configuration 
    }
}
```

## Component Creation Process

1. **Project Analysis**
   - Scan project structure
   - Identify patterns and conventions
   - Extract configuration
   - Analyze container policies for allowed component groups
   - Analyze property naming and alignment patterns
   - Analyze model registration and package exports

2. **Component Generation**
   - Use discovered patterns
   - Follow project conventions
   - Maintain consistency
   - Ensure componentGroup matches policy-allowed groups
   - Ensure property names align across all files
   - Configure proper model registration

3. **Integration**
   - Align with existing components
   - Follow project structure
   - Use discovered naming patterns
   - Validate component group against policies
   - Validate property alignment
   - Verify model package exports

## On Completion of the code

Create {component-name}-README.md with narrative for Developer, Installer and Content-author
Create {component-name}-self-review.md with technical analysis of the code and learning points

## Model Registration

**Critical model registration requirements:**

```java
// Correct model registration
@Model(
    adaptables = SlingHttpServletRequest.class,
    defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL,
    resourceType = "namespace/components/componentname" // Must match component path exactly
)
public class ComponentModel {
    // Model implementation
}
```

## Package Export Configuration

**Required bnd configuration in core/pom.xml:

```xml
<configuration>
    <bnd><![CDATA[
Import-Package: javax.annotation;version=0.0.0,*
Export-Package: com.namespace.core.models
    ]]></bnd>
</configuration>
```

## Property Alignment

Critical property alignment between files:

```plaintext
Model (.java)              Dialog (.content.xml)         HTML template (.html)
@ValueMapValue            name="./propertyName"         ${model.propertyName}
private String property;  fieldLabel="Property"         
```

Example alignment:

```java
// HelloWorldModel.java
@ValueMapValue
private String message;  // Property name in model

public String getMessage() {
    return message;
}
```

```xml
<!-- _cq_dialog/.content.xml -->
<message
    jcr:primaryType="nt:unstructured"
    sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
    fieldLabel="Message"
    name="./message"/>  <!-- Same property name -->
```

```html
<!-- helloworld.html -->
<div class="cmp-helloworld">
    ${model.message}  <!-- Same property name -->
</div>
```

## File Structure

Generated based on project analysis:

```bash
{namespace}/components/{component-name}/
├── .content.xml                    # Component definition with correct group
├── {component-name}.html          # Template with aligned property references
├── _cq_dialog/                    # Dialog with aligned property names
│   └── .content.xml
└── clientlibs/                    # If project uses component-level clientlibs
    ├── css/
    │   └── {component-name}.css
    ├── js/
    │   └── {component-name}.js
    └── .content.xml
```

## Validation Checklist

1. Confirm component group matches policy-allowed groups
2. Verify component appears in correct sidebar group
3. Test component drag-and-drop functionality
4. Validate property name alignment across:
   - Model properties and getters
   - Dialog field names
   - HTML template references
5. **Verify model registration:**
   - Correct resourceType path
   - Package properly exported
   - Model class resolvable
6. Validate component rendering
7. Check policy inheritance and restrictions

## Common Issues and Solutions

1. **Model-Dialog Mismatch**
   - Model: `private String message`
   - Dialog: `name="./text"`
   - Solution: Align property names

2. **Dialog-Template Mismatch**
   - Dialog: `name="./message"`
   - Template: `${model.text}`
   - Solution: Use same property reference

3. **Model-Template Mismatch**
   - Model: `getMessage()`
   - Template: `${model.text}`
   - Solution: Match getter name

4. **Model Resolution Issues**
   - Symptom: "Model cannot be resolved"
   - Causes:
     - Missing package export
     - Incorrect resourceType path
     - Model class not in correct package
   - Solutions:
     - Add Export-Package in bnd config
     - Verify resourceType matches component path
     - Check package structure matches project convention

The implementation details are derived from project analysis rather than predefined templates, with special attention to property alignment and model registration to ensure proper functionality.

This is just the beginning of what's possible with AI-assisted AEM development. I'm excited to see how these tools evolve and how the community adapts them to solve real-world challenges.

/fragments/ddt/proposition

---
Related Articles

guide
guide
Back to Top