maven-scr-plugin
while the OSGi DS annotations require the
maven-bundle-plugin
version 3.2.0 or greater.
maven-scr-plugin
you may be used to finding the DS output under
/target/classes/OSGI-INF
and
/target/classes/OSGI-INF/metatype
. With the
maven-bundle-plugin
you will have to unzip the compiled artifact (the jar file) to find the DS output in its
/OSG-INF
directory.
org.apache.felix.scr.annotations.*
, you'll use
org.osgi.service.component.annotations.*
and
org.osgi.service.metatype.annotations.*
.
maven-scr-plugin
, you need the
maven-bundle-plugin
version 3.2.0 or greater.
org.osgi.service.metatype.annotations
and
org.osgi.service.component.annotations
(currently version 1.3.0) rather than
org.osgi.core
and
org.osgi.compendium
. See the provided sample project's POM file for more specifics.
org.apache.felix.scr.annotations.*
annotations are deprecated.
AttributeDefinition
method 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
resource_resolver_searchpath
.
SlingServlet
annotation 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/key
and 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.file
to see the Id./crx-quickstart/launchpad/felix/bundle<Id>/data
in the file system.hmac
and master
from the source instance to the target instances.com.adobe.granite.crypto
bundle or the entire AEM instance.-Dcom.adobe.granite.crypto.file.disable=true
flag. 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
simple
,
and
,
or
,
not
and
privilege
under
/libs/granite/ui/components/foundation/renderconditions
. There are a few custom render conditions under
/libs/cq/gui/components/projects/admin/renderconditions
which you can explore, as well as
/libs/cq/gui/components/renderconditions/islocked
,
/libs/wcm/msm/components/touch-ui/renderconditions/isblueprint
and
/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:resourceType
to the render condition component such as
granite/ui/components/foundation/renderconditions/simple
and populate the required properties such as
expression
. For example, the following textfield will only render when the query string parameter
biz
equals
baz
.
EL
for short. As such, you have access to param
, paramValues
, header
, headerValues
, cookie
, requestPathInfo
, state
and 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/hyperlink
components to pass data forward, such as:
simple
render 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:rendercondition
resource, 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:resourceType
to the path of your custom render condition component and populate your defined resource properties.
simple
render condition and that you can combine conditions by nesting
and
,
or
and
not
conditions. 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.
defer
,
async
, and/or
onload
attributes on your
script
elements. Likewise, while managing your cross-origin resource sharing (CORS) HTTP requests, you may want to utilize the
crossorigin
attribute on your
script
and/or
link
elements for JavaScript and CSS.
clientlib.html
contains named Sightly template blocks (
js
,
css
,
all
), which in turn set the proper Sightly expression option for mode and call the named Sightly templates in
graniteClientLib.html
.
graniteClientLib.html
then sets the proper Sightly expression options and delegates the more complex logic to a Java-Use API POJO.
ClientLibUseObject.java
then utilizes the
HtmlLibraryManager
in order to write out the final HTML markup.
/libs/granite/sightly/templates
node. To make any alterations, we simply copy all three files out of
/libs
into
/apps
, update the files, and update our Sightly components to point to the new clientlib component (usually
headlibs.html
or similar partial in the page component).
loading
,
onload
, and
crossorigin
options.
HtmlLibraryManager
's
writeIncludes
,
writeCssInclude
and
writeJsInclude
methods. However, since we want custom markup, we need to do that ourselves in the POJO.
/conf
node at the root level along with
/content
,
/etc
,
/apps
and
/libs
. Over time the
/etc
folder'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
com.adobe.granite.confmgr.ConfMgr
and
com.adobe.granite.confmgr.Conf
.
/content/aviato /content/piedpiper /content/hooli /content/hooli/hoolixyz
cq:conf
property of type
String
at 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:conf
property 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"
Conf
respects relative paths as it pertains to the
cq:conf
property. 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"
/conf
should closely resemble
/content
. The configuration nodes should be of type
cq:Page
with the configuration properties on the
jcr:content
sub-nodes. All configurations start below the path specified in
cq:conf
with the addition of
/settings
.
/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/global
is special as it provides an ultimate fallback in the
Conf
inheritance mechanism. It this example
Aviato does not have its own config, so it would use the global configs.
/conf/tenants
is not dictated by AEM, but is a convention worth following to help prevent namespace collision in multi-tenant scenarios.
/conf
,
/apps
and
/libs
with the same apps-then-libs type resolution that you are already familiar with. The resolution order can be set in the Felix console
com.adobe.granite.confmgr.impl.ConfMgrImpl
configuration:
http://localhost:4502/system/console/configMgr/com.adobe.granite.confmgr.impl.ConfMgrImpl.
Conf
object to get a site configuration. The
Conf
object is usually obtained by adapted a Resource or Page using Apache Sling's adaptTo() method. Once you have the site's
Conf
object, 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.
Conf
object 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
Conf
than if you adapt the current resource.
ConfMgr
is 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
com.adobe.granite.confmgr.Conf
.
Conf
object is looking for a config that doesn't exist in the subproject or project, it will look under
/global
.
Conf
inherits and overwrites at the node level, not the property level.
Conf
handles 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.
Conf
respects 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.
Conf
does not allow relative paths that try to move up the tree and into another tenant (i.e. "../../differentSite/foo/bar").
ConMgr
can 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.