如何递归使用百里香叶渲染菜单

时间:2014-07-30 09:09:21

标签: java spring templates web thymeleaf

我想使用ul / li列表呈现HTML菜单。我有这种类结构:

public class MenuItem {

    private String name;

    private MenuItem parent;

    private List<MenuItem> children;

    public MenuItem(String name,List<MenuItem> children) {
        this.name = name;
        this.children = children;
        for (MenuItem child : children) {
            child.parent = this;
        }
    }

    public MenuItem(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public MenuItem getParent() {
        return parent;
    }

    public List<MenuItem> getChildren() {
        return children;
    }
} 

您可以看到它的典型树形结构,其中一个根元素包含对其子元素的引用,并且它们引用了它们等等。

现在我想要渲染这样的结构:

<ul>
    <li>Item 1
        <ul>
            <li>Item 1.1</li>
            <li>Item 1.2
                <ul>
                    <li>Item 1.2.1</li>
                    <li>Item 1.2.3</li>
                </ul>
            </li>
            <li>Item 1.3</li>
        </ul>
    </li>
    <li>Item 2</li>
</ul>

我如何用百里香做到这一点?如果我必须使用其他技术,例如Tiles,Layout或其他任何内容,我会很容易。

编辑:我试过参数化包含/替换,但没有运气。传递的参数将转换为String,并且不能用于其他级别的递归。见https://github.com/ultraq/thymeleaf-layout-dialect/issues/12

非常感谢,

3 个答案:

答案 0 :(得分:3)

试试这个:

为单个菜单项创建一个片段menuFragment.html

<html>
    <section layout:fragment="menu">
        <ul>
            <li th:each="menuItem : ${menuItemsList}" th:text="${menuItem.name}">
                <section layout:include="@{path/to/folder/menuFragment} :: menu" th:with="menuItemsList=${menuItem.children}"></section>
            </li>
        </ul> 
    </section>
</html>

将片段包含在菜单文件中

<section layout:include="@{path/to/folder/menuFragment} :: menu" th:with="menuItemsList=${rootMenuItemAsList}"></section>

rootMenuItemAsList是包含父菜单的列表

希望你有这个帮助

答案 1 :(得分:1)

我尝试了这个,在我看来这一行:

    <li th:each="menuItem : ${menuItemsList}" th:text="${menuItem.name}">
        <section layout:include="@{path/to/folder/menuFragment} :: menu" th:with="menuItemsList=${menuItem.children}"></section>

将覆盖include(在li标签内),因为th:text属性完全相同:覆盖li块内的内容。

我得到了以下内容:

    <li th:each="menuItem : ${menuItemsList}">
        <span  th:text="${menuItem.name}">prototype text...</span>
        <section layout:include="@{path/to/folder/menuFragment} :: menu" th:with="menuItemsList=${menuItem.children}"></section>
    </li>

希望这会有所帮助......

答案 2 :(得分:0)

主要包括:

<section th:include="@{categoryFragment} :: category" th:with="maincategories=${categories}"></section>

作为片段,我使用:

<section th:fragment="category">
    <ul>
        <li th:each="cat : ${maincategories}">
            <span th:text="${cat.categoryName}">Main Cat</span>
            <section th:include="@{categoryFragment} :: category" th:with="maincategories=${cat.getChildren()}"></section>
        </li>
    </ul>
</section>

这绝对适合我。