At the moment I am developing some redirect logic in a HippoCMS powered website, to create 301 redirects for URLs on the old website to their corresponding pages on the new website.
For the old website i only have access to a "title to URL" based index. No further access is possible. The Hippo documents in the new website are created with the exact same title as the old website. So a match should theoretically be possible.
The reason for the development approach is the fact that there are more then 7000 pages that need redirecting. Doing this manually (with the UrlRewriter plugin) would mean 40+ hours of mind numbing work.
I have created a Groovy updater script which SHOULD ;
import org.hippoecm.hst.configuration.hosting.Mount;
import org.hippoecm.hst.container.RequestContextProvider;
import org.hippoecm.hst.core.linking.HstLink;
import org.hippoecm.hst.core.linking.HstLinkCreator;
import org.hippoecm.hst.core.request.HstRequestContext;
class UpdaterTemplate extends BaseNodeUpdateVisitor {
boolean doUpdate(Node node) {
def HstRequestContext = RequestContextProvider.get();
def mount = HstRequestContext.getMount();
def linkCreator= temp.getHstLinkCreator();
def link = linkCreator.create(node.path, mount);
def url = link.toUrlForm(HstRequestContext);
// Output the url
log.debug(url);
}
}
The code was based upon a hippo example page about rewriting links
I can not seem to be able to retrieve the URL for the new website. All other steps are working fine and i have the document JCR node on the new site. I only cannot generate an URL.
The first errors i got made clear that the CMS could not resolve some of the HST classes.
ERROR Cannot run updater: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
updater: 8: unable to resolve class org.hippoecm.hst.container.RequestContextProvider
@ line 8, column 1.
import org.hippoecm.hst.container.RequestContextProvider
^
1 error
This was easily fixed by updating my pom.xml. Only for the duration of development. Will be reset afterwards.
Then the real problem arose, the HstRequestContext is null.
ERROR Updating /content/documents/XYZXYZ failed - java.lang.NullPointerException: Cannot invoke method getMount() on null object
Of course this makes sense, since we do not have a real context. But still... how else should i generate the URLs, without a copy of the full sitemap logic.
Am i on a completely bogus path? Or am i missing something? Please help me out.
HST libraries/context is not available within CMS part (those two are separate apps, with different context/lifecycle). I think easiest would be to create an HST component instead of groovy script (you can use getPersistableSession(request) to write data to the repository), or make a HST REST service which you can call to resolve the links. One such a service already exists, but you'll need to authenticate it: http://127.0.0.1:8080/site/_cmsrest/documents/DOCUMENT_UUID/url/live
private static final String CMSREST_CREDENTIALS_HEADER = "X-CMSREST-CREDENTIALS";
private static final String CMSREST_CMSHOST_HEADER = "X-CMSREST-CMSHOST";
private static final String CREDENTIAL_CIPHER_KEY = "ENC_DEC_KEY";
public String getUrl(final String url) throws IOException {
final CredentialCipher credentialCipher = CredentialCipher.getInstance();
final String encryptedCredentials = credentialCipher.getEncryptedString(CREDENTIAL_CIPHER_KEY, new SimpleCredentials(user, password.toCharArray()));
try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
final HttpGet httpget = new HttpGet(url);
httpget.setHeader(CMSREST_CREDENTIALS_HEADER, encryptedCredentials);
httpget.setHeader(CMSREST_CMSHOST_HEADER, encryptedCredentials);
log.info("Executing request {}", httpget.getRequestLine());
final ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
public String handleResponse(final HttpResponse response) throws IOException {
final int status = response.getStatusLine().getStatusCode();
if (status >= 200 && status < 300) {
final HttpEntity entity = response.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
} else {
log.error("Invalid status: {}", status);
return null;
}
}
};
return httpclient.execute(httpget, responseHandler);
}
}
Note: just replace DOCUMENT_UUID with your own uuid. This must be uuid of document handle.
HTH