Thursday, 12 March 2015

Requesting AEM Component via AJAX

Why?
In AEM pages are created in modular fashion and this modularity is achieved using components. But we often come across a situation where we want a specific component to be reloaded and not the complete page but mostly dispatcher is the main reason for loading a component via AJAX.

As dispatcher caches component's output html due to which dynamicity of a component becomes questionable. For instance if we want a component to show unique results with each request. Loading component via AJAX is one way out for handling such scenarios.


Sample AJAXified component

How?
To request a component via AJAX we will be using a Sling trick. In this trick we will request the URL to the component node then Sling resolution comes into the picture and it look for sling:resourceType property ,executes the script at given path & sends final HTML response.

It is quite straight forward to implement this approach. We need to create a cq:component and the Javascript code for making a AJAX request.  As we would want our component to give unique response each time, we can either use a selector or query parameters and then give response accordingly.

Code snippet below gives an example of how to request the desired component via ajax and show  the latest result.

But for requesting a component's node we need to store the path on which we would be requesting, we will have to store that on our page itself in the page's DOM. Like shown below:

Now we just need to read the path of the component node and request for component to reloaded via AJAX. Here is the sample jQuery method for how to achive this.

I have created a demo component which is loaded on the page via AJAX. To use it one need to drop AJAX Demo Component inside parsys of AJAX Demo Warpper component and on press of reload button it reloads the component via AJAX.

Here is the link for code repository for a sample component that is reloaded via AJAX : Requesting cq:components via AJAX

Tuesday, 20 January 2015

OSGI : Creating Factory configuration in CQ

AEM houses a powerful open source framework in its technology stack, Apache Felix. Felix is a open source implementation of OSGi. OSGi provides a way to manage bundles and their configurations.

OSGi provides a way to configure services and modify those configurations on the run-time. But apart from this there is a another powerful feature that OSGi provides that is : ability to create Factory Configurations. Factory Configurations is a way to create a single service, and bind multiple configurations to it  & then consume those configurations from different classes/Services. You all might have used Logger service provided by CQ out of the box, logger is an example of factory configuration service. 


Factory Configuration















Here are the steps for how to create factory configuration in CQ.

Step 1:

Create a Component/Service class to hold configurations values. This component will act a interface for adding properties of multiple configurations. Key for creating this Component/Service class is that declare this class as a configurationFactory and pass configuration policy as required.



Step 2:

Create a service to that actually uses the FactoryConfig Component/Service as a interface to allow user to add configuration and accept values of properties. For creating this service we will use dynamic binding of OSGi. We will have to create a collection of FactoryConfig class and binding & unbinding methods are also required that will add or remove each FactoryConfig object in/from the collections.


Here is the link to code repository for this service : OSGi Factory Config

Wednesday, 10 December 2014

Default vaules with CQ5/AEM component

Attimes we come across a situation while creating Components in CQ/AEM, where we want a default value of some property to be set the moment component is dropped. This can be done via JCR API but there is an easy way that I will cover in this post.

Using cq:template node :



cq:template node

Simply create a node under component node with name "cq:template" of type "nt:unstructured". 


Now add any property on this node you want to set as default value on the component. Not only properties you can even add node under this node if you want to create a default node under the component node.


Component node hierarchy under /apps 

And Its done. Now every time you drop this component on any page, default values will be created under the component node as shown below :

Final node hierarchy under /content

Here is link to code repository for this component : https://github.com/ankit-gubrani/Codebrains/commit/eea7cc35ae9c736e7ac4d39b398a37f9e5939b88

Saturday, 15 November 2014

Feed importer in Adobe CQ/AEM

AEM comes with a pre-installed feature to import feeds into CQ. Feed importer comes with capability to import RSS and Atom feeds.

Hey!! Wait before that you must be thinking, what is a feed?

Web feed is a way to provide users with updated content. Web feeds are commonly used for news updates as news are the most frequently updating data.

Feed importer is a service to fetch data from feeds or any external source of data on a periodic basis and save data fetched, in the form of CQ page.It polls the specified external data source in given interval.


Here are the steps how to create feed importer in CQ :


Firstly, create a page under which all the imported data will be saved in the form of CQ:Page. All the new pages that will be created under root page will have sling:resourceType property's value same as the root page.

Now once root page is created, create Feed importer :

Open http://<host>:<port>/etc/miscadmin and go to importers




And Open the Feed Importer page, it will open a page as shown 
below :



 Now click on the Add button and complete the dialog as shown below:



Here is link for Atom feeds of Codebrians blog :

http://codebrains.blogspot.com/feeds/posts/default

The moment OK is clicked a Polling configuration node is created, that will poll given feed URL and fetches new data back to CQ then creates pages under given hierarchy.

Here is the one of the auto-create page:























Here is the Link to Github repository of Codebrains to refer the code : 
https://github.com/ankit-gubrani/Codebrains

Wednesday, 12 November 2014

Populate dropdown in CQ5 dialog using Servlet

Dropdowns in CQ5 are easy to create and use, all that needs to be done is create a node with name options and primaryType as cq:widgetcollections and sub-nodes with options.

But problems comes in when the dropdowns with dynamic data or options is to be created. So, in this blog you will see how to address the problem of populating dropdown dynamically.

Firstly, create a source from which data is to be fetched in our case we have registered a Servlet in OSGI at path "/bin/codebrains.json" which returns a JSON object as :

{"root":[{"text":"CodeBrains_Text_0","value":"CodeBrains_Value_0"},{"text":"CodeBrains_Text_1","value":"CodeBrains_Value_1"},{"text":"CodeBrains_Text_2","value":"CodeBrains_Value_2"},{"text":"CodeBrains_Text_3","value":"CodeBrains_Value_3"},{"text":"CodeBrains_Text_4","value":"CodeBrains_Value_4"}]}

Once your servlet is ready and it gives response in the desired format, now browse to Dropdown widget node and add properties that are shown below :









Add following properties on the node :
  • xtype (Required) : selection
  • type : select
  • options (Optional but required if data is to be fetched from servlet) : <path-of-the-servlet> [Value of this property should be path of servlet which will serve the JSON data to be populated in the combo-box]. In our case its value should be "/bin/codebrains.json" as it the path at which servlet is registered in OSGI. 
  • optionsRoot  (Optional):  [Name of the property that contains options array. Use "." or dot-annotation to get till the property that contains options array. ] In our case its value should be "root" as root property of JSON object contains the Array.
  • optionsTextField (Optional): [Name of the field for the options text. This property is used if options object does not contains Text property which is read by default.
  • optionsValueField (Optional) : [Name of the field for the options value. This property is used if options object does not contains Value property which is read by default. ] (Optional)
  • allowBlank  (Optional) : [This property should have boolean value and is used to make any field mandatory. If set false that widget becomes mandatory cannot be set blank. ]





























Here is the Link to Github repository of Codebrains to refer the code : 
https://github.com/ankit-gubrani/Codebrains

Sunday, 9 November 2014

How to reduce file file size of a image using GIMP ?

Does bulky sized images eats up significant amount of space of your disk ? Or such big file size images becomes a barrier to share these images ?    

Here is the solution for you to reduce the file size of a image using GIMP. 

There are two ways by which size of a image can be controlled : 
  1. First by Scaling the image i.e resizing the image.
  2. Second Compressing an image i.e image compression means reducing the size of graphics file.

Resizing the Image(Solution 1) :


Open up the image you want to reduce size of. Then form Scale menu select Scale Image option to open Scale Image Dialog. Same dialog can be opened up by right clicking on the  image → image → Scale Image.


This will open the Scale Image dialog. In the width field of Scale Image dialog and hit tab height will be calculated automatically. Now this image is scaled and size of the image will be reduced on saving.  


Compressing The Image(Solution 2) :


This is a easier way to  reduce the image. All you need to do is, open any image in GIMP. Then go to file → Save As. This will open the Save image dialog

On clicking Save another dialog will  pop up that gives user an option to provide quality of the image. Higher the quality, bigger will be the size of the image.




Your comments and suggestions are welcome.


Wednesday, 22 October 2014

AEM Multifield with different widgets

Multifield widget in AEM was introduced to allow authors to enter any number of values they want and multifield serves its purpose pretty well. But multifield widget out of the box provides only textbox to take input from author. And at times we are in a situation where we want multifield with different widget for eg pathfield or a textarea or datefield. 

In this article we will see how to create or use multifield with different widgets or Xtypes.


Default Multifield widget

Solution : 

Creating a multifield with custom xtype or widget is a two step process. 

Step 1 : Create a multifield widget i.e create a new widget with xtype multifield. But this will create multi-type with only text field for input as shown above. 

FieldConfig node














Step 2 : create another widget with name fieldConfig and add value of xtype property as whatever widget you want in multifield, in this example we have used pathField. 

 
Multifield with pathfield as xtype Multifield with Datefield as xtype


The values that are stored can be accessed the same ways we access in a values of default mutifield widget. 

For reference, here is the Link for the demo Multi-field component : 

https://github.com/ankit-gubrani/Codebrains/tree/master/content/src/main/content/jcr_root/apps/codebrains/components/content/multifieldDemo