diff --git a/changes.xml b/changes.xml index 93d8be4..e8eaf95 100644 --- a/changes.xml +++ b/changes.xml @@ -23,6 +23,12 @@ xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 http://maven.apache.org/plugins/maven-changes-plugin/xsd/changes-1.0.0.xsd"> + + + Support detecting redirect pages using AEM cq:redirectTarget property (instead of link handler properties). + + + Add optional support for using vanity paths when building link URLs to AEM pages. diff --git a/pom.xml b/pom.xml index 3884883..36384fe 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ io.wcm io.wcm.handler.link - 2.1.0 + 2.2.0 jar Link Handler @@ -49,7 +49,7 @@ handler/link - 2024-03-21T10:12:34Z + 2024-05-14T09:33:17Z diff --git a/src/main/java/io/wcm/handler/link/spi/LinkHandlerConfig.java b/src/main/java/io/wcm/handler/link/spi/LinkHandlerConfig.java index 47c4b87..d505934 100644 --- a/src/main/java/io/wcm/handler/link/spi/LinkHandlerConfig.java +++ b/src/main/java/io/wcm/handler/link/spi/LinkHandlerConfig.java @@ -19,6 +19,8 @@ */ package io.wcm.handler.link.spi; +import static com.day.cq.wcm.api.NameConstants.PN_REDIRECT_TARGET; + import java.util.Collections; import java.util.List; @@ -62,7 +64,7 @@ public abstract class LinkHandlerConfig implements ContextAwareService { private static final List> DEFAULT_POST_PROCESSORS = List.of( DefaultInternalLinkInheritUrlParamLinkPostProcessor.class); - private static final String REDIRECT_RESOURCE_TYPE = "wcm-io/handler/link/components/page/redirect"; + static final String REDIRECT_RESOURCE_TYPE = "wcm-io/handler/link/components/page/redirect"; /** * Default content root path. @@ -123,7 +125,8 @@ public boolean isValidLinkTarget(@NotNull Page page) { * @return true if Page is a redirect page */ public boolean isRedirect(@NotNull Page page) { - return ResourceType.is(page.getContentResource(), REDIRECT_RESOURCE_TYPE); + return ResourceType.is(page.getContentResource(), REDIRECT_RESOURCE_TYPE) + || StringUtils.isNotBlank(page.getProperties().get(PN_REDIRECT_TARGET, String.class)); } /** diff --git a/src/main/java/io/wcm/handler/link/type/helpers/InternalLinkResolver.java b/src/main/java/io/wcm/handler/link/type/helpers/InternalLinkResolver.java index b83643d..5e2349d 100644 --- a/src/main/java/io/wcm/handler/link/type/helpers/InternalLinkResolver.java +++ b/src/main/java/io/wcm/handler/link/type/helpers/InternalLinkResolver.java @@ -19,6 +19,11 @@ */ package io.wcm.handler.link.type.helpers; +import static com.day.cq.wcm.api.NameConstants.PN_REDIRECT_TARGET; +import static io.wcm.handler.link.LinkNameConstants.PN_LINK_FRAGMENT; +import static io.wcm.handler.link.LinkNameConstants.PN_LINK_QUERY_PARAM; +import static io.wcm.handler.link.LinkNameConstants.PN_LINK_TYPE; + import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; @@ -40,7 +45,6 @@ import io.wcm.handler.link.Link; import io.wcm.handler.link.LinkArgs; import io.wcm.handler.link.LinkHandler; -import io.wcm.handler.link.LinkNameConstants; import io.wcm.handler.link.LinkRequest; import io.wcm.handler.link.spi.LinkHandlerConfig; import io.wcm.handler.url.UrlHandler; @@ -182,16 +186,16 @@ public boolean acceptPage(@Nullable Page page, @NotNull InternalLinkResolverOpti // optionally override query parameters and fragment from link resource if (queryString == null) { - queryString = props.get(LinkNameConstants.PN_LINK_QUERY_PARAM, String.class); + queryString = props.get(PN_LINK_QUERY_PARAM, String.class); } else { - queryString = props.get(LinkNameConstants.PN_LINK_QUERY_PARAM, queryString); + queryString = props.get(PN_LINK_QUERY_PARAM, queryString); } if (fragment == null) { - fragment = props.get(LinkNameConstants.PN_LINK_FRAGMENT, String.class); + fragment = props.get(PN_LINK_FRAGMENT, String.class); } else { - fragment = props.get(LinkNameConstants.PN_LINK_FRAGMENT, fragment); + fragment = props.get(PN_LINK_FRAGMENT, fragment); } // build link url @@ -226,13 +230,26 @@ public boolean acceptPage(@Nullable Page page, @NotNull InternalLinkResolverOpti * @return Link metadata */ private Link recursiveResolveLink(Page redirectPage, Link link) { - - // set link reference to content resource of redirect page, keep other parameters LinkRequest linkRequest = link.getLinkRequest(); - LinkRequest redirectLinkRequest = new LinkRequest( - redirectPage.getContentResource(), - null, - linkRequest.getLinkArgs()); + LinkRequest redirectLinkRequest; + + String linkType = redirectPage.getProperties().get(PN_LINK_TYPE, String.class); + String cqRedirectTarget = redirectPage.getProperties().get(PN_REDIRECT_TARGET, String.class); + if (StringUtils.isBlank(linkType) && StringUtils.isNotBlank(cqRedirectTarget)) { + // detected cq-style cq:redirectTarget property, use it's value as reference + redirectLinkRequest = new LinkRequest( + null, + null, + cqRedirectTarget, + linkRequest.getLinkArgs()); + } + else { + // set link reference to content resource of redirect page, keep other parameters + redirectLinkRequest = new LinkRequest( + redirectPage.getContentResource(), + null, + linkRequest.getLinkArgs()); + } // check of maximum recursive calls via threadlocal to avoid endless loops, return invalid link if one is detected LinkResolveCounter linkResolveCounter = LinkResolveCounter.get(); diff --git a/src/test/java/io/wcm/handler/link/spi/LinkHandlerConfigTest.java b/src/test/java/io/wcm/handler/link/spi/LinkHandlerConfigTest.java index e52a36b..5d5765b 100644 --- a/src/test/java/io/wcm/handler/link/spi/LinkHandlerConfigTest.java +++ b/src/test/java/io/wcm/handler/link/spi/LinkHandlerConfigTest.java @@ -19,12 +19,16 @@ */ package io.wcm.handler.link.spi; +import static com.day.cq.wcm.api.NameConstants.PN_REDIRECT_TARGET; import static io.wcm.handler.link.spi.LinkHandlerConfig.DEFAULT_ROOT_PATH_CONTENT; import static io.wcm.handler.link.spi.LinkHandlerConfig.DEFAULT_ROOT_PATH_MEDIA; import static io.wcm.handler.link.testcontext.AppAemContext.ROOTPATH_CONTENT; import static io.wcm.handler.link.testcontext.AppAemContext.ROOTPATH_CONTENT_OTHER_SITE; +import static org.apache.sling.api.resource.ResourceResolver.PROPERTY_RESOURCE_TYPE; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -89,4 +93,13 @@ void testGetLinkRootPath_Invalid() { assertNull(underTest.getLinkRootPath(contentPage, "invalid")); } + @Test + void testIsRedirect() { + assertFalse(underTest.isRedirect(context.create().page(ROOTPATH_CONTENT + "/page1"))); + assertTrue(underTest.isRedirect(context.create().page(ROOTPATH_CONTENT + "/page2", null, + PROPERTY_RESOURCE_TYPE, LinkHandlerConfig.REDIRECT_RESOURCE_TYPE))); + assertTrue(underTest.isRedirect(context.create().page(ROOTPATH_CONTENT + "/page3", null, + PN_REDIRECT_TARGET, "https://myhost.com"))); + } + } diff --git a/src/test/java/io/wcm/handler/link/testcontext/DummyLinkHandlerConfig.java b/src/test/java/io/wcm/handler/link/testcontext/DummyLinkHandlerConfig.java index 671627a..099e436 100644 --- a/src/test/java/io/wcm/handler/link/testcontext/DummyLinkHandlerConfig.java +++ b/src/test/java/io/wcm/handler/link/testcontext/DummyLinkHandlerConfig.java @@ -66,7 +66,11 @@ public boolean isValidLinkTarget(Page page) { @Override public boolean isRedirect(Page page) { String templatePath = page.getProperties().get(NameConstants.PN_TEMPLATE, String.class); - return StringUtils.equals(templatePath, DummyAppTemplate.REDIRECT.getTemplatePath()); + boolean isRedirect = StringUtils.equals(templatePath, DummyAppTemplate.REDIRECT.getTemplatePath()); + if (isRedirect) { + return true; + } + return super.isRedirect(page); } } diff --git a/src/test/java/io/wcm/handler/link/type/InternalLinkTypeTest.java b/src/test/java/io/wcm/handler/link/type/InternalLinkTypeTest.java index 3f020b2..de42b75 100644 --- a/src/test/java/io/wcm/handler/link/type/InternalLinkTypeTest.java +++ b/src/test/java/io/wcm/handler/link/type/InternalLinkTypeTest.java @@ -35,6 +35,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import com.day.cq.wcm.api.NameConstants; import com.day.cq.wcm.api.Page; import com.day.cq.wcm.api.WCMMode; @@ -238,6 +239,25 @@ void testRedirectInternal() throws Exception { assertEquals(redirectInternalPage, redirectPages.get(0)); } + @Test + void testRedirectInternal_cqRedirectTarget() throws Exception { + LinkHandler linkHandler = AdaptTo.notNull(adaptable(), LinkHandler.class); + + // redirect page using cq:redirectTarget property + Page redirectInternalPage = context.create().page("/content/unittest/de_test/brand/de/section/redirectInternal", null, + NameConstants.PN_REDIRECT_TARGET, targetPage.getPath()); + + Link link = linkHandler.get(redirectInternalPage).build(); + + assertTrue(link.isValid(), "link valid"); + assertEquals("http://www.dummysite.org/content/unittest/de_test/brand/de/section/content.html", link.getUrl(), "link url"); + assertNotNull(link.getAnchor(), "anchor"); + + List redirectPages = link.getRedirectPages(); + assertEquals(1, redirectPages.size()); + assertEquals(redirectInternalPage, redirectPages.get(0)); + } + @Test void testRedirectInternal_EditMode() throws Exception { if (!(adaptable() instanceof SlingHttpServletRequest)) {