maven-scr-pluginwhile the OSGi DS annotations require the
maven-bundle-pluginversion 3.2.0 or greater.
maven-scr-pluginyou may be used to finding the DS output under
/target/classes/OSGI-INF/metatype. With the
maven-bundle-pluginyou will have to unzip the compiled artifact (the jar file) to find the DS output in its
org.apache.felix.scr.annotations.*, you'll use
maven-scr-plugin, you need the
maven-bundle-pluginversion 3.2.0 or greater.
org.osgi.service.component.annotations(currently version 1.3.0) rather than
org.osgi.compendium. See the provided sample project's POM file for more specifics.
org.apache.felix.scr.annotations.*annotations are deprecated.
AttributeDefinitionmethod naming convention will immediately seem out of place. It's very Pythonic looking with its use of underscores. You don't need to write your method names that way, but the reason for doing so is that the underscores are converted to dots for display in the Felix console and your OSGi configs. For example, you're probably familiar with seeing properties defined as something like
resource.resolver.searchpath. To achieve this in your configuration class, your method would be named
SlingServletannotation is a special case - it's a convenience annotation and unfortunately it's not available anymore. However, the idea is that it will be available in the future as a custom annotation provided by Sling working in the OSGi DS framework when R7 is released. Your current SCR SlingServlet looks something like this (although without all the available properties set):
Servlet.class. The service reference properties for paths, extensions, selectors, methods and resourceTypes are simple String properties. When setting array properties, set each entry on a new line. See the Apache Sling docs on Servlet Registration for the available service reference properties. When setting a non-String property value such as an Integer or Boolean, include the type such as
service.ranking:Integer=100. Here's the OSGi version of that same servlet (again, you probably won't use all the available properties in your servlet):
/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.