Displaying content in tabs dynamically


Active member
I'm creating an add-on which displays some data from the database. Essentially, this data is in the form of:

{Topic}, {Category}, {Item}

For any given topic, I currently display as a long list of its items, grouped by category:

Category A
Item 1
Item 2
Item 3
Category B
Item 4
Item 5
Item 6

This is achieved purely in the template by using the <xen:set> tag to detect a change in category within the <xen:foreach> loop.

However, I was wondering if it would be possible to display each category in a separate tab? Are there any examples out there that I could learn from? The challenge being that for any given topic, the number and names of the categories are variable.

Basically, instead of inserting a new header for each category, I want to break out into a new tab.

Any advice on how this may be achieved would be appreciated.
Last edited:


Active member
After some tinkering around, I think I've got a working solution. The template is essentially as follows:

<xen:set var="$firstPass">1</xen:set>

<ul class="tabs mainTabs Tabs" data-panes="#myPanes > li" data-history="on">
    <xen:foreach loop="$categoryList" value="$cat">
        <li><a href="{$requestPaths.requestUri}#{$cat.category}">{$cat.category}</a></li>

<ul id="myPanes">
    <xen:foreach loop="$itemList" value="$item">
        <xen:if is="{$firstPass}">
            <li id="{$item.category}">
            <xen:set var="$firstPass">0</xen:set>
        <xen:elseif is="{$item.category} != {$curCat}" />
            <li id="{$item.category}">
        <xen:set var="$curCat">{$item.category}</xen:set>
I ended up creating an additional method to my Model that gets all the categories for a given topic. This was then used to populate an additional $viewParam.

So the first <ul> uses a 'foreach' loop to set up the tabs according to the $categoryList (defined above).

The second <ul> uses a 'foreach' loop to populate each pane (or tab) with content ($item.name), checking for category changes along the way (comparing to $curCat).

The $firstPass variable is there to initiate the opening <li> for the very first category encountered. Subsequent changes in category will close the the preceeding one (</li>) before starting the new (<li>). Once the loop has ended, the last category is closed (</li>) as well as the main list (</ul>).

Here's a screenshot of my particular (and unfinished!) implementation:

If there's a more elegant solution to this, I'd love to see it. Otherwise, I hope this helps other struggling add-on developers (like me!) that need to create tabs dynamically based on content.