Extending the Apache Sling Sitemap Generator for AEM 6.5.11 and AEMaaCs | AEM Community Blog Seeding | Community
Skip to main content
kautuk_sahni
Community Manager
Community Manager
December 8, 2021

Extending the Apache Sling Sitemap Generator for AEM 6.5.11 and AEMaaCs | AEM Community Blog Seeding

  • December 8, 2021
  • 5 replies
  • 6556 views

BlogImage.jpg

Extending the Apache Sling Sitemap Generator for AEM 6.5.11 and AEMaaCs by Nikhil Kumar

Abstract

As mentioned in the earlier article of Apache Sling Sitemap Generator we will be exploring on how we extend it to have out extended Apache Sling Sitemap with properties like lastModifiedData, priority and frequency.

As Apache Sling Sitemap bundle is open-source. So we will see how we can extend it to handle our custom properties. We can refer it’s README.md file for the whole process to extend the Apache Sling Sitemap Generator.

We will first start with creating or Java class MySitemapGenerator and with a higher Ranking (let’s say 20 here). As the PageTreeSitemapGeneratorImpl in the components console. already have a ranking of 10. Now we will go ahead and create MySitemapGenerator that extends the abstract class ResourceTreeSitemapGenerator.


package com.mynewsite.core.service.impl;

import java.util.Calendar;
import java.util.Optional;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.sitemap.SitemapException;
import org.apache.sling.sitemap.builder.Sitemap;
import org.apache.sling.sitemap.builder.Url;
import org.apache.sling.sitemap.spi.common.SitemapLinkExternalizer;
import org.apache.sling.sitemap.spi.generator.ResourceTreeSitemapGenerator;
import org.apache.sling.sitemap.spi.generator.SitemapGenerator;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.propertytypes.ServiceRanking;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.wcm.api.Page;

@Component(service = SitemapGenerator.class)
@ServiceRanking(20)
public class MySitemapGenerator extends ResourceTreeSitemapGenerator {

private static final Logger log = LoggerFactory.getLogger(MySitemapGenerator.class);

@Reference
private SitemapLinkExternalizer externalizer;

@Override
protected void addResource(final String name, final Sitemap sitemap, final Resource resource)
throws
SitemapException {

final Page page = resource.adaptTo(Page.class);
final String location = this.externalizer.externalize(resource);
final Url url = sitemap.addUrl(location);
final Calendar lastmod = Optional.ofNullable(page.getLastModified())
.orElse(page.getContentResource()
.getValueMap()
.get(JcrConstants.JCR_CREATED, Calendar.class));
if (lastmod != null) {
url.setLastModified(lastmod.toInstant());
url.setPriority(2);

}
log.debug("Added the {} to Extended Sitemap", url);
}
}

Read Full Blog

Extending the Apache Sling Sitemap Generator for AEM 6.5.11 and AEMaaCs

Q&A

Please use this thread to ask the related questions.

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.

5 replies

Level 2
February 18, 2022

As per the article if we add service ranking the custom generator is getting picked, but if we use scheduler and add the Custom Generator in the Include Generators list of OSGI config then its not picking the custom, still OOTB Sitemap generator is getting called.

 

Am i missing something here, or this is a known issue?

Nikhil-Kumar
Community Advisor
Community Advisor
May 31, 2022

@bnagesh  - I guess we need to provide the service ranking to make it work, or else it picks up the OOTB sitemap.

Level 2
May 31, 2022

@nikhil-kumar Yes. Service ranking is needed, and the generator to be invoked/exclude can be mentioned under osgi configs.

 

Your blog helped me a lot thank you.😊

New Member
May 26, 2022

Thanks @kautuk_sahni  for sharing this. I am curious know how the multiple externalizer domains will be handled with this implementation with SitemapScheduler. Eg. I have 2 website domains in on my publish instance :

Domain 1 - https://demo1.com 

Domain 2 - https://demo2.com

Domain 1 is configured to point to /content/domain-1 on dispatcher

Domain 2 is configured to point to /content/domain-2 on dispatcher

 

I also setup a sitemapscheduler to generate sitemap at specific time interval.

 

Now for domain-1/sitemap.xml, it should generate sitemap with https://demo1.com prefixed in path while for domain-2 it should have https://demo2.com in sitemap urls.

 

Do we need to write 2 separate implementations of sitemap generators by passing different externalizer keys? Even if we try to have 2 implementations, implementation will higher ranking will be in affect other one will be ignored. Also, how the scheduler will be forced to generate 2 separator sitemap implementations?

 

 

Just trying to think over it, may be we need to customize the SitemapLinkExternalizer  implementation and use this custom externalizer into our MySitemapGenerator  should work. OOTB SitemapLinkExternalizer implementation may not work for this scenario. Any thoughts?

Thanks,

 

 

 

 

 

 

 

 

 

Nikhil-Kumar
Community Advisor
Community Advisor
May 31, 2022

@rajeevyadav1 - We can configure multiple sitemap generator at the OSGI Config level. Also if you want to have custom implementation, you can update the above extended class to have different set of priority for different domain. As the priority is set at the URL level.

Level 9
October 29, 2022

If someone is using scr annotations.. as we are unfortunately,

@8220494( immediate = true)
@1790552(value = SitemapGenerator.class)
@Properties({ @2542150(name="service.ranking",intValue = 40)})

Service ranking can be troublesome indeed. Took me  for a jolly ride 😛

 

We are on 6.5.12 and 

<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.sitemap</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>com.adobe.cq.wcm</groupId>
<artifactId>com.adobe.aem.wcm.seo</artifactId>
<version>1.0.6</version>

</dependency>

supriya-hande
Level 4
December 12, 2022

@nikhil-kumar Thanks for this article. It helped me. 🙂 

 

If I want to get fully qualified URL I mean to add hostname before content path in <loc> how can we do that?

currently page path is : /content/we-retails/ue/en/testpage

It should be: http://localhost:4502//content/we-retails/ue/en/testpage

Level 9
December 12, 2022

I ended up creating a custom site map generator and use 

Externalizer ext = resource.getResourceResolver().adaptTo(Externalizer.class) 

ext.publishLink(resource.getResourceResolver(),location)+”.html”


please take care of the quotes 

@supriya-hande 

hope this helps