/etc/keyand share it between your author and publish servers (See: How to Use Crypto support in Adobe CQ / AEM). However, in AEM 6.3 the Crypto keys were moved out of the JCR to make them more secure in case someone gains access to your CRXDE. Side note, ensure the public can't access CRXDE by going through the AEM 6.3 Security Checklist.
21. You can navigate to
/system/console/bundles/com.adobe.granite.crypto.fileto see the Id.
/crx-quickstart/launchpad/felix/bundle<Id>/datain the file system.
masterfrom the source instance to the target instances.
com.adobe.granite.cryptobundle or the entire AEM instance.
-Dcom.adobe.granite.crypto.file.disable=trueflag. Note that this must happen on the first startup of the instance. The instance will not change behavior once AEM has been started with or without the flag.
/jcr:root//*[@sling:resourceType='granite/ui/components/foundation/renderconditions/simple']. You can find the standard render conditions such as
/libs/granite/ui/components/foundation/renderconditions. There are a few custom render conditions under
/libs/cq/gui/components/projects/admin/renderconditionswhich you can explore, as well as
/libs/wcm/msm/components/touch-ui/renderconditions/islivecopy. There is another great example of a custom render condition in the ACS AEM Commons project which displays components based on the current path.
granite:rendercondition, set the
sling:resourceTypeto the render condition component such as
granite/ui/components/foundation/renderconditions/simpleand populate the required properties such as
expression. For example, the following textfield will only render when the query string parameter
ELfor short. As such, you have access to
tenant. You also have access to a powerful, yet simple and straight-forward syntax to evaluate logic in Expression Language. Furthermore, Granite provides extra convenience with a few provided EL Functions. For example:
granite/ui/components/foundation/hyperlinkcomponents to pass data forward, such as:
simplerender conditions are quick and readily available for most basic expressions. However, if you need custom logic, you can write your own render condition. A render condition is simply a JSP component. Within your custom logic you will get the
granite:renderconditionresource, retrieve its relevant properties via the resource's Config and set a true or false SimpleRenderCondition as a request attribute. To evaluate EL expressions, use the ExpressionHelper by way of the ExpressionResolver service, which is powered by the Apache Commons EL interpreter. The combination of a custom render condition and EL expressions is very powerful.
sling:resourceTypeto the path of your custom render condition component and populate your defined resource properties.
simplerender condition and that you can combine conditions by nesting
notconditions. This snippet from the demo project reveals a variety of ways to dynamically render Touch UI components including cookies, headers, query string parameters, selectors, suffixes, JCR privileges and custom render conditions.
/editor.html. Therefore, the path, suffix, selectors and query string parameters are independent of what you see in your browser's address bar when using a normal component dialog in the editor.
onloadattributes on your
scriptelements. Likewise, while managing your cross-origin resource sharing (CORS) HTTP requests, you may want to utilize the
crossoriginattribute on your
clientlib.htmlcontains named Sightly template blocks (
all), which in turn set the proper Sightly expression option for mode and call the named Sightly templates in
graniteClientLib.htmlthen sets the proper Sightly expression options and delegates the more complex logic to a Java-Use API POJO.
ClientLibUseObject.javathen utilizes the
HtmlLibraryManagerin order to write out the final HTML markup.
/libs/granite/sightly/templatesnode. To make any alterations, we simply copy all three files out of
/apps, update the files, and update our Sightly components to point to the new clientlib component (usually
headlibs.htmlor similar partial in the page component).
writeJsIncludemethods. However, since we want custom markup, we need to do that ourselves in the POJO.
/confnode at the root level along with
/libs. Over time the
/etcfolder's responsibility has expanded and configurations have been moved in an effort to clean it up a little. Whereas prior to 6.1 you would have stored site configurations in
/etc, it's now recommended that you store those configurations under
/conf. Along with the new node structure Adobe has provided a valuable, yet simple, utility to help manage these new site configurations in
/content/aviato /content/piedpiper /content/hooli /content/hooli/hoolixyz
cq:confproperty of type
Stringat the root of every project page and point it to the site's corresponding configuration path. A global configuration will be used if a
cq:confproperty is not specified as is the case for Aviato in this example.
/content/piedpiper/jcr:content/@cq:conf = "/conf/tentants/piedpiper" /content/hooli/jcr:content/@cq:conf = "/conf/tentants/hooli" /content/hooli/hoolixyz/jcr:content/@cq:conf = "/conf/tentants/hooli/hoolixyz"
Confrespects relative paths as it pertains to the
cq:confproperty. Therefore, the following settings could also be used:
/content/hooli/jcr:content/@cq:conf = "/conf/tentants/hooli" /content/hooli/hoolixyz/jcr:content/@cq:conf = "hoolixyz"
/confshould closely resemble
/content. The configuration nodes should be of type
cq:Pagewith the configuration properties on the
jcr:contentsub-nodes. All configurations start below the path specified in
cq:confwith the addition of
/conf/global/settings/socialmedia/facebook/jcr:content/@enabled = false /conf/tenants/piedpiper/settings/socialmedia/facebook/jcr:content/@enabled = true /conf/tenants/hooli/settings/socialmedia/facebook/jcr:content/@enabled = true /conf/tenants/hooli/hoolixyz/settings/socialmedia/facebook/jcr:content/@enabled = true
/conf/globalis special as it provides an ultimate fallback in the
Confinheritance mechanism. It this example Aviato does not have its own config, so it would use the global configs.
/conf/tenantsis not dictated by AEM, but is a convention worth following to help prevent namespace collision in multi-tenant scenarios.
/libswith the same apps-then-libs type resolution that you are already familiar with. The resolution order can be set in the Felix console
Confobject to get a site configuration. The
Confobject is usually obtained by adapted a Resource or Page using Apache Sling's adaptTo() method. Once you have the site's
Confobject, you can get any number of predefined ValueMaps and properties. Notice that the ValueMaps cannot be modified – they are read-only. Properties are retrieved from the ValueMap in the familiar way of passing in either a default value or the class type.
Confobject you retrieve is based on the path of the resource. So if have a Sling Model or WCMUsePojo and you adapt the current page, you will get a different
Confthan if you adapt the current resource.
ConfMgris a fairly lightweight and transparent helper. Everything is in the JCR, so configurations can be accessed through normal channels such as a Resource Resolver. However, there are three main benefits to using
Confobject is looking for a config that doesn't exist in the subproject or project, it will look under
Confinherits and overwrites at the node level, not the property level.
Confhandles null values for you. If the configuration, ValueMap or individual properties are null, you can continue without null checks and you won't get a Null Pointer Exception.
Confrespects ACLs and multi-tenant privacy. If you setup your ACLs correctly, a shared component between two tenants will still only be able to access the configurations of the current tenant.
Confdoes not allow relative paths that try to move up the tree and into another tenant (i.e. "../../differentSite/foo/bar").
ConMgrcan be used as a service.
Conf#getList()method, which returns a List of ValueMaps. Configurations can also be chosen explicitly by using a Resource Resolver to get the specific resource.
clear, of which only
clearmethods are not necessary in this example as the validator would use the default AEM provided methods, however, they are included for reference.
selectorproperty ties the validator to the form elements on the page. The property accepts any jQuery selector such as a class (
.my-class-name), type (
INPUT) or attribute (
validateproperty is the function that validates the form element's input. The function provides the form element as a jQuery object as the single available parameter. The field is treated as invalid if this function returns a string literal as the validation error message.
clearproperties are functions that update the UI when when the form element is determined to be invalid or valid respectively. Each function makes two parameters available, the form element as a jQuery object and the validation message.
selectorproperty is obviously required, otherwise the validator can never be called. However, the
clearare optional. For example, if a form element is already being validated through an existing validator, you can update the UI behavior of the error message by registering a new validator with only
clearfunctions. Order of registration is important; the last validator registered is the first validator used. View the Granite UI Validation documentation for further information. AEM's default validators are located at
clearfunctions is to validate a custom dialog component. For example, in the AEM Touch UI Validation Library, the two functions are used in the multifield validator as the field used is an HTML textbox to validate and it's not in the same HTML structure as the other HTML textboxes that the default AEM validator has already registered.