With the complexity of your website, your code complexity will also increase. With this, it becomes more and more difficult to maintain your JavaScript and CSS code. A website made on top of AEM also faces this issue. To combat this, AEM provides a cool feature called Client Libraries.
Client Libraries in AEM
Client libraries allow us to manage our client-side code including JS and CSS and provide options to debug, minify, merge and gzip the client-side code.
- Go to your project folder in CRXDE and create a node called clientlibs of type cq:ClientLibraryFolder
Create a clientlib |
- Now we need to add the categories for the clientlib. Categories is the identifier used to directly include this clientlib from a content page or to embed it in other clientlibs. We can categorize our clientlibs using this property to manage files easily and only load whatever we need. The categories property, being multi-valued, allows a library folder to be part of more than one category. Add the categories property to the clientlibs node.
Name: Categories
Type: String[]
Value: cq.authoring.dialog
- Create the following structure in clientlibs folder
JS and CSS libs |
As you can see, we have created js and css folders (all JS files will go under js folder and all CSS files will go under css folder) along with two text files js.txt and css.txt.
- Create a new component in your project folder as below
Create a component |
- Create a new node under your component cq:dialog of type nt:unstructured. Now create its children nodes as per the below configuration.
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Client Lib Demo"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/tabs"
type="nav"/>
<items jcr:primaryType="nt:unstructured">
<tab1
jcr:primaryType="nt:unstructured"
jcr:title="Properties"
sling:resourceType="granite/ui/components/foundation/container">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>
<items jcr:primaryType="nt:unstructured">
<columns
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<imageSrc
jcr:primaryType="nt:unstructured"
sling:resourceType="cq/gui/components/authoring/dialog/fileupload"
autoStart="{Boolean}false"
class="cq-droptarget field-bgvalue"
fieldDescription="Drag & Drop Image"
fieldLabel="Image"
fileNameParameter="./imageName"
fileReferenceParameter="./imageRef"
id="file-upload-special"
mimeTypes="[image]"
multiple="{Boolean}false"
name="./image"
title="Image"
uploadUrl="${suffix.path}"
useHTML5="{Boolean}true"/>
<altText
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/textfield"
class="field-prereq"
fieldDescription="Please describe the image for screen readers."
fieldLabel="Alt Text"
id="alt-special"
name="./altText"
validation-error-msg="This field is required when the Image is set."
validation-prereq=".field-bgvalue img"
validation-prereq-attr="src"/>
</items>
</columns>
</items>
</tab1>
</items>
</content>
</jcr:root>
- This component has one fileupload widget and one textfield. Our goal is to put validation on the Alt text field. We want the Alt Text field should be required only if we author the Image in the fileupload widget.
- For the validation, we have to write some JS code. Therefore, create a new file named validation.js in the js folder and paste the following code in it.
$(window).adaptTo("foundation-registry").register(
"foundation.validation.validator", {
selector: "#alt-special", // validates the specific alt field
validate: function(el) {
var $el = $(el);
var $form = $el.closest('form'); // get the form
var $upload = $form.find("coral-fileupload[name$=image]"); // find the file upload widget
if ($upload.hasClass('is-filled') && !$el.val()) { // if class exists, return the validation message
return "Enter Alt Text";
} else {
return;
}
}
});
- This code searches the required class and if the class is found, then the validation passes and the edit dialog will be saved, otherwise, it won't.
- Now open the js.txt file and paste the following code in it.
#base=js
validation.js
- The first line determines the path of the JS files relative to the js.txt.
- The second line determines the JS file be included in the client library. Each JS file we want to include has to be written in a new line.
- Now open the dialog and try to save it after authoring image but the Alt Text field is empty. The dialog will not save and show validation error.
Validation error |
- Thus, our client libraries are including. Similarly, we can write CSS and include it in the css.txt.
Other properties in clientlibs
Apart from the few properties discussed in the above section, we have a few other important properties.
dependencies
Let's say clientlibA depends on clientlibB which depends on clientlibC, then on the page which is referring clientlibC, all clientlibA, clientlibB and clientlibC will be included. Thus, dependency property signifies if a one clientlib file depends on others.
embed
For the minifying purpose, AEM will merge all the clienlibs in the current one. If clientlibA embeds clientlibB which further embeds clientlibC, then clientlibA will be loaded by embedding clientlibB's code and clientlibC will not be embedded.
Clientlib configuration
If you navigate to http://<host>:<port>/system/console/configMgr and search for Adobe Granite HTML Library Manager and open it then you will see it has configurations for Minify, Debug, and GZip.
Adobe Granite HTML Library Manager |
Apart from these basic configurations, we are also provided many other configurations to make clientlibs better.
No comments:
Post a Comment
If you have any doubts or questions, please let us know.