diff --git a/README.md b/README.md index 3b32f96..ad32753 100644 --- a/README.md +++ b/README.md @@ -120,9 +120,9 @@ except for some control flow response headers such as [HX-Redirect](https://htmx ##### Special view name prefixes For these views, there is also a special view name handling if you prefer to return a view name instead of a view instance. -* Redirect URLs can be specified via `htmx:redirect:`, e.g. `htmx:redirect:/path`, which causes htmx to perform a redirect to the specified URL. -* Location redirect URLs can be specified via `htmx:location:`, e.g. `htmx:location:/path`, which causes htmx to perform a client-side redirect without reloading the entire page. -* A refresh of the current page can be specified using `htmx:refresh`. +* Redirect URLs can be specified via `redirect:htmx:`, e.g. `redirect:htmx:/path`, which causes htmx to perform a redirect to the specified URL. +* Location redirect URLs can be specified via `redirect:htmx:location:`, e.g. `redirect:htmx:location:/path`, which causes htmx to perform a client-side redirect without reloading the entire page. +* A refresh of the current page can be specified using `refresh:htmx`. ```java @HxRequest @@ -139,7 +139,7 @@ public String user(@PathVariable Long id, @ModelAttribute @Valid UserForm form, redirectAttributes.addFlashAttribute("successMessage", "User has been successfully updated."); htmxResponse.addTrigger("user-updated"); - return "htmx:redirect:/user/list"; + return "redirect:htmx:/user/list"; } ``` diff --git a/htmx-spring-boot/src/main/java/io/github/wimdeblauwe/htmx/spring/boot/mvc/HtmxViewResolver.java b/htmx-spring-boot/src/main/java/io/github/wimdeblauwe/htmx/spring/boot/mvc/HtmxViewResolver.java index 7e2be59..0b1f8c0 100644 --- a/htmx-spring-boot/src/main/java/io/github/wimdeblauwe/htmx/spring/boot/mvc/HtmxViewResolver.java +++ b/htmx-spring-boot/src/main/java/io/github/wimdeblauwe/htmx/spring/boot/mvc/HtmxViewResolver.java @@ -22,18 +22,18 @@ public class HtmxViewResolver extends WebApplicationObjectSupport implements Vie * Prefix for special view names that specify a redirect URL * that htmx should navigate to. */ - public static final String REDIRECT_URL_PREFIX = "htmx:redirect:"; + public static final String REDIRECT_URL_PREFIX = "redirect:htmx:"; /** * Prefix for special view names that specify a redirect URL that * htmx should navigate to without a full page reload. */ - public static final String LOCATION_URL_PREFIX = "htmx:location:"; + public static final String LOCATION_URL_PREFIX = "redirect:htmx:location:"; /** * Prefix for special view names that specify a refresh of the current page. */ - public static final String REFRESH_VIEW_NAME = "htmx:refresh"; + public static final String REFRESH_VIEW_NAME = "refresh:htmx"; private int order = Ordered.LOWEST_PRECEDENCE; @@ -62,9 +62,9 @@ public View resolveViewName(String viewName, Locale locale) throws Exception { return new HtmxRefreshView(); } - if (viewName.startsWith(REDIRECT_URL_PREFIX)) { - String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length()); - RedirectView view = new HtmxRedirectView(redirectUrl, isRedirectContextRelative()); + if (viewName.startsWith(LOCATION_URL_PREFIX)) { + String redirectUrl = viewName.substring(LOCATION_URL_PREFIX.length()); + RedirectView view = new HtmxLocationRedirectView(redirectUrl, isRedirectContextRelative()); String[] hosts = getRedirectHosts(); if (hosts != null) { view.setHosts(hosts); @@ -72,9 +72,9 @@ public View resolveViewName(String viewName, Locale locale) throws Exception { return view; } - if (viewName.startsWith(LOCATION_URL_PREFIX)) { - String redirectUrl = viewName.substring(LOCATION_URL_PREFIX.length()); - RedirectView view = new HtmxLocationRedirectView(redirectUrl, isRedirectContextRelative()); + if (viewName.startsWith(REDIRECT_URL_PREFIX)) { + String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length()); + RedirectView view = new HtmxRedirectView(redirectUrl, isRedirectContextRelative()); String[] hosts = getRedirectHosts(); if (hosts != null) { view.setHosts(hosts); diff --git a/htmx-spring-boot/src/test/java/io/github/wimdeblauwe/htmx/spring/boot/mvc/HtmxHandlerMethodTest.java b/htmx-spring-boot/src/test/java/io/github/wimdeblauwe/htmx/spring/boot/mvc/HtmxHandlerMethodTest.java index 81708f1..7330014 100644 --- a/htmx-spring-boot/src/test/java/io/github/wimdeblauwe/htmx/spring/boot/mvc/HtmxHandlerMethodTest.java +++ b/htmx-spring-boot/src/test/java/io/github/wimdeblauwe/htmx/spring/boot/mvc/HtmxHandlerMethodTest.java @@ -74,6 +74,15 @@ public void testLocationRedirectViewNamePrefixContextRelative() throws Exception .andExpect(header().string("HX-Location", "/contextpath/path")); } + @Test + public void testLocationRedirectViewNamePrefixFlashAttributes() throws Exception { + + mockMvc.perform(get("/location-redirect-view-name-prefix-flash-attributes").headers(htmxRequest())) + .andExpect(status().isOk()) + .andExpect(header().string("HX-Location", "/path")) + .andExpect(flash().attribute("flash", "test")); + } + @Test public void testLocationRedirectWithContextData() throws Exception { @@ -148,6 +157,15 @@ public void testRedirectViewNamePrefixContextRelative() throws Exception { .andExpect(header().string("HX-Redirect", "/contextpath/test")); } + @Test + public void testRedirectViewNamePrefixFlashAttributes() throws Exception { + + mockMvc.perform(get("/contextpath/redirect-view-name-prefix-flash-attributes").contextPath("/contextpath").headers(htmxRequest())) + .andExpect(status().isOk()) + .andExpect(header().string("HX-Redirect", "/contextpath/test")) + .andExpect(flash().attribute("flash", "test"));; + } + @Test public void testRedirectWithContextPath() throws Exception { @@ -216,7 +234,15 @@ public HtmxLocationRedirectView locationRedirectExposingModelAttributes(Redirect @HxRequest @GetMapping("/location-redirect-view-name-prefix") public String locationRedirectViewNamePrefix() { - return "htmx:location:/path"; + return "redirect:htmx:location:/path"; + } + + @HxRequest + @GetMapping("/location-redirect-view-name-prefix-flash-attributes") + public String locationRedirectWithViewNamePrefixFlashAttributes(RedirectAttributes redirectAttributes) { + + redirectAttributes.addFlashAttribute("flash", "test"); + return "redirect:htmx:location:/path"; } @HxRequest @@ -308,10 +334,18 @@ public HtmxRedirectView redirectExposingModelAttributes(RedirectAttributes attri return new HtmxRedirectView("/test"); } + @HxRequest + @GetMapping("/redirect-view-name-prefix-flash-attributes") + public String redirectWithViewNamePrefixFlashAttributes(RedirectAttributes redirectAttributes) { + + redirectAttributes.addFlashAttribute("flash", "test"); + return "redirect:htmx:/test"; + } + @HxRequest @GetMapping("/redirect-view-name-prefix") public String redirectViewNamePrefix() { - return "htmx:redirect:/test"; + return "redirect:htmx:/test"; } @HxRequest @@ -331,7 +365,7 @@ public HtmxRefreshView refresh() { @HxRequest @GetMapping("/refresh-view-name") public String refreshViewName() { - return "htmx:refresh"; + return "refresh:htmx"; } @HxRequest