Hello, I have a server side handlebars helper that I'm trying to use inside of SCF components (Post, Topic, List-Item). It is working fine, but after the information shows up on the page, it disappears after a second.
Because our user profile nodes contain sensitive information in the properties, I cannot make them public as has been done for the geometrixx profiles. This is why I need to use a helper to get the username instead of using the oob {{author.name}}.
Here is the helper:
@Service @Component public class Username implements TemplateHelper<String>{ private final Logger LOGGER = LoggerFactory.getLogger(Username.class); @Reference private ResourceResolverFactory resourceResolverFactory; private static ResourceResolver resourceResolver; @Override public CharSequence apply(String context, Options options) throws IOException { try { if(resourceResolver == null) { resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null); } Resource resource = resourceResolver.getResource(context); ValueMap vals = resource.getValueMap(); String userId = vals.get("userIdentifier").toString(); return userId; } catch (Exception e) { LOGGER.error("Error getting id from context - " + e); return "Default User"; } } @Override public String getHelperName() { return "username"; } @Override public Class<String> getContextType() { return String.class; } }
And then I use it like this in the components:
<p class="component-answerthread__profile-user">{{username this.id}}</p>
(This is done inside of the component's tag where data-component-id="{{id}}" is declared just to be clear.)
Like I said, this is working. It shows up for a second and then disappears. Oddly, it works flawlessly when the user is not logged in (it doesn't disappear).
Solved! Go to Solution.
Views
Replies
Total Likes
The documentation had the recommendation one-sided - if you create a client-side helper, you don't have to have a server-side helper. Now it has a note that if you create a server-side helper you must have a client-side helper.
The client-side helper must have the same effect as the server-side, which would be difficult to accomplish for your task.
That is why you should really extend the AbstractUser class. I was interacting with the team and they changed it from 'could' to 'should'. ;-)
The AbstractUser class essentially implements SocialComponent interface (Javadoc) :
"SocialComponents are POJOs that represent a resource for an AEM Communities feature. Ideally, each SocialComponent represents a specific resourceType with exposed GETters that provide data to the client so the resource is accurately represented. All business logic and view logic are encapsulated in the SocialComponent, including the site visitor's session information, if necessary.
The interface defines a basic set of GETters that are necessary to represent a resource. Importantly, the interface stipulates Map<String, Object> getAsMap() and String toJSONString() methods that are necessary in order to render Handlebars templates and expose GET JSON endpoints for resources."
Hope this helps.
- JK
Views
Replies
Total Likes
Hi,
The component's tag with attribute data-component-id (value is instance of component on page) also needs attribute data-scf-component (value is the resourceType). All scf component templates must have all its markup inside the <div data-scf-component> tag.
Are you using either AEM 6.2 Communities FP1 or AEM 6.1 Communities FP5 ?
Are you able to provide more context for the client side code?
Are there any errors reported?
- JK
Views
Replies
Total Likes
Hi Dallas,
Two things :
1) a server side helper also has to be implemented on the client side (needs clarification in the documentation).
The component gets re-rendered on the clientside for logged in user, at this time, the client side helper is looked up, if not found, things disappear.
2) a better way is to subclass (extend) https://docs.adobe.com/docs/en/aem/6-2/develop/ref/javadoc/com/adobe/cq/social/scf/core/AbstractUser...
- JK
Views
Replies
Total Likes
Hi JK, thanks for your time on this.
Yes, the documentation is a little misleading where it states it's not technically required (only recommended) to implement them both client and server side.
That being said, I did implement it on the client side the same way other server side helpers are defined such as 'includeClientLib' and 'if-wcm-mode' (otherwise it throws a js error 'Helper not found'). For testing purposes I just pasted my code into /etc/clientlibs/social/commons/scf/helpers.js to make sure it was being included correctly.
Here's how I implemented it client side:
Handlebars.registerHelper("username", function(context, options) { // This helper only works on the server side. return ""; });
As for using the AbstractUser interface, wouldn't that still require making the profile node public? I think we'll just bite the bullet and move all the sensitive data out of the profile node and make the node public.
Also sorry for deleting my other post. It was showing up twice so I hit delete on one of them and both were removed. Here's the code in case it is needed
<div class="component-answerthread__answer" class="scf scf-post {{#if _isNew}}scf-is-new{{/if}}" data-component-id="{{id}}" data-scf-component="social/qna/components/hbs/post"> <aside class=""> <a href="https://forums.adobe.com/content/sitename/profile.html/{{username this.id}}"> <img class="component-answerthread__profile-pic" src="{{author.largeAvatarURL}}"/> </a> <div class="component-answerthread__user-date-box"> <a href="https://forums.adobe.com/content/sitename/profile.html/{{username this.id}}"> <p class="component-answerthread__profile-user">{{username this.id}}</p> </a> <p class="component-answerthread__profile-time-stamp">{{pretty-time created}}</p> </div> </aside> <div class="component-answerthread__a-text"> {{{message}}} </div> <div class="{{#if topLevel}}withTopLevel{{/if}}"> {{#if configuration.isVotingAllowed}} {{include this.votes resourceType='social/tally/components/hbs/voting'}} {{/if}} {{include this template="toolbar"}} </div> </div>
Views
Replies
Total Likes
The documentation had the recommendation one-sided - if you create a client-side helper, you don't have to have a server-side helper. Now it has a note that if you create a server-side helper you must have a client-side helper.
The client-side helper must have the same effect as the server-side, which would be difficult to accomplish for your task.
That is why you should really extend the AbstractUser class. I was interacting with the team and they changed it from 'could' to 'should'. ;-)
The AbstractUser class essentially implements SocialComponent interface (Javadoc) :
"SocialComponents are POJOs that represent a resource for an AEM Communities feature. Ideally, each SocialComponent represents a specific resourceType with exposed GETters that provide data to the client so the resource is accurately represented. All business logic and view logic are encapsulated in the SocialComponent, including the site visitor's session information, if necessary.
The interface defines a basic set of GETters that are necessary to represent a resource. Importantly, the interface stipulates Map<String, Object> getAsMap() and String toJSONString() methods that are necessary in order to render Handlebars templates and expose GET JSON endpoints for resources."
Hope this helps.
- JK
Views
Replies
Total Likes