EJS templates: How to generate an HTML tree structure in the most elegant and handy way

ejs, html, javascript

Solution

I found a better approach, but it need a separate EJS file.

In my `main.ejs`:

<%- partial('treeView', {items: tree}) %>

In the `treeView.ejs`:

<% if (items.length) { %>
<ul>
<% } %>

    <% items.forEach(function(item){ %>
    <li>
        <a href="<%= item.link %>"><%= item.name %></a>
        <%- partial('treeView', {items: item.children}) %>
    </li>
    <% }) %>

<% if (items.length) { %>
</ul>
<% } %>

Problem

I have this nested Array of Objects: ``` var tree = [ { name: "item 1", link: "#link-1", children: [ { name: "item 1.1", link: "#link-11", children: [ { name: "item 1.1.1", link: "#link-111", children: [] } ] }, { name: "item 1.2", link: "#link-12", children: [] } ] }, { name: "item 2", children: [] } ]; ``` I would like to generate an HTML `ul` `li` tree structure from this model. The only solution I found is just below (via a recursive function). But I would like to avoid string concatenation, because in my real situation I have more markup to add on each rows of `li` (and this is really not handy). ``` <% var markup = ''; function htmlTreeBuilder(items) { if (items.length) { markup += '<ul>'; } for (var i = 0; i < items.length; i++) { markup += '<li>'; markup += '<a href="' + items[i].link + '">' + items[i].name + '</a>'; // Children htmlTreeBuilder(items[i].children); markup += '</li>'; } if (items.length) { markup += '</ul>'; } } htmlTreeBuilder(tree); %> <%- markup %> ```

Original source