Sightly and cq:dropTargets - aem

I'm developing a new site using the latest AEM6 (formerly CQ). Originally you were able to drag images/videos into the components drop zone which was setup in the components dropTarget using JSP's.
But since Sightly templating is now the preferred way of building components rather than JSP's is it still possible to have dropTarget in Sighlty templates?

Drop target is configured using node cq:dropTargets node under the cq:editConfig and it doesn't depend on the used markup language.
The only thing that markup has to produce is a <div> tag with class cq-dd-CONFIGNAME which will be used as a drop zone. Sightly can easily generate such markup (below example will show it only in the edit mode):
<div data-sly-test="${wcmmode.edit}" class="cq-dd-images">Drop image here</div>

Related

AEM - Apply separate styles to authoring view and publishing view for component

I'm using Adobe Experience Manager and i need to apply separate styles to authoring view and publishing view for component. The reason for this is I have some JS that changes the layout of the component at desktop size, however in authoring mode this means the component is no longer usable or fully visible.
So far I have:
looked in Adobe Forums for a similar question
tried to add some styles within html file based on the condition of edit mode being true:
<sly data-sly-test.author="${wcmmode.edit}"><style><!--my code--></style></sly>
Instead of writing inline styles based on the edit mode, better way would be to define a separate client library and add that client library on your pages only in edit mode. Let's say, you have a component - "Custom Component" which has the class as - "custom-comp".
<div class="custom-component">
<!-- your custom component html code goes here -->
</div>
So I am assuming you would already have defined some CSS for this component in the project client library that should be loaded on your pages already. To style it different in author mode, you can try following steps -
In your page.html, define a special class which will identify whether your page is being loaded in Author or in Publish. Something like below -
< body class="${wcmmode.edit || wcmmode.design ? 'authoring-mode' : ''}">
Using above line of code, your pages will now have a special class - "authoring-mode" only when you open the page in Author. But when you open page in publish, this class won't appear which is exactly what you want here.
Now, you need to define a new client library in your code which will have CSS and JS files and you need to load this new client library in your customheaderlibs. Again this client library needs to be added only in author mode.
Write custom CSS rules for your custom component using the combination of two class names - "authoring-mode" and component class name - "custom-component".
Test your changes in author mode and publish mode.

Restrict parsys in a static template to include only certain components without using etc/design (AEM)

I am using AEM 6.5 and I have a static template that contains a parsys -
<header class="wrapper">
<div data-sly-resource="${'mypar' # resourceType='wcm/foundation/components/parsys'}"></div>
</header>
I want to restrict this parsys so that only a particular component (say Comp1) can be added.
I know that I can add this can be configured under etc/designs/<app-name>/<template-name>/mypar with a property components. The problem in my case is that the pages that use this template do not have a design associated with it. I dont want to create a new design just for this one property.
Is there and alternative to restrict a parsys or a static template to use only certain components. I need to make this as a prt of my code base.
There is a library wcm.io, which includes a parsys that can be configured in the parent-component. https://wcm.io/wcm/parsys/usage.html This library is maintained by one of the biggest AEM agencies in Germany.
An alternative is to create your own parsys component.

Conditionally include different clientlibs depending on the browser in AEM?

Is it possible to conditionally include different clientlibs based on the user agent of the browser?
IE
<sly data-sly-use.clientLib="/libs/granite/sightly/templates/clientlib.html"
data-sly-call="${clientlib.js # categories='a'}"/>
Modern Browsers
<sly data-sly-use.clientLib="/libs/granite/sightly/templates/clientlib.html"
data-sly-call="${clientlib.js # categories='b'}"/>
AEM version: 6.3
If not, what are the other alternatives to achieve the same?
Note: I tried to get this check done in a sling rewriter server side but the problem is, with the dispatcher on, it will only hit AEM for the furst time and cache the html, any subsequent hit will not invoke any server side logic to render it. Hence, it has to be done client side IMO
For this you have to write custom clientlibs templates as described here : https://github.com/nateyolles/aem-clientlib-async.
And then in the WCMUse class you can check user agent and include clientlibs accordingly.
First of all, as you already pointed out correctly, you need asolution that works with the dispatcher cache. So Sightly is not an option.
Then, regarding the fact, that most AEM templates have paragraph systems with multiple possible components to be added to a page on the one hand and AEM clientlibs are build on a template level (and not on page level) you end up with a clientlib holding lots of unused JS and CSS most of the time, since you have to cover all the possible options of components used in your page and paragraph system.
With that in mind, clientlibs might not be a good option to be used after all.
Having static CSS and JS files in your AEM repo and referencing them client side based on a JS snippet will do the trick and - in most cases - you will not buy any side effects with that approach.
You can either:
Wrap your clientlibs with conditional comments: https://stackoverflow.com/a/11703767
Create a Use-Object that check the User-Agent header and exposes a method isIE that you can use to conditionally include the clientlibs with data-sly-test. Alternatively your Use-Object could just return the proper categiers based on user agent so you can have only one clientlib call.
You could use the <script module> and <script nomodule> to achieve that. The first one is ignored by older browsers and the second one by the modern ones. Similar to Vue's Modern Mode. Check: https://cli.vuejs.org/guide/browser-compatibility.html#modern-mode
More likely you would need some back-end to create your custom clientlib template.

Deleting, Moving pre defined components from template in Adobe AEM

I have requirement where, in template we will have some list of components by default. But the requirement is, author can delete,move these components in the page.
We are using sightly and I have used
<div sly data-sly-resource="${'sample' # resourceType='sampleapp/components/content/sample'}" />
This is working fine. But I am not sure how do to delete and move this component.
Any help is appreciated.
If you have a template/component in which you include a specific component then it cannot be moved or deleted. It will show the delete option but after refresh it will be there again (not configured). The things that can be moved are components placed within parsyses.
To create template which has predefined components that can be then moved around you need to base your structure on parsyses. Place your predefined components within the templates parsyses - within the templates jcr:content. Remember that template is nothing else then a predefined content node.
See the example in which the survey-template has predefined content:

How to restrict components in parsys

Is there a way in CQ 5.6 to restrict use of specific components within a parsys? e.g. I want to restrict author to use only text component within a parsys, following is how I render the parsys inside one of my component JSP file:
<cq:include path="textpar" resourceType="foundation/components/parsys" />
Previously in CQ 5.4 following code in /etc/designs/myapp/.content.xml used to work for this:
<textpar
jcr:lastModified="{Date}2012-10-21T15:00:00.000-07:00"
jcr:lastModifiedBy="admin"
jcr:primaryType="nt:unstructured"
sling:resourceType="foundation/components/parsys"
components="[/libs/foundation/components/text]">
<section jcr:primaryType="nt:unstructured"/>
But in CQ 5.6 it's not working. Am I missing something or the way to restrict components changed?
Thanks
This actually works. There's seems to be some cache issue on my machine though, whenever I change something in /etc/designs/myapp/.content.xml I've to clear my cache to get the updated components, this is on FF 25 (Ubuntu 12.04).
Here is a very easy tutorial on setting default types for parsys and iparsys:
http://experiencedelivers.adobe.com/cemblog/en/experiencedelivers/2012/06/default-components-in-your-parsys.html