Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

Custom workflow publishes page with selected referenced assets

Avatar

Level 4

Hello,

I'm trying to design a workflow that can publish page with referenced assets, basically do the same job as "Published References" popup in manage publication.

I suppose the process would be:

1. Get all referenced assets and select what I need.

2. Publish these assets with page.

 

I was thinking to get the asset path(s) under payload/jcr:content (our team stores the asset path(s) there), and set these path under the workflow instance to publish them. However, it seems that workflow instance doesn't bind referenced assets publication (I used manage publication and selected all references, but cannot find them under corresponding workflow instance).

 

As to getting the referenced assets, is ReferenceSearch a better way to get asset path(s)? Will be gratefull if there's any code snippet to look at

And as long as I get the assets I'd like to publish, what should I do next? what's the logic behind it?

 

Thank you.

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

@YuSheng 

You only need the keys from the map (assetReferencesMap.getKeys()) and ignore the values, which will give you the asset paths 

/content/dam/asset1.xls
/content/dam/asset2.pdf 
/content/dam/asset3.PNG

Next step is to publish the paths using the Replicator service 

@Reference
protected Replicator replicator;

replicator.replicate(replicationSession, ReplicationActionType.ACTIVATE, assetPaths, null);

 

 

View solution in original post

4 Replies

Avatar

Community Advisor

@YuSheng 

You can rely on AssetReferenceSearch to get the assets used in the page to publish them.

Example snippet: 

Node pageJcrContentNode = pageJcrContentResource.adaptTo(Node.class);

Map<String,Asset> assetReferencesMap = new
AssetReferenceSearch(pageJcrContentNode, "/content/dam", resourceResolver).search();

 

If you're looking to get all the references, like Assets, Page Template, Experience Fragments, Content Fragments, and others, then you might want to use ActivationReferenceSearchService to getReferences

Avatar

Level 4

Thank you @Lokesh_Vajrala,

The snippet is clear about getting the assets, now I got the asset map like

 

{
/content/dam/asset1.xls=com.day.cq.dam.core.impl.AssetImpl@abcd1234, 
/content/dam/asset2.pdf=com.day.cq.dam.core.impl.AssetImpl@abcd1234, 
/content/dam/asset3.PNG=com.day.cq.dam.core.impl.AssetImpl@abcd1234
}

 

but how to publish them after getting this map?

 

I've checked the manage publication instance (scheduled activation model) and found the asset paths can be seen in the "comment" and "versions" properties under metadata, the form be like: 

{
    "/etc/workflow/packages/generated-package0/jcr:content": "1.0",
    "/content/MyProject/PageToPublish/jcr:content": "1.0",
    "/content/dam/Asset1.xls": "1.0",
    "/content/dam/Asset2.pdf": "1.10",
    "/content/dam/Asset3.PNG": "1.10",
    "/conf/MyProject/settings/wcm/templates/PageTemplate/policies/jcr:content": "1.0"
}

 

Is AEM processes publication by recognizing this property? the numbers after the paths look like version number which is generated automatically and there are more paths related to the payload than just asset (template, packages...etc.) I suppose I cannot simply override the property.

So what should I do with the asset map I get manually?

Avatar

Correct answer by
Community Advisor

@YuSheng 

You only need the keys from the map (assetReferencesMap.getKeys()) and ignore the values, which will give you the asset paths 

/content/dam/asset1.xls
/content/dam/asset2.pdf 
/content/dam/asset3.PNG

Next step is to publish the paths using the Replicator service 

@Reference
protected Replicator replicator;

replicator.replicate(replicationSession, ReplicationActionType.ACTIVATE, assetPaths, null);

 

 

Avatar

Level 4

Thank you @Lokesh_Vajrala now it works!

I paste my snippet below for future reference or anyone needs it

@Reference
protected Replicator replicator;
	
@Override
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap processArguments) throws WorkflowException {
		String payloadPath = workItem.getWorkflowData().getPayload().toString();

		ResourceResolver resolver = workflowSession.adaptTo(ResourceResolver.class);
		Resource payloadResource = resolver.getResource(payloadPath + "/jcr:content");
		Session session = resolver.adaptTo(Session.class);

		Node pageJcrContentNode = payloadResource.adaptTo(Node.class);
		Map<String,Asset> assetReferencesMap = new AssetReferenceSearch(pageJcrContentNode, "/content/dam", resolver).search();
		List<String> keysList = new ArrayList<String>();
		String[] assetPathsArray;
		
		for ( String key : assetReferencesMap.keySet() ) {
			keysList.add(key);
		}
		
		assetPathsArray = keysList.toArray(String[]::new);
		
		try {
			// replicator.replicate(replicationSession, ReplicationActionType.ACTIVATE, assetPaths, null);
			replicator.replicate(session, ReplicationActionType.ACTIVATE, assetPathsArray, null);
		} catch (ReplicationException e) {
			
			e.printStackTrace();
		}
	} 

The process combines getting assets and replication together, will try to separate them with asset selection function in between.