Dynamic sitemap generator | Community
Skip to main content
May 6, 2020
Solved

Dynamic sitemap generator

  • May 6, 2020
  • 1 reply
  • 3303 views

Hello, I have tried to create a dynamic sitemap generator using a servlet, I would like to help me by leaving your recommendations to optimize the code or a better way to achieve the creation of a dynamic sitemap.

The idea is to allow the author, to select whether or not the pages will appear on the sitemap, the way in which this is done will not be placed, but basically it will allow using the hideInSitemap fields, whose value will be true or false, in order to create the mapping.

 

class SitemapGenerator:

package es.hesperia.web.terrum.core.servlets; import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.activation.UnsupportedDataTypeException; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.servlet.Servlet; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.servlets.HttpConstants; import org.apache.sling.api.servlets.SlingSafeMethodsServlet; import org.osgi.framework.Constants; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.day.cq.search.PredicateGroup; import com.day.cq.search.Query; import com.day.cq.search.QueryBuilder; import com.day.cq.search.result.Hit; import com.day.cq.search.result.SearchResult; @Component(service = Servlet.class, property = { Constants.SERVICE_DESCRIPTION + "=Query Builder servlet", "sling.servlet.methods=" + HttpConstants.METHOD_GET, "sling.servlet.paths=" + "/bin/projectSitemap" }) public class SitemapGenerator extends SlingSafeMethodsServlet { final String path = "/content/project/language-master"; final String project = "/content/project"; final String propertyFilterVar = "hideInSitemap"; //field to search final String propertyFilterValue = "false"; final String lastModified = "cq:lastModified";//last change to the page final String priorityPage= "priorityPage"; private static final long serialVersionUID = 2610051404257637265L; private static final Logger log = LoggerFactory.getLogger(SitemapGenerator.class); @Reference private transient QueryBuilder builder; @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) { Session session = null; try { log.debug("----------< Executing Query Builder Servlet >----------"); ResourceResolver resourceResolver = request.getResourceResolver(); session = resourceResolver.adaptTo(Session.class); Map<String, String> pages = new HashMap<>(); pages.put("path", this.path); pages.put("property", this.propertyFilterVar); pages.put("property.1_value", this.propertyFilterValue); Query query = this.builder.createQuery(PredicateGroup.create(pages), session); query.setHitsPerPage(-1);//unlimited results String lastKey = ""; SearchResult searchResult = query.getResult(); PrintWriter out = response.getWriter(); List<List<String[]>> languageKey = new ArrayList<>();//list of pages by language List<String[]> pagesList = null;//by pages for(Hit hit : searchResult.getHits()) { String[] contentNode = new String[4]; String pathUrl = hit.getPath(); String simplePath = pathUrl; simplePath = simplePath.replaceAll(project, request.getServerName()); simplePath = simplePath.replaceAll("/jcr:content", ".html"); Resource rs = resourceResolver.getResource(pathUrl);//Metadata Node node = rs.adaptTo(Node.class); String actualKey = node.getAncestor(4).getPath();//arbol hasta el nivel del idioma contentNode[0] = simplePath;// url of the page contentNode[1] = node.getProperty(lastModified).getString();//last update contentNode[2] = node.getProperty(priorityPage).getString();//priority contentNode[3] = actualKey.replace(this.path+"/", "");//format language -> [a-z]{2} /** * if lastKey is equal to actualKey, a new list of pages is added * for a new language nueva */ if (!lastKey.equals(actualKey)) { /** * when lastKey is igual to "" is the first language that is stored * and only the page list for the first language is initialized */ if (!lastKey.equals("")) { languageKey.add(pagesList); } pagesList = new ArrayList<>(); lastKey = actualKey; } int size = pagesList.size(); Boolean inserted = false; int index = 0; /** * alphabetically sorts each page, as it is added */ while (!inserted && index<size) { if (simplePath.compareTo(pagesList.get(index)[0])<0) { pagesList.add(index,contentNode); inserted = true; } index++; } /** * if no elements were inserted into the list, it is inserted at the end of the list */ if (!inserted) { pagesList.add(contentNode); } } languageKey.add(pagesList); int numPages = languageKey.get(0).size(); int numLanguages = languageKey.size(); response.setContentType("text/xml"); out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); out.println("<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">"); for (int i = 0; i < numPages; i++) { out.println("<url>"); out.println("<loc>"+languageKey.get(numLanguages-1).get(i)[0]+"</loc>");//URL /** * if there is more than one language the alternative links are printed * for each language */ if (numLanguages > 1) { int size = numLanguages; for (int index = size-1; index>=0;index--) { out.println("<xhtml rel=\"alternate\" hreflang=\""+languageKey.get(index).get(i)[3]//language +"\" href=\""+languageKey.get(index).get(i)[0]+"\" />");//url } } String dateStr = languageKey.get(0).get(i)[1];//updated date String pattern = "\\D\\d{3}"; //new format dateStr = dateStr.replaceFirst(pattern, ""); out.println("<lastmod>"+dateStr+"</lastmod>");//last update out.println("<priority>"+languageKey.get(0).get(i)[2]+"</priority>");//priority out.println("</url>"); } out.println("</urlset>"); session.save(); } catch (UnsupportedEncodingException|UnsupportedDataTypeException e) { log.error("UnsupportedEncodingException|UnsupportedDataTypeException:", e); } catch (IOException e) { log.error("IOException:", e); e.printStackTrace(); } catch (RepositoryException e) { log.error("RepositoryException:", e); e.printStackTrace(); } finally { if(session != null) { session.logout(); } } } }

This is my code, it is personalized but I would like to know other points of view to improve it or other ways of doing it.

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

Use Acs commons sitemap generator with simple configuration instead of developing custom logic..

1 reply

Shashi_Mulugu
Community Advisor
Shashi_MuluguCommunity AdvisorAccepted solution
Community Advisor
May 30, 2020

Use Acs commons sitemap generator with simple configuration instead of developing custom logic..

March 27, 2023

Could you please share the steps for Using Acs commons sitemap generator with simple configuration instead of developing custom logic for change frequency.