Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

Editing components in partials in Angular single-page application

Avatar

Level 3

Hi everyone,

I am in a dilemma with my Angular single-page application in AEM 6.0(base version, no updates). I cannot properly edit my components in Classical UI(touch-based UI is not enabled) for the partial pages in my website. I can see the components I've included in the partial page, but they are incorrectly placed. The sidekick and editing properties are set for the "master" page so I imagine that has something to do with resolving the issue.

Here is the code for my "master" page:
 

<%@include file="/libs/foundation/global.jsp" %> <cq:include script="/libs/wcm/core/components/init/init.jsp"/> <!DOCTYPE html> <html ng-app="app"> <head> <cq:includeClientLib categories="coredashboard"/> <style> /* This helps the ng-show/ng-hide animations start at the right place. */ /* Since Angular has this but needs to load, this gives us the class early. */ .ng-hide { display: none!important; } </style> <title ng-bind="title">aos-dashboard</title> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" /> <link rel="icon" type="image/png" href="<%=currentDesign.getPath()%>/dashboard/img/favicon/hotwater.ico"> <base href="https://forums.adobe.com/"> </head> <body> <div ng-include="'app/layout/shell.html'"></div> </body> </html>

Here is the code for the partial page loaded in the "app/layout/shell.html":
 

<%@include file="/libs/foundation/global.jsp" %> <% String indexDesignPath = designer.getDesignPath(currentPage.getAbsoluteParent(2)); %> <section id="home-view" > <div class="hero"> <div class="container-fluid"> <div ui-view> <div class="container landing-overview-content"> <h1>Professional Contractor Resources &amp; Tool</h1> <cq:include path="paragraph1" resourceType="foundation/components/parsys"/> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed quam sem, blandit sed metus sed, vehicula tincidunt velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec vel mi non sapien lacinia imperdiet. Morbi fringilla vestibulum eros ut tempus.</p> <div class="btn-block"> <a ui-sref="home.register" class="register btn">Get Started</a> <a ui-sref="home.login" class="login btn btn--secondary-ghost">Log In</a> </div> </div> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-md-6 col-sm-6 col-xs-12 card card__center"> <span class="icon-contractor-locator"></span> <h3>Contractor Locator</h3> <p>Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Cras Contractor Rewards justo odio, dapibus ac facilisis in, posuere consectetur egestas eget quam.</p> <a href="#" class="btn btn--primary-ghost">Learn More</a> </div> <div class="col-md-6 col-sm-6 col-xs-12 card card__center line__left"> <span class="icon-product-selector-hotwater"></span> <h3>Product Selector</h3> <p>Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Sed posuere consectetur est at lobortis. Donec id elit non mi porta gravida at eget metus.</p> <a href="#" class="btn btn--primary-ghost">Learn More</a> <img src="<%=indexDesignPath%>/dashboard/img/xpert-logo.png"/> </div> </div> </div> </section>

An image of the master page in classical UI is attached, showing the misplacement (the parsys should be under the "Professional Contractors header"). 

Everything is fine when I access the parital page directly with Classical UI. An image of this is also attached, but obviously no styling is available since its loaded in the "master page" and it would be a huge inconvenience for my authors.

Here is a rundown of what I have checked/tried in debugging:

  • Installed a fresh instance of AEM
  • Included "<cq:include script="/libs/wcm/core/components/init/init.jsp"/>" only in the partial page. This made the page turn completely white with no sidekick or anything present. No errors were reported in the Google Chrome "Inspect" debugging dialog.
  • Included "<cq:include script="/libs/wcm/core/components/init/init.jsp"/>" in both the master and partial page. The page loaded with the partial page under the "page properties", but I again still had the same placement problems and I could not edit any component beyond parsys(which I have to double-click to drag and drop components).
  • Both the partial and master page components have a sling:resourceSuperType of "foundation/components/page". 


Thanks!

Ali


 

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

Well you can easily solve this problem by creating multiple views for your partial pages. By multiple views I mean you can use the concept of sling selectors and create 2 JSPs of your partial page component. Out of the 2 JSPs one should have the partial markup and it can be called as "partial.template.jsp" and another JSP called as partial.jsp will include header/footer with the CSS/JS and in the body it will just do a standard cq:include of partial.template.jsp. 

Also, you will have to make a slight change in the routing URLs of partials in your Angular JS application so that it refers to partial URLs as partial.template.html and not partial.html. And when author open pages for editing they will see partial.html with complete header/footer and when they access it through master then they will only see the partial markup (as Angular will pull partial.template.html). 

View solution in original post

10 Replies

Avatar

Level 3

Attachment did not work in the post. Here is the master page showing the displacement

Avatar

Level 10

When you open the page - can you drop other AEM Components onto the page?

Avatar

Level 10

One of your css is conflicting with the CQ clientlibs. Just do the browser debug and you should be able to find the culprit !

Avatar

Correct answer by
Employee Advisor

Well you can easily solve this problem by creating multiple views for your partial pages. By multiple views I mean you can use the concept of sling selectors and create 2 JSPs of your partial page component. Out of the 2 JSPs one should have the partial markup and it can be called as "partial.template.jsp" and another JSP called as partial.jsp will include header/footer with the CSS/JS and in the body it will just do a standard cq:include of partial.template.jsp. 

Also, you will have to make a slight change in the routing URLs of partials in your Angular JS application so that it refers to partial URLs as partial.template.html and not partial.html. And when author open pages for editing they will see partial.html with complete header/footer and when they access it through master then they will only see the partial markup (as Angular will pull partial.template.html). 

Avatar

Level 3

Scott,

I cannot drag and drop components, the only I added it in was by double-clicking the parsys. That is the only component that responded to a click/double-click.  The sidekick list of components is empty.

bsolki,

My css is not the issue since the styling and functionality of sidekick works perfectly when viewing the pages individually. 

kunal23,

That would be a work-around, but again I do not want my authors to view each partial individually to edit. I want them to be able to edit when taking account the full page. It does set me on a different path of thinking though.

Thanks again to everyone for the responses, I will try a few different things and will report back.

Ali

Avatar

Level 10

If CSS isnt a case, then I would agree with @kunal123.

with SPA, though the pages are included as partials, each partials are a different page w.r.t AEM and Authors have to change author the content at the partial level while then can preview as SPA once done. 

Avatar

Level 3

bsloki wrote...

If CSS isnt a case, then I would agree with @kunal123.

with SPA, though the pages are included as partials, each partials are a different page w.r.t AEM and Authors have to change author the content at the partial level while then can preview as SPA once done. 

 

Yeah, I have tried to think of some 'tricky' ways to make it work but yeah can't escape the fact that you pointed out. Going to have to go the route of kunal123

Avatar

Level 3

blkhatpersian wrote...

bsloki wrote...

If CSS isnt a case, then I would agree with @kunal123.

with SPA, though the pages are included as partials, each partials are a different page w.r.t AEM and Authors have to change author the content at the partial level while then can preview as SPA once done. 

 

Yeah, I have tried to think of some 'tricky' ways to make it work but yeah can't escape the fact that you pointed out. Going to have to go the route of kunal123

 

Hi @blkhatpersian

I am facing exactly the same issue as yours. Have you resolved it or editing the partial page only?

Waiting for the response eagerly :)

Thanks!

Akshita

Avatar

Level 3

akshitaa82720401 wrote...

blkhatpersian wrote...

bsloki wrote...

If CSS isnt a case, then I would agree with @kunal123.

with SPA, though the pages are included as partials, each partials are a different page w.r.t AEM and Authors have to change author the content at the partial level while then can preview as SPA once done. 

 

Yeah, I have tried to think of some 'tricky' ways to make it work but yeah can't escape the fact that you pointed out. Going to have to go the route of kunal123

 

Hi @blkhatpersian

I am facing exactly the same issue as yours. Have you resolved it or editing the partial page only?

Waiting for the response eagerly :)

Thanks!

Akshita

 

Hi Akshita!

I did go the route of editing it on partial pages, essentially using the path of the request to determine whether I need to load certain files. I also check if the run mode is "author" or "publish" as well.

Here is the Java class I created:

import java.util.ArrayList; import java.util.Set; import javax.servlet.http.HttpServletRequest; public class DashboardUtility { private static ArrayList<String> acceptedReferrers; private DashboardUtility(){} static{ acceptedReferrers = new ArrayList<String>(); acceptedReferrers.add("/content/dashboardangular/"); } public static boolean isPagePartialOnly(HttpServletRequest request, String pagePath){ if(request.getPathInfo().contains(pagePath)) { return true; } return false; } public static boolean isServerAuthor(Set<String> slingRunModes) { if (slingRunModes.contains("author")){ return true; } return false; } }

Then in my partial pages I perform the following checks at the beginning of the JSP file using that class above. I use the SlingRequest for the request path. If it matches the criteria, I load my clientlibrary and the AEM "init.jsp" file that will show the components.
 

<%if(DashboardUtility.isServerAuthor(sling.getService(SlingSettingsService.class).getRunModes())){ if(DashboardUtility.isPagePartialOnly(slingRequest, currentPage.getPath())){  %> <cq:include script="/libs/wcm/core/components/init/init.jsp"/> <cq:includeClientLib categories="coredashboard"/> <% } else { WCMMode.DISABLED.toRequest(slingRequest); } } %>  

 

I wish I didn't have to do that check everytime I load a page, but for now this is the solution I came up with. Thanks!