Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SITES-7941: add a decoupled frontend project #1002

Merged
merged 9 commits into from
Nov 21, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ Name | Default | Description
`aemVersion` | `cloud` | Target AEM version (can be `cloud` for [AEM as a Cloud Service](https://docs.adobe.com/content/help/en/experience-manager-cloud-service/landing/home.html); or `6.5.5` for [Adobe Managed Services](https://github.com/adobe/aem-project-archetype/tree/master/src/main/archetype/dispatcher.ams) or on-premise).
`sdkVersion` | `latest` | When `aemVersion=cloud` an [SDK](https://docs.adobe.com/content/help/en/experience-manager-cloud-service/implementing/developing/aem-as-a-cloud-service-sdk.html) version can be specified (e.g. `2020.02.2265.20200217T222518Z-200130`).
`includeDispatcherConfig` | `y` | Includes a dispatcher configuration either for cloud or for AMS/on-premise, depending of the value of `aemVersion` (can be `y` or `n`).
`frontendModule` | `general` | Includes a Webpack frontend build module that generates the client libraries (can be `general` or `none` for regular sites; can be `angular` or `react` for a Single Page App that implements the [SPA Editor](https://docs.adobe.com/content/help/en/experience-manager-65/developing/headless/spas/spa-overview.html)).
`frontendModule` | `general` | Includes a Webpack frontend build module that generates the client libraries (can be `general` or `none` for regular sites; can be `angular`, `react` or `decoupled` for a Single Page App that implements the [SPA Editor](https://docs.adobe.com/content/help/en/experience-manager-65/developing/headless/spas/spa-overview.html). In the later case the project will be preconfigured to use the [AEM as a Cloud Service Frontend Pipeline](https://experienceleague.adobe.com/docs/experience-manager-cloud-service/content/sites/administering/site-creation/enable-front-end-pipeline.html)).
`language` | `en` | Language code (ISO 639-1) to create the content structure from (e.g. `en`, `deu`).
`country` | `us` | Country code (ISO 3166-1) to create the content structure from (e.g. `US`).
`singleCountry` | `y` | Includes a language-master content structure (can be `y`, or `n`).
Expand Down
6 changes: 3 additions & 3 deletions src/main/archetype/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#set( $symbol_escape = '\' )
#set( $startbrace = "{" )
#set( $endbrace = "}" )
#set( $isSpaProject = $frontendModule == "angular" || $frontendModule == "react" )
#set( $isSpaProject = $frontendModule == "angular" || $frontendModule == "react" || $frontendModule == "decoupled" )
#set( $includeClassifierOnUberJar = $aemVersion.matches("6\.5\.[0-5]") )

<modelVersion>4.0.0</modelVersion>
Expand All @@ -38,7 +38,7 @@
<modules>
<module>all</module>
<module>core</module>
#if ( $frontendModule != "none" )
#if ( $frontendModule != "none" && $frontendModule != "decoupled" )
<module>ui.frontend</module>
#end
#if ( $includeFormsheadless == "y" )
Expand Down Expand Up @@ -89,7 +89,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
#if ( $isSpaProject )
<spa.project.core.version>1.3.12</spa.project.core.version>
<spa.project.core.version>1.3.16</spa.project.core.version>
#end
#if ( $frontendModule == "angular" )
<!--
Expand Down
2 changes: 1 addition & 1 deletion src/main/archetype/ui.apps/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ Require-Capability: osgi.extender;filter:="(&(osgi.extender=sling.scripting)(ver
<version>${project.version}</version>
</dependency>

#if ( $frontendModule != "none" )
#if ( $frontendModule != "none" && $frontendModule != "decoupled" )
<dependency>
<groupId>${groupId}</groupId>
<artifactId>${rootArtifactId}.ui.frontend</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@
SPA-specific meta tags
*/-->
<meta name="theme-color" content="#000000" />
#if ( $frontendModule != "decoupled" )
<link rel="icon" href="/etc.clientlibs/${appId}/clientlibs/clientlib-${frontendModule}/resources/favicon.ico" />
<link rel="apple-touch-icon" href="/etc.clientlibs/${appId}/clientlibs/clientlib-${frontendModule}/resources/logo192.png" />
<link rel="manifest" href="/etc.clientlibs/${appId}/clientlibs/clientlib-${frontendModule}/resources/manifest.json" />

#end
<!-- AEM page model -->
<meta
property="cq:pagemodel_root_url"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,16 @@

<sly data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html"/>

#if ( $frontentModule != "decoupled" )
<sly data-sly-call="${symbol_dollar}{clientlib.all @ categories=['coralui3']}"/>
<sly data-sly-call="${symbol_dollar}{clientlib.css @ categories=['${appId}.base']}"/>
#end

<sly data-sly-list="${page.htmlPageItems}">
buuhuu marked this conversation as resolved.
Show resolved Hide resolved
<script data-sly-test="${symbol_dollar}{item.location.name == 'header'}"
data-sly-element="${symbol_dollar}{item.element.name @ context='unsafe'}"
data-sly-attribute="${symbol_dollar}{item.attributes}"></script>
</sly>

#else

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured">
<com.adobe.cq.wcm.core.components.internal.DataLayerConfig
jcr:primaryType="nt:unstructured"
Expand All @@ -13,4 +13,106 @@
jcr:primaryType="nt:unstructured"
clientId="28b07c6be4d544f188dc2f36e33b196b"
reportSuiteId=""/>
#if ( $frontendModule == 'decoupled')
<com.adobe.aem.wcm.site.manager.config.SiteConfig
jcr:primaryType="nt:unstructured"
siteTemplatePath="/libs/wcm/core/site-templates/aem-site-template-stub-2.0.0"
themePackageName="${appId}"/>
<com.adobe.cq.wcm.core.components.config.HtmlPageItemsConfig
jcr:primaryType="cq:Page">
<jcr:content
jcr:primaryType="cq:PageContent"
prefixPath="http://localhost:3000">
<items jcr:primaryType="nt:unstructured">
<css
jcr:primaryType="nt:unstructured"
element="link"
location="header">
<attributes jcr:primaryType="nt:unstructured">
<as
jcr:primaryType="nt:unstructured"
name="as"
value="style"/>
<href
jcr:primaryType="nt:unstructured"
name="href"
value="/static/css/main.css"/>
<rel
jcr:primaryType="nt:unstructured"
name="rel"
value="preload stylesheet"/>
<type
jcr:primaryType="nt:unstructured"
name="type"
value="text/css"/>
</attributes>
</css>
<main
jcr:primaryType="nt:unstructured"
element="script"
location="header">
<attributes jcr:primaryType="nt:unstructured">
<src
jcr:primaryType="nt:unstructured"
name="src"
value="/static/js/main.js"/>
<defer
jcr:primaryType="nt:unstructured"
name="defer"
value="true"/>
<type
jcr:primaryType="nt:unstructured"
name="type"
value="text/javascript"/>
</attributes>
</main>
<favicon
jcr:primaryType="nt:unstructured"
element="link"
location="header">
<attributes jcr:primaryType="nt:unstructured">
<href
jcr:primaryType="nt:unstructured"
name="href"
value="/favicon.ico"/>
<rel
jcr:primaryType="nt:unstructured"
name="rel"
value="icon"/>
</attributes>
</favicon>
<appleTouchIcon
jcr:primaryType="nt:unstructured"
element="link"
location="header">
<attributes jcr:primaryType="nt:unstructured">
<href
jcr:primaryType="nt:unstructured"
name="href"
value="/logo192.png"/>
<rel
jcr:primaryType="nt:unstructured"
name="rel"
value="apple-touch-icon"/>
</attributes>
</appleTouchIcon>
<manifest
jcr:primaryType="nt:unstructured"
element="link"
location="header">
<attributes jcr:primaryType="nt:unstructured">
<href
jcr:primaryType="nt:unstructured"
name="href"
value="/manifest.json"/>
<rel
jcr:primaryType="nt:unstructured"
name="rel"
value="manifest"/>
</attributes>
</manifest>
</items>
</jcr:content>
</com.adobe.cq.wcm.core.components.config.HtmlPageItemsConfig>
#end
</jcr:root>
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,10 @@
<policy_spa
jcr:primaryType="nt:unstructured"
jcr:title="${appTitle} SPA Page Policy"
sling:resourceType="wcm/core/components/policy/policy"
clientlibs="[${appId}.${frontendModule}]">
#if ( $frontendModule != "decoupled" )
clientlibs="[${appId}.${frontendModule}]"
#end
sling:resourceType="wcm/core/components/policy/policy">
<jcr:content jcr:primaryType="nt:unstructured"/>
</policy_spa>
#end
Expand All @@ -435,7 +437,9 @@
jcr:primaryType="nt:unstructured"
jcr:title="${appTitle} App Policy"
sling:resourceType="wcm/core/components/policy/policy"
#if ( $frontendModule != "decoupled" )
clientlibs="[${appId}.${frontendModule}]"
#end
isRoot="{Boolean}true"
structureDepth="3"
/>
Expand Down Expand Up @@ -611,7 +615,7 @@
jcr:primaryType="nt:unstructured"
jcr:title="SPA Content"
sling:resourceType="wcm/core/components/policy/policy"
components="[/libs/wcm/foundation/components/responsivegrid,/apps/${appId}/components/text]">
components="[group:${appTitle} - Content]">
<jcr:content jcr:primaryType="nt:unstructured"/>
</spa-default>
#if ( ($includeForms == "y" or $includeFormsenrollment == "y" or $includeFormscommunications == "y") and $aemVersion == "cloud")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
<jcr:content
cq:allowedTemplates="[/conf/${appId}/settings/wcm/templates/(?!xf-).*]"
cq:conf="/conf/${appId}"
cq:redirectTarget="/content/${appId}/${country}/${language}"
#if ( $isSpaProject )
cq:redirectTarget="/content/${appId}/${country}/${language}/home"
cq:template="/conf/${appId}/settings/wcm/templates/spa-app-template"
#else
cq:redirectTarget="/content/${appId}/${country}/${language}"
cq:template="/conf/${appId}/settings/wcm/templates/page-content"
#end
jcr:primaryType="cq:PageContent"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="cq:Page">
<jcr:content
cq:lastModified="{Date}2018-10-04T09:50:29.650+02:00"
cq:lastModifiedBy="admin"
cq:template="/conf/${appId}/settings/wcm/templates/spa-page-template"
jcr:primaryType="cq:PageContent"
jcr:title="${appTitle} Home Page"
sling:resourceType="${appId}/components/page">
<root
jcr:primaryType="nt:unstructured"
sling:resourceType="wcm/foundation/components/responsivegrid">
<responsivegrid
jcr:primaryType="nt:unstructured"
sling:resourceType="wcm/foundation/components/responsivegrid">
<text
jcr:primaryType="nt:unstructured"
sling:resourceType="${appId}/components/text"
text="&lt;p>Hello World!&lt;/p>"
textIsRich="true">
<cq:responsive jcr:primaryType="nt:unstructured"/>
</text>
</responsivegrid>
</root>
</jcr:content>
</jcr:root>
34 changes: 25 additions & 9 deletions src/main/resources/META-INF/archetype-post-generate.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,15 @@ if (aemVersion == "cloud") {
buildContentSkeleton(uiContentPackage, uiAppsPackage, singleCountry, appId, language, country)
cleanUpFrontendModule(frontendModules, frontendModule, rootPom, rootDir, appsFolder, confFolder, configFolder, contentFolder,enableSSR, includeCommerce)

if ( includeDispatcherConfig == "n"){
if (includeDispatcherConfig == "n") {
// remove the unneeded config file
def rrfConfig;
if (aemVersion.startsWith("6.4")) {
assert new File("$configFolder/config.publish/org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl.config").delete()
rrfConfig = new File("$configFolder/config.publish/org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl.config")
} else {
assert new File("$configFolder/config.publish/org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl.cfg.json").delete()
rrfConfig = new File("$configFolder/config.publish/org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl.cfg.json")
}
assert !rrfConfig.exists() || rrfConfig.delete();
} else {
def source;
if (aemVersion == 'cloud') {
Expand Down Expand Up @@ -275,12 +277,12 @@ def cleanUpFrontendModule(frontendModules, optionFrontendModule, rootPom, rootDi
}

// Rename selected frontend module (e.g. "ui.frontend.angular" -> "ui.frontend")
if (optionFrontendModule != "none") {
if (optionFrontendModule != "none" && optionFrontendModule != "decoupled") {
assert new File(rootDir, "ui.frontend.$optionFrontendModule").renameTo(new File(rootDir, "ui.frontend"))
}

// Not generating SPA: Delete SPA-specific files
if (optionFrontendModule != "angular" && optionFrontendModule != "react") {
if (optionFrontendModule != "angular" && optionFrontendModule != "react" && optionFrontendModule != "decoupled") {
// Delete app component
assert new File("$appsFolder/components/structure/spa").deleteDir()
assert new File("$appsFolder/components/xfpage/body.html").delete()
Expand All @@ -298,6 +300,7 @@ def cleanUpFrontendModule(frontendModules, optionFrontendModule, rootPom, rootDi
assert new File("$confFolder/settings/wcm/template-types/remote-page").deleteDir()

// Delete SPA content
assert new File("$contentFolder/language-masters/en/home").deleteDir()
assert new File("$contentFolder/us/en/home").deleteDir()

}else{
Expand All @@ -312,21 +315,29 @@ def cleanUpFrontendModule(frontendModules, optionFrontendModule, rootPom, rootDi
}

// Generating SPA: Delete non-SPA specific files
if (optionFrontendModule == "angular" || optionFrontendModule == "react") {
if (optionFrontendModule == "angular" || optionFrontendModule == "react" || optionFrontendModule == "decoupled") {
assert new File("$confFolder/settings/wcm/templates/page-content").deleteDir()
assert new File("$confFolder/settings/wcm/template-types/page").deleteDir()

if(enableSSR == "n"){
// remove JcrResourceResolverFactoryImpl configuration as Sling Mappings do not work with SPA yet
for (def rrfConfig in [
new File("$configFolder/config.publish/org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl.cfg.json"),
new File("$configFolder/config.publish/org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl.config")
]) {
assert !rrfConfig.exists() || rrfConfig.delete()
}

if (enableSSR == "n") {

if(optionFrontendModule == "react"){
if (optionFrontendModule == "react") {
//cleanup IO runtime related files from react module
assert new File(rootDir, "ui.frontend/webpack.config.express.js").delete();
assert new File(rootDir, "ui.frontend/webpack.config.adobeio.js").delete();
assert new File(rootDir, "ui.frontend/manifest.yml").delete();
assert new File(rootDir, "ui.frontend/src/server").deleteDir();
assert new File(rootDir, "ui.frontend/actions").deleteDir();
assert new File(rootDir, "ui.frontend/scripts").deleteDir();
}else if(optionFrontendModule == "angular"){
} else if (optionFrontendModule == "angular") {
assert new File(rootDir, "ui.frontend/server.ts").delete();
assert new File(rootDir, "ui.frontend/serverless.ts").delete();
assert new File(rootDir, "ui.frontend/manifest.yml").delete();
Expand All @@ -337,6 +348,11 @@ def cleanUpFrontendModule(frontendModules, optionFrontendModule, rootPom, rootDi
}

}

if (optionFrontendModule == "decoupled") {
// remove clientlibs for decoupled frontend
assert new File("$appsFolder/clientlibs").deleteDir();
}
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
groupId=archetype.it
artifactId=testing-frontend-decoupled
appId=testing-frontend-decoupled
package=it.pkg
version=0.1-SNAPSHOT
appTitle=Test General Decoupled Project
aemVersion=cloud
sdkVersion=latest
language=en
country=us
singleCountry=n
frontendModule=decoupled
includeExamples=n
includeErrorHandler=n
includeDispatcherConfig=n
includeCommerce=n
commerceEndpoint=https://hostname.com/grapql
includeForms=n
includeFormsenrollment=n
includeFormscommunications=n
sdkFormsVersion=latest
datalayer=${datalayer}
amp=${amp}
enableDynamicMedia=y
enableSSR=n
precompiledScripts=n
includeFormsheadless=n
1 change: 1 addition & 0 deletions src/test/resources/projects/frontend-decoupled/goal.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
install