Search code examples
springtwitter-bootstrapspring-mvcspring-bootthymeleaf

Bootstrap Navbar Highlighting in Thymeleaf's layout


I am evaluating spring boot + MVC + bootstrap . One problem I am facing is bootstrap's navbar highlighting problem in thymeleaf.

I hope thymeleaf can judge the tab which should be highlighted.

I searched and found this solution : Bootstrap Navbar Highlighting in Thymeleaf

In the containing(outer) page , it uses

<div th:replace="header::header('home')">
  to be replaced header
</div>

to designate the home tab should be highlighted.

And in the contained (inner) page , it uses

<nav class="..." th:fragment="header(activeTab)">
<ul class="nav navbar-nav">
  <li th:class="${activeTab == 'home'} ? 'active' : null "><a href="#" th:href="@{/home}">Home</a></li>
</ul>

to judge this tab should be highlighted or not.

It works for every single page well , but not for layout.

In a layout page , the containing (outer) page is a decorator , which decorates other pages (home / about / contact ...) . The tab value is pending here .

for example

<div th:replace="header::header('home')">
  to be replaced header
</div>
<div layout:fragment="content">
  layout
</div>
<div th:replace="footer::footer">
  to be replaced footer
</div>

I cannot pre-assign home tab in the layout file. Is there any way to solve it ?

Can it judge by controller or even controller's method ?

environment :

springboot.version 1.3.0.M5
spring.version :4.2.1.RELEASE 

Thanks a lot !


Solution

  • It is not a exact solution for your question but maybe you will like the idea. You may use request context path to recognize which tab is actually selected, so you can use ${#httpServletRequest.getContextPath()} and maybe then something like that:

    <ul class="nav navbar-nav" th:with="view=${#httpServletRequest.getServletPath()}">
      <li th:classappend="${#strings.startsWith(view,'/home')? 'active' : ''}"><a href="#" th:href="@{/home}">Home</a></li>
    </ul>
    

    Or you can use ControllerAdvice:

    @ControllerAdvice(assignableTypes = { MyController.class })
    public class MyControllerAdvice {
    
      @ModelAttribute
      public void addAttributes(@RequestParam Map<String, String> params, Model model, HttpServletRequest request) {
    String activeTab = ... whatever
        model.addAttribute("active_tab", activeTab);
      }
    }
    

    There is one big disadvantage of using @ControllerAdvice. If you are planning to use Spring WebFlow to create multi-page forms (wizards) then it will not work because WebFlow does not use model attributes.