Customization in AEM Asset Quick Publish Action

This post is about a requirement raised in Experience League Community forum related to Custom implementation on Asset Publish.  

AEM Asset Quick Publish Customization

Project has custom field named "Effective date". If an asset is selected to publish before an Effective date, pop up should be triggered with option to either "Cancel" or "Continue to Publish"

Requirement of this sort involving customizations on top of an OOB functionality can be approached as follows

  • Locate the OOB files related to the functionality
  • Custom code readiness
  • Understanding the existing logic
  • Incorporating our custom logic by overlaying the OOB files.
  • Testing all possible use cases related to custom functionality without hindering any other related  OOB flow. 

Locate the OOB files:

  • As part of locating the OOB files, first step is to trigger a "Quick Publish" on an Asset and observe the flow.
  • While observing the flow for this purpose, we need to have Developer tools on -> Network Tab with "Preserve Logs" checked  + an eye on address bar.
  • Unlike pages, assets will not prompt a pop up. Instead, loading icon shows up and will be presented with the pop up saying "Selected assets are queued up for activation"/ Success / Failure modal accordingly.
  • Network Trace : 
    • Behind the scene(as evident from Network), references.json and replicate.json (POST XHR request is called). Former is to look for references as with the name and latter for actual replication action which is via a OOB servlet registered with path - /bin/replicate
    • In the list of entries, there will be a column named "Initiator" - hover over the Initiator -> In the pop up we can see an hierarchy of files from which this request is initiated (complete control flow) 
    • At this stage we will arrive at the OOB JS associated with the functionality
  • From Address bar
    • In order to locate the complete resource/page component responsible for this entire view(assets.html as evident in the address bar of the browser)
    • Navigate to http://localhost:4502/system/console -> Sling -> Resource Resolver -> Type in the URL - http://localhost:4502/assets.html -> Click on Resolve -> It resolves to a resource at /libs/dam/gui/content/assets
    • With this information, lets head to CRXDE and access the path /libs/dam/gui/content/assets
    • Observing the nodes under the path, could see that it is a page resource and it has nodes named "head", "actions" and so on that are part of assets.html page.
    • Clientlibs would be in head section and at this path, all category names that are part of assest.html page is available. (Using this category name, we can locate the actual clientlib files location using dumplibs.html - http://localhost:4502/libs/granite/ui/content/dumplibs.html)

Custom code readiness:

  • Have the functional piece of custom code ready. We can test it locally by having separate clientlib category. In this case, we should be able to get the effective date of the selected asset and trigger pop up if current date is less than effective date. 
  • Have this logic ready in separate JS and affirm its working. 
  • To avoid too many conditional checks at code, have created a new dropdown field in Metadata schema to check if asset is to be published based on effective date. Only if "Yes" is chosen, Effective date field will come up and is made mandatory based on this rule that is applied. (Required + Visible based on Rule applied - Rules section on fields in OOB Metadata Schema form). By this way, conditional checks are handled at properties level and controlled with single flag check at code level. 
  • Note : 
    •  Checkbox field is not available OOB in Metadataschema and hence have used dropdown field.
    • Separate clientlib category created is to be added to /assets.html -> head -> clientlibs so as to load when the assets.html is accessed (This is interim step)
    • We are going to incorporate the change in publishasset.js by overlaying to /apps. For now to test this(would like to iterate that this is interim to test it as standalone JS), adding it directly to /libs path(/libs/dam/gui/content/assets/jcr:content/head/clientlibs). Remove it soon after testing, NEVER make any write operation to /libs.

Understanding the existing logic:

  • After locating the JS responsible for this, we need to completely understand the existing logic only then we will be able to arrive at the exact location of where we can incorporate our custom code. 
  • In this use case, on analyzing the publishasset.js(/libs/dam/gui/coral/components/admin/publish/clientlibs/publishasset/publishasset.js), below is the high level flow
    • Initializes all 3 publish status modal (Publish success modal, error modal, info modal) and adds to HTML in hidden state. (_initialize function)
    • replicateToPublish(activator) function is called -> iterates through all selected items -> Call references.json -> Call replicate.json -> Based on replication status, respective modal(one of the above 3) is displayed.

Incorporating custom code by overlay:

  • Once it is ready to include, use "Overlay Node" option on right click actions of a node to overlay the OOB files from /libs to /apps
    • In this case, it is on /libs/dam/gui/coral/components/admin/publish/clientlibs/publishasset node -> Right click -> Overlay Node -> similar structure is created in /apps as /apps/dam/gui/coral/components/admin/publish/clientlibs/publishasset
  • Copy the JS(publishassets.js) to overlayed path in /apps -> Amend the JS to incorporate custom code. 
  • Per the flow mentioned in previous section, second step has to be within condition/ it is the place where our custom code can be added in.
  • Assumptions :
    • Custom logic is written considering multiple asset selection assuming even if one of the asset in multiple selected assets is having effective date in future, then it will show pop up. 
    • If multiple selection is not considered/not allowed, then the logic has to be amended accordingly. Need not run through iteration. 
  • Below snippets highlights where our custom function is included. 
  • Existing OOB:
  • To be changed as: 

Note:

  • Logic within newly added function is slight amended in comparison with above standalone script (in "Custom code readiness" section in order to be in flow with OOB JS - Should be self explanatory)
  • Complete JS is added to GITHUB  - publishasset.js (Per AEM 6.5.0)

Quick Publish flow after incorporating custom code:

Testing/Covering all use cases:

  • It is important that we cover and test all possible use cases related to custom flow.
  • For this use case considered, we might need to consider the flow for "Manage Publication" too based on the business needs.  
  • Also below scenarios to be tested/considered and logic can be extended/amended accordingly based on expected behavior
    • Multiple asset selection with respect to Effective Date - Considered with Assumption as mentioned earlier
    • Combination of assets which has effective date set and one without it - Considered
    • Assets without effective date - Usual OOB flow, considered
    • (TBD based on business needs) Effective date set and has passed current date either due to 
      • Human error of intentionally setting to past date (can be controlled via field validation) or 
      • Asset is once published and to be published again (Understanding to be arrived at whether Effective date will be updated manually in this case)
    Conclusion:
    • This implementation is for demonstration of how customization can be handled. Based on the project/content structure + business process + considering all possible OOB options + in a view of long run, decide on the efficient customization approach.

    Comments

    1. Thank you Vijaylakshmi, this really helped me.

      ReplyDelete
    2. ▷ Online Casino Gambling - Atlantic City | AmbienHoppie
      Our online casinos offer the widest selection of gaming options available at the most exciting casinos in Atlantic City and 온라인 카지노 커뮤니티 cass2 a place to play.

      ReplyDelete
    3. "Thank you for addressing such a practical use case. The way you have broken down the logic into smaller, actionable steps makes it much easier to understand and implement. Would love to see more examples like this!"

      Dust Collector Manufacturer
      Axial Flow Fans manufactrurer

      ReplyDelete
    4. "The part about using separate clientlib categories for testing before incorporating into the OOB structure is a great tip. This ensures clean implementation while maintaining a fallback option. Well done!"

      Pulse jet Dust Collector manufacturer
      Wood Dust Collector

      ReplyDelete
    5. "Great blog! Could you elaborate on the considerations when handling multiple asset selection for effective dates? This scenario seems particularly challenging but critical."

      Wet Scrubber Manufacturer
      Dust Collector

      ReplyDelete

    Post a Comment

    Popular posts from this blog

    Embedding Third party dependency/OSGi bundle in AEM application hosted in AEMasCS

    OSGI Factory Configuration implementation

    Embed Third party dependency using bnd-maven-plugin