|
| 1 | +# ${appTitle} |
| 2 | +#if ( $aemVersion == "cloud") |
| 3 | + |
| 4 | +This is an AEM as a Cloud Service project using the Java stack. |
| 5 | + |
| 6 | +It is built locally using Maven#if ( $frontendModule != "decoupled" ) and can be tested against a local Quickstart#if ( $includeDispatcherConfig != "n" ), and the Dispatcher configuration is validated locally using the Dispatcher Tools#end#end. |
| 7 | + |
| 8 | +Production deployments are done through Adobe Cloud Manager using Full Stack Pipelines#if ( $frontendModule == "decoupled" ) and Frontend Pipelines for decoupled frontend code#end. |
| 9 | + |
| 10 | +The Java version used in Cloud Manager pipelines is defined in the `.cloudmanager/java-version` file. Assume the same is used for local builds. |
| 11 | + |
| 12 | +#else |
| 13 | + |
| 14 | +This is an AEM project targeting Adobe Managed Services or on-prem using the Java stack. |
| 15 | + |
| 16 | +It is built locally using Maven and can be tested against a local Quickstart. |
| 17 | + |
| 18 | +#end |
| 19 | +#if ( $includeCif == "y" || $includeForms == "y" || $includeFormsenrollment == "y" || $includeFormscommunications == "y" || $includeFormsheadless == "y" || $precompiledScripts == "y" ) |
| 20 | +${hash}${hash} Add-ons and extensions |
| 21 | + |
| 22 | +#if ( $includeCif == "y" ) |
| 23 | +- **Commerce Integration Framework (CIF)**: The commerce backend endpoint is configured in `ui.config` OSGi configurations. CIF Core Components are included for building commerce experiences (product pages, catalog, search, cart, checkout). See README-CIF.md for more details. |
| 24 | +#end |
| 25 | +#if ( $includeForms == "y" || $includeFormsenrollment == "y" || $includeFormscommunications == "y" ) |
| 26 | +#if ( $aemVersion == "cloud" ) |
| 27 | +- **AEM Forms**: Forms Core Components are provided OOTB in AEM as a Cloud Service. The project contains Adaptive Forms components, templates, themes, and configurations for building form experiences. |
| 28 | +#else |
| 29 | +- **AEM Forms**: The project contains Adaptive Forms components, templates, themes, and configurations for building form experiences. |
| 30 | +#end |
| 31 | +#end |
| 32 | +#if ( $includeFormsheadless == "y" ) |
| 33 | +- **Headless Adaptive Forms**: The `ui.frontend.react.forms.af` module provides a React-based rendering layer for forms consumed via the form model JSON. Forms can be rendered in external applications while leveraging AEM Forms capabilities for form logic and data handling. |
| 34 | +#end |
| 35 | +#if ( $precompiledScripts == "y" ) |
| 36 | +- **Precompiled Scripts**: HTL scripts from `ui.apps` are precompiled into a bundle during the build and attached as a secondary bundle artifact for improved performance. See README-precompiled-scripts.md for more details. |
| 37 | +#end |
| 38 | + |
| 39 | +#end |
| 40 | +${hash}${hash} Modules |
| 41 | + |
| 42 | +- `core`: OSGi bundle. Contains the Java code for backend services, models, and business logic#if ( $includeCif == "y" ), including commerce-specific models and servlets#end. Uses OSGi for dependency injection, Sling models for exposing content to Sling scripts and JUnit for unit testing. |
| 43 | +#if ( $includeDispatcherConfig != "n" ) |
| 44 | +#if ( $aemVersion == "cloud" ) |
| 45 | +- `dispatcher`: Contains the cloud-optimized Dispatcher configuration, including caching and security settings. Uses immutable files that are validated by the Dispatcher SDK. |
| 46 | +#else |
| 47 | +- `dispatcher`: Contains Dispatcher configuration suitable for Adobe Managed Services or on-prem deployments, including caching and security settings. |
| 48 | +#end |
| 49 | +#end |
| 50 | +- `ui.apps`: FileVault content package. Contains the application code, including components, templates, client libraries, and content structure. Uses HTL as the scripting engine. |
| 51 | +- `ui.apps.structure`: FileVault content package. Empty module that defines the structure of the repository content. |
| 52 | +- `ui.config`: FileVault content package. Contains OSGi configurations for the application. |
| 53 | +- `ui.content`: FileVault content package. Contains the mutable content for the application, such as the initial site structure, templates, sample assets. |
| 54 | +#if ( $frontendModule == "general" ) |
| 55 | +- `ui.frontend`: Frontend module built with Webpack. Compiles TypeScript/JavaScript and Sass/SCSS. During the build it's copied to the `ui.apps` module as client libraries. Uses Node.js, npm, and webpack. |
| 56 | +#end |
| 57 | +#if ( $frontendModule == "react" ) |
| 58 | +- `ui.frontend`: React-based SPA module built with Create React App. Uses `@adobe/aem-react-editable-components` for SPA Editor integration. During the build it's copied to the `ui.apps` module as client libraries. Run `npm start` to develop locally with a proxy to AEM (port 3000)#if ( $enableSSR == "y" ). Includes server-side rendering capabilities using Adobe I/O Runtime#end. Uses Node.js, npm, and webpack. |
| 59 | +#end |
| 60 | +#if ( $frontendModule == "angular" ) |
| 61 | +- `ui.frontend`: Angular-based SPA module built with Angular CLI. Uses `@adobe/aem-angular-editable-components` for SPA Editor integration. During the build it's copied to the `ui.apps` module as client libraries. Run `npm start` to develop locally with a proxy to AEM (port 4200)#if ( $enableSSR == "y" ). Includes server-side rendering capabilities using Adobe I/O Runtime#end. Uses Node.js, npm, and webpack. |
| 62 | +#end |
| 63 | +#if ( $frontendModule == "decoupled" ) |
| 64 | +#if ( $aemVersion == "cloud" ) |
| 65 | +- `ui.frontend`: Decoupled frontend module (headless). Consumes AEM content via JSON model APIs. Deployed via the AEM as a Cloud Service Frontend Pipeline separately from backend code. No client libraries are generated in `ui.apps`. |
| 66 | +#else |
| 67 | +- `ui.frontend`: Decoupled frontend module (headless). Consumes AEM content via JSON model APIs. No client libraries are generated in `ui.apps`. |
| 68 | +#end |
| 69 | +#end |
| 70 | +#if ( $includeFormsheadless == "y" ) |
| 71 | +- `ui.frontend.react.forms.af`: React-based headless Adaptive Forms rendering module. Consumes form models and renders forms in a headless manner. Uses Node.js, npm, and webpack. |
| 72 | +#end |
| 73 | +#if ( $aemVersion == "cloud" ) |
| 74 | +- `it.tests`: Integration tests module. Uses the AEM Testing clients to run tests against running AEM instances. Executed by Cloud Manager during the _Custom Functional Testing_ step of a full stack pipeline. |
| 75 | +- `ui.tests`: UI tests module. Uses Cypress to run end-to-end tests against running AEM instances. Executed by Cloud Manager during the _Custom UI Testing_ step of a full stack pipeline. |
| 76 | +#else |
| 77 | +- `it.tests`: Integration tests module. Uses the AEM Testing clients to run tests against running AEM instances. |
| 78 | +- `ui.tests`: UI tests module. Uses Cypress to run end-to-end tests against running AEM instances. |
| 79 | +#end |
| 80 | +- `all`: FileVault content package. Includes all other FileVault packages for easy deployment. |
| 81 | + |
| 82 | +${hash}${hash} Build |
| 83 | + |
| 84 | +The project uses Maven as the build tool. The following commands are commonly used: |
| 85 | + |
| 86 | +- full build: `mvn clean install` |
| 87 | +#if ( $aemVersion == "cloud" ) |
| 88 | +- build and deploy to local AEM SDK: `mvn clean install -PautoInstallSinglePackage` |
| 89 | +#else |
| 90 | +- build and deploy to a local Quickstart: `mvn clean install -PautoInstallSinglePackage` |
| 91 | +#end |
| 92 | +- build and deploy a single FileVault content package: `mvn clean install -pl <module> -PautoInstallPackage` |
| 93 | +- build and deploy a single OSGi bundle: `mvn clean install -pl <module> -PautoInstallBundle` |
| 94 | +#if ( $frontendModule == "react" || $frontendModule == "angular" || $frontendModule == "general" ) |
| 95 | +- build frontend only: `cd ui.frontend && npm run build` |
| 96 | +- develop frontend locally#if ( $frontendModule == "react" || $frontendModule == "angular" ) (requires AEM running)#end: `cd ui.frontend && npm start` |
| 97 | +#end |
| 98 | +#if ( $includeDispatcherConfig != "n" ) |
| 99 | +#if ( $aemVersion == "cloud" ) |
| 100 | +- validate Dispatcher configuration: `cd dispatcher && ./bin/validate.sh src` |
| 101 | +#end |
| 102 | +#end |
| 103 | + |
| 104 | +${hash}${hash} Important resources |
| 105 | + |
| 106 | +Note: there are significant architectural differences between AEM as a Cloud Service and Adobe Managed Services/on-prem deployments. The resources below have been curated to ensure they apply to this project. Use them in preference to generic AEM resources. |
| 107 | +## |
| 108 | +## Resource data: ["title", "cloud_url", "noncloud_url"] or ["title", "shared_url"] - empty string means no resource for that platform |
| 109 | +#set($resourceData = [ |
| 110 | + ["Core Concepts", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/overview/architecture", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/introduction/the-basics"], |
| 111 | + ["AEM Project Structure", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/aem-project-content-package-structure", ""], |
| 112 | + ["AEM Technical Foundations", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/aem-technologies", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/deploying/introduction/platform"], |
| 113 | + ["AEM Development Guidelines", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/development-guidelines", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/introduction/dev-guidelines-bestpractices"], |
| 114 | + ["Java API Best Practices", "https://experienceleague.adobe.com/en/docs/experience-manager-learn/foundation/development/understand-java-api-best-practices"], |
| 115 | + ["The AEM as a Cloud Service SDK", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/aem-as-a-cloud-service-sdk", ""], |
| 116 | + ["Sling Adapters", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/full-stack/sling-adapters", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/platform/sling-adapters"], |
| 117 | + ["Sling Resource Merger", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/full-stack/sling-resource-merger", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/platform/sling-resource-merger"], |
| 118 | + ["Getting Started with HTL", "https://experienceleague.adobe.com/en/docs/experience-manager-htl/content/getting-started"], |
| 119 | + ["Overlays", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/full-stack/overlays", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/platform/overlays"], |
| 120 | + ["Templates", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/full-stack/components-templates/templates", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/platform/templates/templates"], |
| 121 | + ["Core Components Introduction", "https://experienceleague.adobe.com/en/docs/experience-manager-core-components/using/introduction"], |
| 122 | + ["Components Reference Guide", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/full-stack/components-templates/reference", ""], |
| 123 | + ["Manage digital assets with the Adobe Experience Manager Assets HTTP API", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/assets/admin/mac-api-assets", ""], |
| 124 | + ["Deprecated and Removed Features and APIs", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/release-notes/deprecated-removed-features", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/release-notes/deprecated-removed-features"], |
| 125 | + ["Best Practices for Sling Service User Mapping and Service User Definition", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/security/best-practices-for-sling-service-user-mapping-and-service-user-definition", ""], |
| 126 | + ["Using Client-Side Libraries", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/full-stack/clientlibs", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/introduction/clientlibs"], |
| 127 | + ["Universal Editor in AEM", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/universal-editor/getting-started", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/headless/universal-editor/introduction"], |
| 128 | + ["Content Fragments", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/sites/administering/content-fragments/overview", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/assets/content-fragments/content-fragments"], |
| 129 | + ["Experience Fragments", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/sites/authoring/fragments/experience-fragments", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/sites/authoring/authoring/experience-fragments"], |
| 130 | + ["AEM APIs for Structured Content Delivery and Management", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/headless/apis-headless-and-content-fragments", ""], |
| 131 | + ["Developing and Extending Workflows", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/extending-aem/extending-workflows/workflows"], |
| 132 | + ["Replication", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/operations/replication", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/deploying/configuring/replication"], |
| 133 | + ["Content Search and Indexing", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/operations/indexing", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/deploying/deploying/queries-and-indexing"], |
| 134 | + ["CDN in AEM as a Cloud Service", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/content-delivery/cdn", ""], |
| 135 | + ["Deployment and Maintenance", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/deploying/overview", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/deploying/deploying/deploy"], |
| 136 | + ["API Reference Materials", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/reference-materials", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/introduction/reference-materials"], |
| 137 | + ["WCM.io AEM Mocks", "https://wcm.io/testing/aem-mock/"], |
| 138 | + ["Sling Mocks", "https://sling.apache.org/documentation/development/sling-mock.html"] |
| 139 | +])## |
| 140 | +## |
| 141 | +#if ( $includeDispatcherConfig != "n" )## |
| 142 | +#set($dummy = $resourceData.add(["Validating and Debugging using Dispatcher Tools", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/content-delivery/validation-debug", ""]))## |
| 143 | +#end## |
| 144 | +## |
| 145 | +#if ( $frontendModule == "react" || $frontendModule == "angular" || $frontendModule == "decoupled" )## |
| 146 | +#set($dummy = $resourceData.add(["SPA Editor Overview", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/hybrid/introduction", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/spas/spa-overview"]))## |
| 147 | +#set($dummy = $resourceData.add(["Developing SPAs for AEM", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/hybrid/developing", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/spas/spa-architecture"]))## |
| 148 | +#end## |
| 149 | +## |
| 150 | +#if ( $frontendModule == "react" )## |
| 151 | +#set($dummy = $resourceData.add(["AEM React Editable Components", "https://www.npmjs.com/package/@adobe/aem-react-editable-components"]))## |
| 152 | +#end## |
| 153 | +## |
| 154 | +#if ( $frontendModule == "angular" )## |
| 155 | +#set($dummy = $resourceData.add(["Create your first Angular SPA in AEM", "https://experienceleague.adobe.com/en/docs/experience-manager-learn/getting-started-with-aem-headless/spa-editor/angular/overview"]))## |
| 156 | +#set($dummy = $resourceData.add(["AEM Angular Editable Components", "https://www.npmjs.com/package/@adobe/aem-angular-editable-components"]))## |
| 157 | +#end## |
| 158 | +## |
| 159 | +#if ( $frontendModule == "decoupled" )## |
| 160 | +#set($dummy = $resourceData.add(["Enabling Front-End Pipeline", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/sites/administering/site-creation/enable-front-end-pipeline", ""]))## |
| 161 | +#end## |
| 162 | +## |
| 163 | +#if ( $includeCif == "y" )## |
| 164 | +#set($dummy = $resourceData.add(["Adobe Commerce Integration", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/content-and-commerce/storefront/getting-started", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/commerce/integrations/magento"]))## |
| 165 | +#set($dummy = $resourceData.add(["CIF Core Components", "https://github.com/adobe/aem-core-cif-components"]))## |
| 166 | +#end## |
| 167 | +## |
| 168 | +#if ( $includeForms == "y" || $includeFormsenrollment == "y" || $includeFormscommunications == "y" || $includeFormsheadless == "y" )## |
| 169 | +#set($dummy = $resourceData.add(["AEM Forms Overview", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/forms/forms-overview/home", "https://experienceleague.adobe.com/en/docs/experience-manager-65/content/commerce/integrations/magento"]))## |
| 170 | +#set($dummy = $resourceData.add(["Forms Core Components", "https://github.com/adobe/aem-core-forms-components"]))## |
| 171 | +#set($dummy = $resourceData.add(["Form builder: Create forms with core components", "https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/forms/adaptive-forms-authoring/authoring-adaptive-forms-core-components/create-an-adaptive-form-on-forms-cs/creating-adaptive-form-core-components", ""]))## |
| 172 | +#end## |
| 173 | +## |
| 174 | +#if ( $includeFormsheadless == "y" )## |
| 175 | +#set($dummy = $resourceData.add(["Headless Adaptive Forms", "https://experienceleague.adobe.com/en/docs/experience-manager-headless-adaptive-forms/using/overview", ""]))## |
| 176 | +#end## |
| 177 | +## |
| 178 | +#if ( $precompiledScripts == "y" )## |
| 179 | +#set($dummy = $resourceData.add(["Precompiled Bundled Scripts", "https://experienceleague.adobe.com/en/docs/experience-manager-core-components/using/developing/archetype/precompiled-bundled-scripts", ""]))## |
| 180 | +#end## |
| 181 | +## |
| 182 | +#foreach($item in $resourceData)## |
| 183 | +#if($item.size() == 2)## |
| 184 | +#set($url = $item.get(1))## |
| 185 | +#elseif(${aemVersion} == "cloud")## |
| 186 | +#set($url = $item.get(1))## |
| 187 | +#else## |
| 188 | +#set($url = $item.get(2))## |
| 189 | +#end## |
| 190 | +#if($url && $url != "")## |
| 191 | +- [$item.get(0)]($url) |
| 192 | +#end## |
| 193 | +#end |
| 194 | + |
0 commit comments