Duplicate vanity URLs
Question
On edit mode, when I copy a page with a vanity URL, then I go tho this page, and then on preview, Jahia switch to the original page, not the copy.
Cause
If your Jahia uses a version of the SEO prior to 7.2.0, then you can have duplicate vanity URL on your site. This copies were made when you copy contents with existing vanity URLs. From SEO 7.2.0 Jahia create a new uniq vanity URL instead of copying the existing one.
Solution
The solution is to update your SEO module at least to version 7.2.0
However, you may have some existing duplicate vanity URLs that you may want to remove. Here is a way to clean it, using a groovy script. The goal of this script is to build a list of all duplicate vanity found in your site (update the siteKey
in the script for your existing site). and for each duplicate entries, it lists all founded path and keeps only the original value (the first created vanity).
By default, this script does not remove any vanity URL, except if you change the doIt
value to true
.
import org.jahia.api.Constants
import org.jahia.services.content.*
import org.jahia.services.sites.JahiaSite
import javax.jcr.NodeIterator
import javax.jcr.RepositoryException
import javax.jcr.query.Query
String siteKey = "digitall";
boolean doIt = false; // set to true to remove duplicated vanities
Set<String> urls = new HashSet<String>();
Set<String> duplicateUrls = new HashSet<String>();
def logger = log;
def JahiaSite site = org.jahia.services.sites.JahiaSitesService.getInstance().getSiteByKey(siteKey);
JCRTemplate.getInstance().doExecuteWithSystemSession(null, Constants.EDIT_WORKSPACE, new JCRCallback() {
@Override
Object doInJCR(JCRSessionWrapper session) throws RepositoryException {
def q = "select * from [jnt:vanityUrl] as p where isdescendantnode('/sites/" + siteKey + "')";
//logger.info("Here are the vanity urls")
NodeIterator iterator = session.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2).execute().getNodes();
while (iterator.hasNext()) {
try {
final JCRNodeWrapper node = (JCRNodeWrapper) iterator.nextNode();
String url = node.getPropertyAsString('j:url');
//logger.info(url)
if (urls.contains(url)) {
duplicateUrls.add(url);
} else {
urls.add(url);
}
} catch (javax.jcr.PathNotFoundException e) {
} catch (javax.jcr.ItemNotFoundException inf) {
}
}
if (duplicateUrls.size() == 0) {
logger.info("Great, we did not found any duplicate vanity!")
} else {
logger.info("Mmm.... we found some duplicate entries...")
for (String duplicateUrl : duplicateUrls) {
logger.info("[" + duplicateUrl + "]");
def u = "select * from [jnt:vanityUrl] where ['j:url']='" + duplicateUrl + "' and isdescendantnode('/sites/" + siteKey + "') order by ['jcr:created']";
iterator = session.getWorkspace().getQueryManager().createQuery(u, Query.JCR_SQL2).execute().getNodes();
int i = 0;
while (iterator.hasNext()) {
try {
final JCRNodeWrapper node = (JCRNodeWrapper) iterator.nextNode();
if (i > 0) {
if (doIt) {
logger.info(" - " + node.getPath() + " (removed)");
node.remove();
} else {
logger.info(" - " + node.getPath() + " (conflict found: this vanity should be removed)");
}
} else {
logger.info(" - " + node.getPath());
}
i++;
} catch (javax.jcr.PathNotFoundException e) {
} catch (javax.jcr.ItemNotFoundException inf) {
}
}
}
}
if (doIt) {
session.save();
}
return null;
}
});
This could be the output result: